如何在Mac OS X上运行自制的GDB版本?

时间:2021-10-24 16:44:51

I am trying to debug a C++ program in Eclipse using gdb. I think it works fine in my main() function, but elsewhere it gives me a warning when I try to look at the value of a variable:

我正在尝试使用gdb在Eclipse中调试C ++程序。我认为它在我的main()函数中工作正常,但是在我尝试查看变量值时,它会给我一个警告:

Failed to execute MI command:
-data-evaluate-expression variable
Error message from debugger back end:
Could not find the frame base for "Class::method()".`

After scouring the internet, I am having a hard time understanding what this error means or finding out how to fix the problem. There are a few other similar questions (here and here) floating around Stack Overflow.

在浏览互联网之后,我很难理解这个错误的含义或找出如何解决问题。 Stack Overflow还有一些类似的问题(这里和这里)。

Since Apple's Xcode command line tools are painfully out-of-date (see gcc and gdb issues) I needed to use my own homebrewed versions. I don't know if there is something in the setup for these tools that I might have missed.

由于Apple的Xcode命令行工具已经过时了(请参阅gcc和gdb问题),我需要使用自己的自制版本。我不知道这些工具的设置中是否有我可能错过的东西。

I can debug from command line using gdb and I hit the same error: "Could not find the frame base for "Class::method()", so I'm pretty sure it is not an issue with Eclipse.

我可以使用gdb从命令行调试,我遇到了同样的错误:“找不到”Class :: method()“的框架基础,所以我很确定它不是Eclipse的问题。

Does anything jump out to anyone, that might be causing this problem?

是否有任何事情可能导致这个问题?

  • Mac OS X 10.8.5 (Mountain Lion)
  • Mac OS X 10.8.5(Mountain Lion)

  • Eclipse 4.2.1 (Juno)
  • Eclipse 4.2.1(Juno)

  • gcc 4.8.2 (homebrewed) (with -O0 and -g3)
  • gcc 4.8.2(自制)(带-O0和-g3)

  • gdb 7.6.2 (homebrewed and codesigned)
  • gdb 7.6.2(自制和编码)

Update:

I am also seeing the line:

我也看到了这条线:

BFD: /System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork(i386:x86-64): unknown load command 0x20

Followed by several warnings:

随后是几个警告:

warning: Could not open OSO archive file "/private/tmp/gcc48-KqoQ/gcc-4.8.2/build/x86_64-apple-darwin12.5.0/libstdc++-v3/src/../libsupc++/.libs/libsupc++convenience.a"
warning: Could not open OSO archive file "/private/tmp/gcc48-KqoQ/gcc-4.8.2/build/x86_64-apple-darwin12.5.0/libstdc++-v3/src/../src/c++11/.libs/libc++11convenience.a"
warning: Could not open OSO archive file "/private/tmp/gcc48-KqoQ/gcc-4.8.2/build/x86_64-apple-darwin12.5.0/libstdc++-v3/src/../src/c++98/.libs/libc++98convenience.a"
warning: `/private/tmp/gcc48-KqoQ/gcc-4.8.2/build/x86_64-apple-darwin12.5.0/libstdc++-v3/src/.libs/compatibility-atomic-c++0x.o': can't open to read symbols: No such file or directory.
warning: `/private/tmp/gcc48-KqoQ/gcc-4.8.2/build/x86_64-apple-darwin12.5.0/libstdc++-v3/src/.libs/compatibility-c++0x.o': can't open to read symbols: No such file or directory.
warning: `/private/tmp/gcc48-KqoQ/gcc-4.8.2/build/x86_64-apple-darwin12.5.0/libstdc++-v3/src/.libs/compatibility-chrono.o': can't open to read symbols: No such file or directory.
warning: `/private/tmp/gcc48-KqoQ/gcc-4.8.2/build/x86_64-apple-darwin12.5.0/libstdc++-v3/src/.libs/compatibility-debug_list-2.o': can't open to read symbols: No such file or directory.
...

which continues for several lines. Google searches for "gdb bfd unknown load command" reveal a lot of sites without any solution, but they all seem to indicate that there may be a conflict between non-apple versions of gdb and Mac OS X 10.8+.

继续几行。谷歌搜索“gdb bfd unknown load command”显示很多站点没有任何解决方案,但它们似乎都表明非苹果版本的gdb和Mac OS X 10.8+之间可能存在冲突。

Any insight would help a ton!

任何见解都会有所帮助!

1 个解决方案

#1


1  

It's because the name mangling. Names are mangled same with GCC and Clang (they often share similar mechanisms). Name mangling makes it available to have C/C++ method and Assembly procedure with the same name. See what happens to a C definition:

这是因为名字错了。名字与GCC和Clang相同(它们通常具有相似的机制)。名称修改使其可用于具有相同名称的C / C ++方法和汇编过程。看看C定义会发生什么:

void myfunc() {}

We use nm to view binary names of symbols. Use nm --demangle to view unmangled names. Nm output for compiled file is: ... 0000000000000000 T _myfunc ... Number of other symbols depends on debugging level, see GCC manpage for -O and -g options. As we see, there is a number. It's hexadecimal. It has eight digits on 32bit machines and sixteen digits on 64bit machines (it's because n-bit CPU means that n-bits represent a pointer, the symbol is really a pointer inside the binary file). Then we have symbol type. Only two values are interesting now: T is a C/C++/... method, t is an assembler procedure. See what goes on if we compile following assembly code:

我们使用nm来查看符号的二进制名称。使用nm --demangle查看未编码的名称。编译文件的Nm输出为:... 0000000000000000 T _myfunc ...其他符号的数量取决于调试级别,请参阅-O和-g选项的GCC联机帮助页。如我们所见,有一些数字。它是十六进制的。它在32位机器上有8位数字,在64位机器上有16位数字(这是因为n位CPU意味着n位表示指针,该符号实际上是二进制文件中的指针)。然后我们有符号类型。现在只有两个值很有趣:T是C / C ++ / ...方法,t是汇编程序。如果我们编译以下汇编代码,请看看会发生什么:

myproc:

GCC and Clang shouldn't push debugging symbols when compiling Assembly, so nm output will probably look like:

在编译汇编时,GCC和Clang不应该推送调试符号,因此nm输出可能看起来像:

0000000000000000 t myproc

Assembly procedure names are not mangled. C++ is mangled, very strangely. Some characters, like : or , are not allowed in symbol name. Compile this C++ source:

装配过程名称不会受到损坏。 C ++被破坏了,非常奇怪。符号名称中不允许使用某些字符,例如:或。编译这个C ++源代码:

namespace myspace { void myfunc() {} }

We see output:

我们看到输出:

...
0000000000000000 T __ZN7myspace6myfuncEv
...

And main method name is never mangled. If we have like this:

主要方法名称永远不会被破坏。如果我们喜欢这样:

int main(int argc, char** argv) {}
int main(std::vector<std::string> args) {}

only the second name is mangled. I think this may be the problem. And, these warnings mean NOTHING. They mean that system was recompiled with low debugging symbol count.

只有第二个名字被破坏了。我想这可能是问题所在。并且,这些警告意味着什么。它们意味着系统重新编译时调试符号数较少。

#1


1  

It's because the name mangling. Names are mangled same with GCC and Clang (they often share similar mechanisms). Name mangling makes it available to have C/C++ method and Assembly procedure with the same name. See what happens to a C definition:

这是因为名字错了。名字与GCC和Clang相同(它们通常具有相似的机制)。名称修改使其可用于具有相同名称的C / C ++方法和汇编过程。看看C定义会发生什么:

void myfunc() {}

We use nm to view binary names of symbols. Use nm --demangle to view unmangled names. Nm output for compiled file is: ... 0000000000000000 T _myfunc ... Number of other symbols depends on debugging level, see GCC manpage for -O and -g options. As we see, there is a number. It's hexadecimal. It has eight digits on 32bit machines and sixteen digits on 64bit machines (it's because n-bit CPU means that n-bits represent a pointer, the symbol is really a pointer inside the binary file). Then we have symbol type. Only two values are interesting now: T is a C/C++/... method, t is an assembler procedure. See what goes on if we compile following assembly code:

我们使用nm来查看符号的二进制名称。使用nm --demangle查看未编码的名称。编译文件的Nm输出为:... 0000000000000000 T _myfunc ...其他符号的数量取决于调试级别,请参阅-O和-g选项的GCC联机帮助页。如我们所见,有一些数字。它是十六进制的。它在32位机器上有8位数字,在64位机器上有16位数字(这是因为n位CPU意味着n位表示指针,该符号实际上是二进制文件中的指针)。然后我们有符号类型。现在只有两个值很有趣:T是C / C ++ / ...方法,t是汇编程序。如果我们编译以下汇编代码,请看看会发生什么:

myproc:

GCC and Clang shouldn't push debugging symbols when compiling Assembly, so nm output will probably look like:

在编译汇编时,GCC和Clang不应该推送调试符号,因此nm输出可能看起来像:

0000000000000000 t myproc

Assembly procedure names are not mangled. C++ is mangled, very strangely. Some characters, like : or , are not allowed in symbol name. Compile this C++ source:

装配过程名称不会受到损坏。 C ++被破坏了,非常奇怪。符号名称中不允许使用某些字符,例如:或。编译这个C ++源代码:

namespace myspace { void myfunc() {} }

We see output:

我们看到输出:

...
0000000000000000 T __ZN7myspace6myfuncEv
...

And main method name is never mangled. If we have like this:

主要方法名称永远不会被破坏。如果我们喜欢这样:

int main(int argc, char** argv) {}
int main(std::vector<std::string> args) {}

only the second name is mangled. I think this may be the problem. And, these warnings mean NOTHING. They mean that system was recompiled with low debugging symbol count.

只有第二个名字被破坏了。我想这可能是问题所在。并且,这些警告意味着什么。它们意味着系统重新编译时调试符号数较少。