源码编译GDB 13.1(RHEL7)无法获取工作目录:权限拒绝
问题描述
在RHEL7系统上源码编译GDB 13.1成功后,每次启动执行pwd命令都会报错:
Error finding name of working directory: Permission denied
启动gdbserver时也会出现相同错误并立即退出。受企业环境限制,无法以root身份运行GDB,且对运行GDB的目录拥有全部权限。
补充的strace -e file gdb --batch -ex pwd输出如下:
... openat(AT_FDCWD, "/proc/self/fd", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3 lstat(".", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 openat(AT_FDCWD, "..", O_RDONLY) newfstatat(3, "bin", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(3, "..", O_RDONLY) newfstatat(4, "x86_64.linux.2.6.glibc.2.17", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(4, "..", O_RDONLY) newfstatat(3, ".exec", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(3, "..", O_RDONLY) newfstatat(4, "install", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(4, "..", O_RDONLY) newfstatat(3, "13.1", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(3, "..", O_RDONLY) newfstatat(4, "gdb", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(4, "..", O_RDONLY) newfstatat(3, "fsf", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(3, "..", O_RDONLY) = -1 EACCESS (Permission denied) gdb: warning: error finding working directory: Permission denied ... lstat(".", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(AT_FDCWD, "..", O_RDONLY) newfstatat(11, "bin", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(11, "..", O_RDONLY) newfstatat(12, "x86_64.linux.2.6.glibc.2.17", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(12, "..", O_RDONLY) newfstatat(11, ".exec", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(11, "..", O_RDONLY) newfstatat(12, "install", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(12, "..", O_RDONLY) newfstatat(11, "13.1", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(11, "..", O_RDONLY) newfstatat(12, "gdb", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(12, "..", O_RDONLY) newfstatat(11, "fsf", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0 openat(11, "..", O_RDONLY) = -1 EACCESS (Permission denied) Error finding name of working directory: Permission denied open(".gdb_history", O_RDONLY) +++ exited with 1 +++
解决方案分析
从strace输出能明确定位问题:GDB默认通过/proc/self/fd回溯遍历父目录来确定当前工作目录,但路径中某个上级目录没有执行权限(Linux下遍历目录需要x权限),导致最后一步访问被拒绝。即使你对当前运行目录有完全权限,只要父目录缺少x权限就会触发这个错误。
以下是两个可行的解决办法:
临时绕过:手动指定PWD环境变量
GDB会优先读取PWD环境变量来获取当前工作目录,无需遍历父目录。启动GDB前执行:export PWD=$(pwd)或者直接在启动命令中指定:
PWD=$(pwd) gdb该方法同样适用于gdbserver:
PWD=$(pwd) gdbserver <你的参数>永久解决:重新编译GDB时禁用procfs依赖
如果临时方法不够方便,可以在编译GDB时添加配置选项,强制它不依赖/proc来获取工作目录:./configure --disable-procfs --prefix=<你的安装路径> make && make install注意
--disable-procfs会关闭部分依赖/proc的功能,但完全满足基本调试和pwd命令的使用需求。
内容的提问来源于stack exchange,提问作者Percee
相关产品推荐
相关产品推荐

