c++ 使用gdb时找不到调试符号

slsn1g29  于 2023-01-10  发布在  其他
关注(0)|答案(9)|浏览(221)

GNU通用数据库Fedora(6.8-37.el5)内核2.6.18-164.el5
我正试着调试我的应用程序,但是每次我把二进制文件传递给gdb时,它都说:

(no debugging symbols found)

下面是二进制文件的文件输出,如您所见,它没有被剥离:

vid: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

我使用以下CFLAGS进行编译:

CFLAGS = -Wall -Wextra -ggdb -O0 -Wunreachable-code

有谁能告诉我,我是不是错过了一些简单的东西?

uyto3xhc

uyto3xhc1#

-g存在时,“未找到调试符号”最常见的原因是链接行上的某个地方存在一些“杂散”的-s-S参数。
man ld开始:

-s
   --strip-all
       Omit all symbol information from the output file.

   -S
   --strip-debug
       Omit debugger symbol information (but not all symbols) from the output file.
tktrz96b

tktrz96b2#

应用程序必须同时编译链接(带有-g选项)。即,您需要将-g同时放入CPPFLAGSLDFLAGS中。

vjrehmav

vjrehmav3#

有些Linux发行版不使用gdb风格的调试符号(IIRC更喜欢dwarf2)。
通常,gccgdb在使用哪种调试符号方面是同步的,强制使用特定的样式只会导致问题;除非您知道还需要其他东西,否则就只使用-g

vjhs03f7

vjhs03f74#

如果您正在为Android进行编译,您还应该尝试使用-ggdb而不是-g!

13z8s7eq

13z8s7eq5#

将-ggdb替换为-g,并确保没有使用strip命令剥离二进制文件。

pzfprimi

pzfprimi6#

我知道这个问题很久以前就有答案了,但是最近我花了几个小时试图解决一个类似的问题。安装是本地PC运行Debian 8,使用Eclipse CDT Neon.2,远程ARM 7板(Olimex)运行Debian 7.工具链是Linaro 4. 9,在远程板上使用Gdbserver,在本地PC上使用Linaro GDB。我的问题是调试会话将启动,程序将执行,但是断点不起作用,并且当手动暂停时会导致“找不到源”。我的编译行选项(Linaro gcc)包括-ggdb -O 0,正如许多人建议的那样,但仍然是同样的问题。最终我在远程板上尝试gdb,它抱怨没有符号。奇怪的是,“file”报告目标可执行文件上的调试没有剥离。
我最终通过在链接器选项中添加-g来解决这个问题。我不会声称完全理解为什么这会有帮助,但我想把这个传递给其他人,以防万一它会有帮助。在这个例子中,Linux确实需要在链接器选项中添加-g。

pgpifvop

pgpifvop7#

希望你编译的系统和你正在调试的系统有相同的架构。我遇到了一个问题,32位二进制调试符号拒绝加载到我的64位机器上。切换到32位系统对我很有效。

92dk7w1h

92dk7w1h8#

对于那些带着这个问题来到这里并且正在使用Qt的人:在release配置中,有一个步骤是在执行make install的过程中剥离二进制文件。您可以传递配置选项CONFIG+=nostrip来告诉它不要:
取代:

qmake <your options here, e.g. CONFIG=whatever>

加上CONFIG+=nostrip,所以:

qmake <your options here, e.g. CONFIG=whatever> CONFIG+=nostrip
chhkpiq4

chhkpiq49#

到目前为止,我看到的解决方案都很好:
1.必须使用-g调试标志进行编译,以通知编译器生成调试符号
1.确保编译器标志中没有杂散的-s,杂散的-s会剥离所有符号的输出。
这里只是补充一下,因为对我有效的解决方案没有在任何地方列出。编译器标志的顺序很重要。我包含了来自许多位置的多个头文件(-I/usr/local/include -Iutil -I。我在编译时对(-Wall)发出了所有警告。
对我来说正确的食谱是:

gcc -I/usr/local/include -Iutil -I -Wall -g -c main.c -o main.o

注意事项:

  • 包含标志位于开头
  • -Wall在包含标志之后和-g之前
  • -g位于末尾

标志的任何其他顺序将导致不生成调试符号。
我在WSL2上使用Ubuntu 22.04上的gcc版本11.3.0。

相关问题