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

时间:2009-02-27 13:38:44

标签: c++ gcc gdb

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

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

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

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

以下是由Xcode执行的对gccld的两次示例性调用。 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   “/用户/ adriangrigore /文档/ Gemsweeper   MAC /编译/ 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 /用户/ adriangrigore /文档/ Gemsweeper   MAC /编译/调试”   -L /开发商/软件开发工具包/ MacOSX10.5.sdk在/ usr / local / lib目录   -L / opt / local / lib“-F / Users / adriangrigore / Documents / Gemsweeper   MAC /编译/调试”   -F /用户/ adriangrigore /库/框架   -F /开发商/软件开发工具包/ MacOSX10.5.sdk /库/框架   -filelist“/ Users / adriangrigore / Documents / Gemsweeper   MAC /编译/ 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   “/用户/ adriangrigore /文档/ Gemsweeper   MAC / 3   党/的FreeImage /距离/ libfreeimage.a”   “/用户/ adriangrigore /文档/ Gemsweeper   MAC / 3   党的内/ cpuinfo-1.0 / libcpuinfo.a”   -L / usr / local / lib -framework IOKit -framework Carbon -framework Cocoa -framework System -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 /编译/调试/ Gemsweeper   Mac.app/Contents/MacOS/Gemsweeper Mac“

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

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

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

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

11 个答案:

答案 0 :(得分:3)

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

尝试获取最新的gdb。

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

......只是一个想法

Read this

答案 5 :(得分:1)

  

我尝试过编译XCode SDL   项目模板并没有   遇到同样的问题,所以它   必须是由于我的特殊之处   项目

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

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

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

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

执行此操作后,您的问题应该继续存在。 以下是您需要更改设置的项目设置屏幕:

alt text

答案 6 :(得分:0)

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

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

只是一个猜测。

答案 7 :(得分:0)

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

这个问题在我们的PowerPC架构上更为明显。

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

我从来没有让“修复和继续”功能适合我。

答案 8 :(得分:0)

如果您使用main

,WxWidgets也会定义自己的IMPLEMENT_APP()

来自here

  

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

     

IMPLEMENT_APP(MyApp)

答案 9 :(得分: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

答案 10 :(得分: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[]) {