GDB 抱怨缺少 raise.c
每次 gdb 捕获异常时,我都会收到一个烦人的错误.我已经运行了以下示例程序
#include int main() {抛出 std::invalid_argument("");返回0;}
运行 gdb 的结果是
在抛出一个 'std::invalid_argument' 实例后调用终止什么():程序收到信号 SIGABRT,中止.__GI_raise (sig=sig@entry=6) 在 ../sysdeps/unix/sysv/linux/raise.c:5151 ../sysdeps/unix/sysv/linux/raise.c:没有这样的文件或目录.
这还不算太糟,因为我确实得到了我需要的信息,只是让我烦恼...
有人知道如何解决这个问题吗?
解决方案要在 Ubuntu 上对 C 库进行完整的源代码调试,只需几个步骤:
安装 libc6 的 debuginfo 版本.
它可能已经安装 - Ubuntu 上的 gdb 软件包依赖于它 - 但如果没有,请运行
sudo apt install libc6-dbg
.准备包系统以下载和处理源代码包(如果之前尚未完成).
sudo apt install dpkg-devgrep deb-src/etc/apt/sources.list
Grep 的输出应该显示(并且可能还有我们不需要担心的其他匹配项):
<块引用>deb-src http://archive.ubuntu.com/ubuntu/bionic main 受限deb-src http://archive.ubuntu.com/ubuntu/bionic-updates main 受限
如果 grep 显示这些
<块引用>deb-src
行用#
注释掉:# deb-src http://archive.ubuntu.com/ubuntu/bionic main 受限# deb-src http://archive.ubuntu.com/ubuntu/bionic-updates main 受限
然后编辑
/etc/apt/sources.list
删除这些行开头的#
,然后运行sudo apt update
.下载与安装的C库版本对应的源代码.
首先,在任何地方创建一个目录 - 我将在这里使用
/opt/src
.然后执行以下操作:
cd/opt/srcapt源libc6
如果
的错误信息<块引用>apt
命令给出类似E:您必须在您的 sources.list 中放入一些源"URI
那么我在第 2 步中的说明可能已经过时了;在这里发表评论.
下载完成后,运行:
find $PWD -maxdepth 1 -type d -name 'glibc*'
记住这个名字 - 它类似于
/opt/src/glibc-2.23
确定 gdb 希望在哪里找到源代码并进行适当的调整.
运行 gdb,让它运行你的程序直到它停止,然后在 gdb 提示符下执行以下操作:
(gdb) 信息源当前源文件是 ../sysdeps/unix/sysv/linux/raise.c编译目录为/build/glibc-KM3i_a/glibc-2.23/signal
所以 gdb 期望源代码在
/build/glibc-KM3i_a/glibc-2.23
中.有两种方法可以解决此问题:- 移动(或使用符号链接)使源代码位于(或看起来)位于
/build/glibc-KM3i_a/glibc-2.23
中.或者
告诉 gdb 如何替换正确的源目录路径名:
(gdb) 设置替代路径/build/glibc-KM3i_a/glibc-2.23/opt/src/glibc-2.23
现在,回到你的框架,gdb 应该显示源代码行:
(gdb) 第 1 帧#1 0xb7e2fea9 in __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:54返回 INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
- 移动(或使用符号链接)使源代码位于(或看起来)位于
I'm getting an an annoying error every time gdb catches an exception. I've run the following example program
#include <stdexcept>
int main() {
throw std::invalid_argument("");
return 0;
}
And the result from running gdb is
terminate called after throwing an instance of 'std::invalid_argument'
what():
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
It's not all that bad, as I do get the information I need, it's just bugging me...
Do anyone know how to fix this?
解决方案To do full source code debugging of the C library on Ubuntu, there are just a few steps to take:
Install the debuginfo version of libc6.
It's probably already installed - the gdb package on Ubuntu has a dependency on it - but in case it isn't, run
sudo apt install libc6-dbg
.Prepare the package system to download and process source code packages, if this hasn't previously been done.
sudo apt install dpkg-dev grep deb-src /etc/apt/sources.list
Grep's output should show (and there may be additional matches that we don't need to worry about):
deb-src http://archive.ubuntu.com/ubuntu/ bionic main restricted deb-src http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted
If the grep shows that these
deb-src
lines are commented out with#
:# deb-src http://archive.ubuntu.com/ubuntu/ bionic main restricted # deb-src http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted
then edit
/etc/apt/sources.list
to remove the#
at the beginning of these lines and then runsudo apt update
.Download the source code corresponding to the installed version of the C library.
First, create a directory anywhere - I'll use
/opt/src
here.Then do the following:
cd /opt/src apt source libc6
If the
apt
command gives an error message likeE: You must put some 'source' URIs in your sources.list
then my instructions in step 2 may have become outdated; post a comment here.
When the download is complete, run this:
find $PWD -maxdepth 1 -type d -name 'glibc*'
Remember this name - it'll be something like
/opt/src/glibc-2.23
Determine where gdb expects to find the source code and make appropriate adjustments.
Run gdb, have it run your program until it stops, and at the gdb prompt do this:
(gdb) info source Current source file is ../sysdeps/unix/sysv/linux/raise.c Compilation directory is /build/glibc-KM3i_a/glibc-2.23/signal
So gdb is expecting the source code to be in
/build/glibc-KM3i_a/glibc-2.23
. There are two ways to fix this:- Move (or use a symlink) so that the source code is (or appears to be) in
/build/glibc-KM3i_a/glibc-2.23
.or
Tell gdb how to substitute the correct source directory pathname:
(gdb) set substitute-path /build/glibc-KM3i_a/glibc-2.23 /opt/src/glibc-2.23
Now, go back to your frame, and gdb should show the source code line:
(gdb) frame 1 #1 0xb7e2fea9 in __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:54 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
- Move (or use a symlink) so that the source code is (or appears to be) in
相关文章