Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C/C++;更漂亮?_C++_C_Callstack - Fatal编程技术网

C++ 如何在C/C++;更漂亮?

C++ 如何在C/C++;更漂亮?,c++,c,callstack,C++,C,Callstack,我想打印带有更多信息的调用堆栈,比如gdb 这就是我目前所拥有的 void to_print_callstack() { void *buffer[100]; int n = backtrace(buffer,10); char **str = backtrace_symbols(buffer, n); for (int i = 0; i < n; i++) { printf("%d: %s\n", i, str[i]);

我想打印带有更多信息的调用堆栈,比如gdb

这就是我目前所拥有的

void to_print_callstack()
{
    void *buffer[100];
    int n = backtrace(buffer,10);
    char **str = backtrace_symbols(buffer, n);

    for (int i = 0; i < n; i++)
    {
        printf("%d:  %s\n", i, str[i]);
    }
}
这很难读。使用函数名会更好。
非常感谢您提供的提示。

免责声明:以下内容主要针对使用GCC或Clang with libstdc++的Linux,您可能需要在其他系统上使用不同的方法

最重要的是在链接时向命令行添加
-rdynamic
。我不知道是否所有系统都需要这样做,但对我来说,这实际上把所有这些地址都变成了符号

现在,您已经获得了一些信息,您可能需要对符号进行修改。您可以从一个独立函数开始对任何符号进行demangle:

// you most likely need these headers (plus stuff for std::cout, ...)
#include <cxxabi.h>
#include <execinfo.h>

std::string demangle( const char* const symbol )
{
    const std::unique_ptr< char, decltype( &std::free ) > demangled(
      abi::__cxa_demangle( symbol, 0, 0, 0 ), &std::free );
    if( demangled ) {
        return demangled.get();
    }
    else {
        return symbol;
    }
}

(由于我没有使用
std::cout
,所以我不得不稍微修改一下我的代码,因此可能会有一些小问题-检查代码是否适合您,如果不适合,您需要帮助修复它,请告诉我)。

在我阅读所需材料时,您回答了——:)“如果不使用特殊链接器选项,符号名称可能不可用。对于使用GNU链接器的系统,有必要使用-rdynamic链接器选项。请注意,“静态”函数的名称不会公开,并且在回溯中不可用。“@Jongware你可能会对更新的答案感兴趣。这太棒了。它对我有用。我想知道是否有一种方法可以同时打印行号?@Manoj很遗憾,我一直无法找到一种合理的方法来获得帧的行号。
// you most likely need these headers (plus stuff for std::cout, ...)
#include <cxxabi.h>
#include <execinfo.h>

std::string demangle( const char* const symbol )
{
    const std::unique_ptr< char, decltype( &std::free ) > demangled(
      abi::__cxa_demangle( symbol, 0, 0, 0 ), &std::free );
    if( demangled ) {
        return demangled.get();
    }
    else {
        return symbol;
    }
}
void backtrace()
{
  // TODO: replace hardcoded limit?                                                      
  void* addresses[ 256 ];
  const int n = ::backtrace( addresses, std::extent< decltype( addresses ) >::value );
  const std::unique_ptr< char*, decltype( &std::free ) > symbols(
    ::backtrace_symbols( addresses, n ), &std::free );
  for( int i = 0; i < n; ++i ) {
    // we parse the symbols retrieved from backtrace_symbols() to                                                                                                                
    // extract the "real" symbols that represent the mangled names.                                                                                                              
    char* const symbol = symbols.get()[ i ];
    char* end = symbol;
    while( *end ) {
      ++end;
    }
    // scanning is done backwards, since the module name
    // might contain both '+' or '(' characters.
    while( end != symbol && *end != '+' ) {
      --end;
    }
    char* begin = end;
    while( begin != symbol && *begin != '(' ) {
      --begin;
    }

    if( begin != symbol ) {
      std::cout << std::string( symbol, ++begin - symbol );
      *end++ = '\0';
      std::cout << demangle( begin ) << '+' << end;
    }
    else {
      std::cout << symbol;
    }
    std::cout << std::endl;
  }
}