3

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

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

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

问题是否与我正在链接的第三方库之一以及它们的编译方式有关?还是完全不同的东西?

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

/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/adrianrigore/Documents/Gemsweeper Mac/build/Debug" -L/Developer/SDKs/MacOSX10 .5.sdk/usr/local/lib -L/opt/local/lib "-F/Users/adrianrigigore/Documents/Gemsweeper Mac/build/Debug" -F/Users/adrianrigore/Library/Frameworks -F/Developer/ SDKs/MacOSX10.5.sdk/Library/Frameworks -filelist "/Users/adrianrigore/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/3rd party/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 -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"-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/build/Debug/Gemsweeper Mac.app/Contents/MacOS /Gemsweeper Mac"-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/build/Debug/Gemsweeper Mac.app/Contents/MacOS /Gemsweeper Mac"8 -framework SDL -framework Cocoa -o "/Users/adriangrigore/Documents/Gemsweeper Mac/build/Debug/Gemsweeper Mac.app/Contents/MacOS/Gemsweeper Mac"8 -framework SDL -framework Cocoa -o "/Users/adriangrigore/Documents/Gemsweeper Mac/build/Debug/Gemsweeper Mac.app/Contents/MacOS/Gemsweeper Mac"

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

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

我已经尝试编译一个 Xcode SDL 项目模板并且没有遇到同样的问题,所以这一定是由于我的项目中有一些特殊的东西。

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

4

11 回答 11

3

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

尝试获取最新的 gdb。

于 2012-12-10T09:56:34.167 回答
1

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

于 2009-03-03T09:34:52.627 回答
1

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

...只是一个想法

读这个

于 2009-03-03T09:36:47.643 回答
1

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

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

第三方库似乎是发布版本(当然,除非您自己重命名它们)例如,我确信 boost 使用-d库名称中的名字来表示调试库(例如libboost_filesystem-mt-d.a)。

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

于 2009-02-27T16:24:18.917 回答
1

你在编译优化吗?我发现 O2 或更高级别的符号与符号混淆很多,使 gdb 和核心文件几乎毫无用处。

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

于 2009-02-27T16:33:46.320 回答
1

我试过编译一个 XCode SDL 项目模板并没有遇到同样的问题,所以它一定是由于我的项目中有一些特殊的东西。

正确的。您的项目设置有所不同。

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

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

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

你的问题应该在这样做之后解决。这是您需要更改设置的项目设置屏幕:

替代文字

于 2009-03-04T05:10:38.103 回答
0

I encountered this several years ago when transitioning from the Codewarrior compilers to Xcode. I believe the way to get around this is to put the flag "-fno-inline-functions" in Other C Flags (for Dev only).

This problem was more pronounced on the PowerPC architecture for us.

What about if you remove the "-fvisibility-inlines-hidden" and "-mfix-and-continue" flags?

I've never had the "fix and continue" feature work properly for me.

于 2009-03-05T16:10:15.843 回答
0

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

这里

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

IMPLEMENT_APP(MyApp)

于 2009-03-05T22:13:25.563 回答
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[]) {
于 2009-03-08T10:16:29.037 回答
0

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

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

只是一个猜测。

于 2009-03-04T20:21:03.267 回答
0

在这里查看我的答案

我现在已经下载并编译了 FreeImage 源代码,是的,文件b44ExpLogTable.cpp被编译成libfreeimage.a. 问题看起来像脚本gensrclist.sh只是收集所有.cpp文件而没有跳过带有 main in 的文件。该脚本生成一个名为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
于 2009-03-06T11:15:51.157 回答