我正在使用GCC编译器在Linux上工作.当我的C++程序崩溃时,我希望它能自动生成一个堆栈跟踪.
我的程序由许多不同的用户运行,它也可以在Linux,Windows和Macintosh上运行(所有版本都使用编译gcc).
我希望我的程序能够在崩溃时生成堆栈跟踪,并且在用户下次运行它时,它会询问他们是否可以将堆栈跟踪发送给我,以便我可以追踪问题.我可以处理向我发送信息,但我不知道如何生成跟踪字符串.有任何想法吗?
我们在专有的assert宏中使用堆栈跟踪来捕获开发人员的错误 - 当捕获错误时,打印堆栈跟踪.
我发现gcc的配对backtrace()/ backtrace_symbols()方法不足:
第一个问题可以通过abi :: __ cxa_demangle来解决.
然而,第二个问题更加艰难.我发现了替换backtrace_symbols().这比gcc的backtrace_symbols()更好,因为它可以检索行号(如果使用-g编译),并且不需要使用-rdynamic进行编译.
Hoverer代码是GNU许可的,所以恕我直言我不能在商业代码中使用它.
任何建议?
PS
gdb能够打印传递给函数的参数.可能已经要求太多了:)
PS 2
类似的问题(感谢nobar)
我需要从C++程序中获取addr2line提供的信息(来自回溯函数调用的文件和行).是否有类似于addr2line的库调用?
编辑:我在Linux环境中工作.
我知道我可以直接调用addr2line,我知道我可以在我的程序中使用addr2line 的源代码(也是GPL许可).但我想调用库函数(如果存在)更清晰.
编辑:我将使用binutils的bfd,就像addr2line一样.无论如何,bfd意味着什么?
我需要在运行的进程中获取堆栈的基地址。这将使我能够打印将由addr2line理解的原始堆栈跟踪(已剥离运行二进制文件,但addr2line可以访问符号)。我通过检查以下内容的elf标头成功做到了这一点argv[0]:我读取了入口点并将其从中减去&_start:
#include <stdio.h>
#include <execinfo.h>
#include <unistd.h>
#include <elf.h>
#include <stdio.h>
#include <string.h>
void* entry_point = NULL;
void* base_addr = NULL;
extern char _start;
/// given argv[0] will populate global entry_pont
void read_elf_header(const char* elfFile) {
// switch to Elf32_Ehdr for x86 architecture.
Elf64_Ehdr header;
FILE* file = fopen(elfFile, "rb");
if(file) {
fread(&header, 1, sizeof(header), file);
if (memcmp(header.e_ident, ELFMAG, SELFMAG) == 0) {
printf("Entry point from file: %p\n", (void *) header.e_entry);
entry_point = (void*)header.e_entry;
base_addr = …Run Code Online (Sandbox Code Playgroud)