我通過經典的 configure、make、make install 構建了程式。幾個月后,程式崩潰了。我仍然有源代碼和未剝離的可執行檔案所在的構建目錄。從那里,我像這樣呼叫 gdb:
530-north:courier$ gdb -q --core /tmp/core_epoch\=1667475742_pid\=23653_file\=\!usr\!local\!libexec\!courier\!courierd courierd
Reading symbols from courierd...
[New LWP 23653]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/usr/local/libexec/courier/courierd'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000561e841e5afd in msgq::completed(drvinfo&, unsigned long) ()
(gdb) info args
No symbol table info available.
我bt可以看到兩個函式之間的一長串呼叫:
#0 0x0000561e841e5afd in msgq::completed(drvinfo&, unsigned long) ()
#1 0x0000561e841e609a in msgq::startdelivery(drvinfo*, delinfo*) ()
#2 0x0000561e841e5bd8 in msgq::completed(drvinfo&, unsigned long) ()
#3 0x0000561e841e609a in msgq::startdelivery(drvinfo*, delinfo*) ()
#4 0x0000561e841e5bd8 in msgq::completed(drvinfo&, unsigned long) ()
...
#204 0x0000561e841e5a17 in msgq::completed(drvinfo&, unsigned long) ()
#205 0x0000561e841e609a in msgq::startdelivery(drvinfo*, delinfo*) ()
#206 0x0000561e841e5a17 in msgq::completed(drvinfo&, unsigned long) ()
#207 0x0000561e841e70fe in courierbmain() ()
#208 0x0000561e841dd030 in main ()
每兩次呼叫都會將堆疊推進 0x110,總共約 27Kb,這比正在運行的行程分配的 132Kb 堆疊要少得多,因此它不是堆疊溢位。SIGSEGV 可能來自空指標或其他。為什么gdb不指向它?這是 GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git,順便說一句。
如果我省略了 gdb 的最后一個引數,bt則不會顯示函式名稱。我搞砸了編譯嗎?在 config.log 我看到我有'CFLAGS= -march=nocona -O2 -g' 'LDFLAGS= -march=nocona -O2' 'CXXFLAGS= -march=nocona -O2 -std=c 11'. 源檔案是 C 。也許我錯過了一些-g?然而,一些符號在那里......
uj5u.com熱心網友回復:
為什么gdb不指向它?
因為您還沒有使用適當的除錯資訊編譯您的程式。
您必須在程式集級別除錯此崩潰。disasemble $pc從和開始info registers。
源檔案是 C 。也許我錯過了一些-gs?
是的:你CXXFLAGS沒有-g.
然而,一些符號在那里......
在 UNIX 系統(與 Windows 不同)上,即使沒有-g. 這里沒有矛盾。
更新:
但是,如果我不將未剝離的檔案作為引數傳遞,則不會顯示函式名稱。
是:strip洗掉符號和除錯資訊。
您可以通過使用一個簡單的測驗來觀察這一點:
// t.cc
#include <cstdlib>
struct S {
void fn() { abort(); }
};
int main()
{
S().fn();
}
首先讓我們看看在正確構建二進制檔案以進行除錯時它是如何作業的:
g -g t.cc -o a.out && strip ./a.out -o a.out.stripped &&
./a.out.stripped; gdb -q --batch -ex where ./a.out core
Aborted (core dumped)
...
warning: core file may not match specified executable file.
[New LWP 476070]
Core was generated by `./a.out.stripped'.
Program terminated with signal SIGABRT, Aborted.
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
44 ./nptl/pthread_kill.c: No such file or directory.
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
#1 0x00007f12444895df in __pthread_kill_internal (signo=<optimized out>, threadid=<optimized out>) at ./nptl/pthread_kill.c:89
#2 __GI___pthread_kill (threadid=<optimized out>, signo=<optimized out>) at ./nptl/pthread_kill.c:89
#3 0x00007f12445f5e70 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007f1244428469 in __GI_abort () at ./stdlib/abort.c:79
#5 0x000055de28a24165 in S::fn (this=0x7ffcd0d1d80f) at t.cc:4
#6 0x000055de28a2414d in main () at t.cc:9
注意檔案/行資訊和函式名稱的存在。如果我們使用剝離版本,則兩者都不存在:
ore was generated by `./a.out.stripped'.
Program terminated with signal SIGABRT, Aborted.
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
44 ./nptl/pthread_kill.c: No such file or directory.
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
#1 0x00007f12444895df in __pthread_kill_internal (signo=<optimized out>, threadid=<optimized out>) at ./nptl/pthread_kill.c:89
#2 __GI___pthread_kill (threadid=<optimized out>, signo=<optimized out>) at ./nptl/pthread_kill.c:89
#3 0x00007f12445f5e70 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007f1244428469 in __GI_abort () at ./stdlib/abort.c:79
#5 0x000055de28a24165 in ?? ()
#6 0x000055de28a2414d in ?? ()
#7 0x00007f124442920a in __libc_start_call_main (main=main@entry=0x55de28a24139, argc=argc@entry=1, argv=argv@entry=0x7ffcd0d1d928) at ../sysdeps/nptl/libc_start_call_main.h:58
#8 0x00007f12444292bc in __libc_start_main_impl (main=0x55de28a24139, argc=1, argv=0x7ffcd0d1d928, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffcd0d1d918) at ../csu/libc-start.c:389
#9 0x000055de28a24071 in ?? ()
現在讓我們重復錯誤構建的二進制檔案(這就是你所擁有的):
g t.cc -o b.out && strip ./b.out -o b.out.stripped &&
./b.out.stripped; gdb -q --batch -ex where ./b.out core
Aborted (core dumped)
...
warning: core file may not match specified executable file.
[New LWP 478614]
Core was generated by `./b.out.stripped'.
Program terminated with signal SIGABRT, Aborted.
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
44 ./nptl/pthread_kill.c: No such file or directory.
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
#1 0x00007f21a0a895df in __pthread_kill_internal (signo=<optimized out>, threadid=<optimized out>) at ./nptl/pthread_kill.c:89
#2 __GI___pthread_kill (threadid=<optimized out>, signo=<optimized out>) at ./nptl/pthread_kill.c:89
#3 0x00007f21a0bf5e70 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007f21a0a28469 in __GI_abort () at ./stdlib/abort.c:79
#5 0x000056049b052165 in S::fn() ()
#6 0x000056049b05214d in main ()
注意函式名稱 ( S::fn(), main) 的存在,但缺少檔案/行/引數資訊。這與您觀察到的結果相符。
如果您再次嘗試使用b.out.stripped,您將獲得與之前使用 運行時相同的結果a.out.stripped:
Core was generated by `./b.out.stripped'.
Program terminated with signal SIGABRT, Aborted.
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
44 ./nptl/pthread_kill.c: No such file or directory.
#0 __pthread_kill_implementation (threadid=<optimized out>, signo=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
#1 0x00007f21a0a895df in __pthread_kill_internal (signo=<optimized out>, threadid=<optimized out>) at ./nptl/pthread_kill.c:89
#2 __GI___pthread_kill (threadid=<optimized out>, signo=<optimized out>) at ./nptl/pthread_kill.c:89
#3 0x00007f21a0bf5e70 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007f21a0a28469 in __GI_abort () at ./stdlib/abort.c:79
#5 0x000056049b052165 in ?? ()
#6 0x000056049b05214d in ?? ()
#7 0x00007f21a0a2920a in __libc_start_call_main (main=main@entry=0x56049b052139, argc=argc@entry=1, argv=argv@entry=0x7fff3554bc78) at ../sysdeps/nptl/libc_start_call_main.h:58
#8 0x00007f21a0a292bc in __libc_start_main_impl (main=0x56049b052139, argc=1, argv=0x7fff3554bc78, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff3554bc68) at ../csu/libc-start.c:389
#9 0x000056049b052071 in ?? ()
此外, readelf --debug-dump=info courierd 顯示了很多版本 4 的內容。
是的,如果您運行readelf --debug-dump b.out,您可以觀察到很多來自 , 等的 DWARF4 內容 crt0.o(crtbegin.o取決于您的 GCC 和 GLIBC 的構建方式)。
如果你有.c鏈接的檔案,這些也將有 DWARF4 除錯資訊,因為你CFLAGS 確實包含-g.
但是 DWARF4 的任何東西都不會來自msgq::completed定義的任何地方。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/529841.html
