GCC调试器堆栈跟踪显示错误的文件名和行号

问题描述 投票:3回答:11

我正在尝试将一个相当大的C ++项目移植到在Mac OS X上使用g ++ 4.0。我的项目编译没有错误,但我无法让GDB正常工作。当我通过在GDB命令行上键入“bt”来查看堆栈时,显示的所有文件名和行号都是错误的。

例如,根据GDB堆栈跟踪,我的main()函数应该是来自Mac OS X SDK的stdexcept,这没有任何意义。

什么可能导致GDB故障如此严重?我已经在代码中检查了#line和#file语句,并确保代码只有unix行结尾。我也清理并重建了这个项目。我也试过调试一个Hello World项目,并且没有遇到同样的问题。

问题可能与我链接的第三方库之一以及编译方式有关吗?或者它是完全不同的东西?

以下是由gcc执行的对ldXcode的两个示例性调用。 AFAIK我的项目中的所有cpp文件都使用相同的参数进行编译和链接。

/Developer/usr/bin/gcc-4.0 -x c ++ -arch i386 -fmessage-length = 0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -O0 -fpermissive -Wreturn-type -Wunused-variable -DNO_BASS_SOUND -D_DEBUG -DXCODE -D__WXMAC__ -isysroot /Developer/SDKs/MacOSX10.5.sdk -mfix-and-continue -fvisibility-inlines-hidden -mmacosx-version-min = 10.4 -gdwarf-2 -D_FILE_OFFSET_BITS = 64 -D_LARGE_FILES -D__WXDEBUG__ -D__WXMAC__ -c“/ Users / adriangrigore / Documents / Gemsweeper Mac / TSDLGameBase.cpp”-o“/ Users / adriangrigore / Documents / Gemsweeper Mac / build / Gemsweeper Mac.build/Debug/Gemsweeper Mac.build/Objects-normal/ I386 / TSDLGameBase.o”

/Developer/usr/bin/g++-4.0 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk“-L / Users / adriangrigore / Documents / Gemsweeper Mac / build / Debug”-L / Developer / SDKs / MacOSX10 .5.sdk / usr / local / lib -L ​​/ opt / local / lib“-F / Users / adriangrigore / Documents / Gemsweeper Mac / build / Debug”-F / Users / adriangrigore / Library / Frameworks -F / Developer / SDKs / MacOSX10.5.sdk / Library / Frameworks -filelist“/ Users / adriangrigore / Documents / Gemsweeper Mac / build / Gemsweeper Mac.build/Debug/Gemsweeper Mac.build/Objects-normal/i386/Gemsweeper Mac.LinkFileList” - mmacosx-version-min = 10.4 /opt/local/lib/libboost_program_options-mt.a /opt/local/lib/libboost_filesystem-mt.a /opt/local/lib/libboost_serialization-mt.a / opt / local / lib / libboost_system-mt.a /opt/local/lib/libboost_thread-mt.a“/ Users / adriangrigore / Documents / Gemsweeper Mac / 3rd party / FreeImage / Dist / libfreeimage.a”“/ Users / adriangrigore / Documents / Gemsweeper Mac /第三方/ cpuinfo-1.0 / libcpuinfo.a“-L / usr / local / lib -framework IOKit -framework Carbon -framework Cocoa -framework Sy干-framework的QuickTime -framework的OpenGL -framework AGL -lwx_macd_richtext-2.8 -lwx_macd_aui-2.8 -lwx_macd_xrc-2.8 -lwx_macd_qa-2.8 -lwx_macd_html-2.8 -lwx_macd_adv-2.8 -lwx_macd_core-2.8 -lwx_base_carbond_xml-2.8 -lwx_base_carbond_net-2.8 -lwx_base_carbond-2.8 -framework SDL -framework Cocoa -o“/ Users / adriangrigore / Documents / Gemsweeper Mac / build / Debug / Gemsweeper Mac.app/Contents/MacOS/Gemsweeper Mac”

请注意,我已经问了一个关于Xcode调试器here的类似问题,但是我正在重新发布,因为我刚刚得知这实际上不是Xcode的错,而是GCC / ld / GDB的问题。

编辑:我的项目使用以下第三方库:SDLBoostwxWidgets。我不确定这是否对这个问题很重要,但我只是想提一下,以防万一。

我已经尝试编译Xcode SDL项目模板并且没有遇到同样的问题,所以它必须是由于我的项目中的一些特殊内容。

第二次编辑:正如我刚刚发现的那样,我在使用字符串“这是一个自动生成的”搜索文件时犯了一个错误。我刚刚发现了几十个带有相同字符串的文件,都属于FreeImage,我正在使用的第三方库之一。所以,问题似乎与FreeImage有关,但我仍然不确定如何继续。

