如何在 cygwin 中使用“*.stackdump”文件进行调试
how to debug using "*.stackdump" file in cygwin
我是 cygwin(和 linux)的新手。
当我尝试运行我的基于C语言的可执行文件时,发生段错误,我拿了stackdump文件。但是,我不知道如何使用它进行调试。
我一直在寻找如何使用堆栈转储文件进行调试的方法,但我找不到。
任何小技巧对我都非常有用。感谢阅读我糟糕的英语(英语不是我的第一语言)。
首先:你需要编译你的程序传递给 gcc 标志 -ggdb
否则堆栈转储信息是无用的。我建议也传递 -O0
标志,这样使用 gdb 进行调试会更容易,因为代码不会被优化。
第二:堆栈转储提供堆栈中存在的地址,
在这个 32 位的例子中,我们有两个地址:
$ cat t-invmod.exe.stackdump
Stack trace:
Frame Function Args
0028C878 61032BCB (000000F4, 0000EA60, 000000A4, 0028C8D8)
0028C998 610E7A7A (00000001, 0028CA3F, 00000001, 611A2C80)
地址可以来自您的程序或加载的共享库。
要将地址转换为代码位置,请使用addr2line
。
示例:
$ addr2line.exe -a 610E7A7A -a 61032BCB -e /usr/bin/cygwin1.dll
0x610e7a7a
/usr/src/debug/cygwin-2.5.1-1/winsup/cygwin/cygerrno.h:36
0x61032bcb
/usr/src/debug/cygwin-2.5.1-1/winsup/cygwin/cygerrno.h:35
在这种情况下,高地址告诉我崩溃是在共享库中而不是在程序中。您可以使用 ldd
来识别地址所属的地址:
$ ldd t-invmod.exe
ntdll.dll => /cygdrive/c/Windows/SysWOW64/ntdll.dll (0x776d0000)
kernel32.dll => /cygdrive/c/Windows/syswow64/kernel32.dll (0x75500000)
KERNELBASE.dll => /cygdrive/c/Windows/syswow64/KERNELBASE.dll (0x75a10000)
SYSFER.DLL => /cygdrive/c/Windows/SysWOW64/SYSFER.DLL (0x73480000)
cygflint.dll => /usr/bin/cygflint.dll (0x5f390000)
cygwin1.dll => /usr/bin/cygwin1.dll (0x61000000)
cyggmp-10.dll => /usr/bin/cyggmp-10.dll (0x589e0000)
cygmpfr-4.dll => /usr/bin/cygmpfr-4.dll (0x51080000)
cyggcc_s-1.dll => /usr/bin/cyggcc_s-1.dll (0x5ece0000)
cygntl-9.dll => /usr/bin/cygntl-9.dll (0x50270000)
cygstdc++-6.dll => /usr/bin/cygstdc++-6.dll (0x4b340000)
如果地址低于dll的地址,则属于你的程序;如果属于共享库需要安装相关的*debuginfo包来恢复位置信息
我是 cygwin(和 linux)的新手。
当我尝试运行我的基于C语言的可执行文件时,发生段错误,我拿了stackdump文件。但是,我不知道如何使用它进行调试。
我一直在寻找如何使用堆栈转储文件进行调试的方法,但我找不到。 任何小技巧对我都非常有用。感谢阅读我糟糕的英语(英语不是我的第一语言)。
首先:你需要编译你的程序传递给 gcc 标志 -ggdb
否则堆栈转储信息是无用的。我建议也传递 -O0
标志,这样使用 gdb 进行调试会更容易,因为代码不会被优化。
第二:堆栈转储提供堆栈中存在的地址, 在这个 32 位的例子中,我们有两个地址:
$ cat t-invmod.exe.stackdump
Stack trace:
Frame Function Args
0028C878 61032BCB (000000F4, 0000EA60, 000000A4, 0028C8D8)
0028C998 610E7A7A (00000001, 0028CA3F, 00000001, 611A2C80)
地址可以来自您的程序或加载的共享库。
要将地址转换为代码位置,请使用addr2line
。
示例:
$ addr2line.exe -a 610E7A7A -a 61032BCB -e /usr/bin/cygwin1.dll
0x610e7a7a
/usr/src/debug/cygwin-2.5.1-1/winsup/cygwin/cygerrno.h:36
0x61032bcb
/usr/src/debug/cygwin-2.5.1-1/winsup/cygwin/cygerrno.h:35
在这种情况下,高地址告诉我崩溃是在共享库中而不是在程序中。您可以使用 ldd
来识别地址所属的地址:
$ ldd t-invmod.exe
ntdll.dll => /cygdrive/c/Windows/SysWOW64/ntdll.dll (0x776d0000)
kernel32.dll => /cygdrive/c/Windows/syswow64/kernel32.dll (0x75500000)
KERNELBASE.dll => /cygdrive/c/Windows/syswow64/KERNELBASE.dll (0x75a10000)
SYSFER.DLL => /cygdrive/c/Windows/SysWOW64/SYSFER.DLL (0x73480000)
cygflint.dll => /usr/bin/cygflint.dll (0x5f390000)
cygwin1.dll => /usr/bin/cygwin1.dll (0x61000000)
cyggmp-10.dll => /usr/bin/cyggmp-10.dll (0x589e0000)
cygmpfr-4.dll => /usr/bin/cygmpfr-4.dll (0x51080000)
cyggcc_s-1.dll => /usr/bin/cyggcc_s-1.dll (0x5ece0000)
cygntl-9.dll => /usr/bin/cygntl-9.dll (0x50270000)
cygstdc++-6.dll => /usr/bin/cygstdc++-6.dll (0x4b340000)
如果地址低于dll的地址,则属于你的程序;如果属于共享库需要安装相关的*debuginfo包来恢复位置信息