c++ gcc gdb
11个回答
3
投票

当我的gdb版本与我的g ++版本不匹配时,我遇到了这些症状。

尝试获取最新的gdb。


0
投票

看我的答案here

我现在已经下载并编译了FreeImage源代码,是的,文件b44ExpLogTable.cpp被编译成libfreeimage.a。问题看起来像脚本gensrclist.sh只收集所有.cpp文件而不跳过带有main的文件。该脚本生成一个名为Makefile.srcs的文件,但已经提供了一个。 (在我的Leopard上运行它失败了,sh的一些问题 - 如果我将sh改为bash,它会起作用)

在你改变任何东西之前,这给了一个a.out

c++ libfreeimage.a

文件Makefile.srcs已经创建,所以你应该能够从中删除文件b44ExpLogTable.cpp。然后做

make -f Makefile.osx clean
make -f Makefile.osx

完成后,上面的c++ libfreeimage.a应该给出以下错误

Undefined symbols:
  "_main", referenced from:
      start in crt1.10.5.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

0
投票

我有一个你可以尝试的新东西。

就在你自己的main之前,你可以写

#ifdef main
#  error main is defined
#endif

int main(int argc, char *argv[]) {

如果你有一些重新定义main的标题,这应该会出错。

如果您定义了自己的定义,则可能会收到先前定义的警告

#define main foo

int main(int argc, char *argv[]) {

您也可以在undef之前尝试main

#undef main

int main(int argc, char *argv[]) {

1
投票

你的cpp文件肯定有调试符号(-gdwarf-2选项)。

您是否为调试符号使用单独的dSYM文件?或者它们是否在目标文件中。我首先尝试在dSYM文件中使用DWARF并查看是否有帮助(反之亦然)

第三方库似乎是发布版本(除非你自己重命名它们),例如我肯定知道boost使用库名中的-d monniker来表示调试库(例如libboost_filesystem-mt-d.a)。

现在,这不应该造成问题,它应该只是意味着你不能进入第三方库的调用。 (至少在你做的时候没有任何意义;)但是既然你有问题,可能值得尝试链接这些库的调试版本......


1
投票

你正在编译优化吗?我发现O2或更高版本的符号相当混乱,使得gdb和核心文件几乎没用。

另外,请确保使用-g选项进行编译。


1
投票

您是否正在使用SDL? SDL重新定义了main,因此您的主要名称将被命名为SDL_main,并且SDL部分可能会进行大量优化,因此在那里您将无法获得良好的gdb输出。

...只是一个想法

Read this


1
投票

对于测试,您可以检查addr2line是否为您提供了预期值。如果是这样,这表明你的编译/链接参数生成的ELF没有任何问题,并且对GDB产生了所有怀疑。如果没有,那么工具和ELF文件仍然存在怀疑。


1
投票

我已经尝试编译一个XCode SDL项目模板,并没有遇到同样的问题,所以它必须是由于我的项目中的一些特殊内容。

正确。您的项目设置是不同的。

您需要在调试版本的Xcode项目设置中禁用调试优化。不幸的是,Xcode会让GDB跳转到奇怪的行(乱序),当你期望它按顺序移动时。

转到您的项目设置。设置以下内容

1) Instruction Scheduling   = None
2) Optimization Level       = None [-O0]
3) ZERO_LINK                = None

这样做之后你的问题应该继续存在。以下是您需要更改设置的项目设置屏幕:

alt text


0
投票

从您的标志中,调试信息应该在目标文件中。

您的项目设置是否在一个位置构建可执行文件,然后在完成后将最终可执行文件移动到另一个位如果是这种情况,那么gdb可能无法找到目标文件,因此无法正确地从目标文件中检索调试信息。

只是一个猜测。


0
投票

几年前我从Codewarrior编译器转换到Xcode时遇到了这个问题。我相信解决这个问题的方法是将旗帜“-fno-inline-functions”放入其他C旗帜(仅适用于Dev)。

对于我们来说,这个问题在PowerPC架构上更为明显。

如果删除“-fvisibility-inlines-hidden”和“-mfix-and-continue”标志怎么办?

我从来没有让“修复和继续”功能正常工作。


0
投票

如果你使用他们的main宏,WxWidgets也会定义他们自己的IMPLEMENT_APP()

来自here

与所有程序一样,必须有“主要”功能。在wxWidgets下,main使用此宏实现,该宏创建应用程序实例并启动程序。

IMPLEMENT_APP(MyApp)

© www.soinside.com 2019 - 2024. All rights reserved.