c++ Abseil的GetStackTrace函数不返回任何内容

dwbf0jvd  于 2023-04-01  发布在  其他
关注(0)|答案(1)|浏览(145)
void show_stackframe() {
        std::cout << "Show stack frame function from Abseil." << std::endl;
        void *trace[100];
  
        int i, trace_size = 0;

        trace_size = absl::GetStackTrace(trace, 100, 0);
        printf("[bt] Execution path: %d\n", trace_size);
        for (i=0; i<trace_size; ++i)
        {
             printf("[bt] %s\n", (char*)trace[i]);
        }
     }

我在一个大型代码库的某个点上使用了这个函数getstacktrace(之前我在这一点上造成了一个分段错误,我使用GDB查看了堆栈跟踪。)但是我根本没有得到任何堆栈跟踪。也就是说,Abseil返回的trace_size是0。为什么这行不通?
这是因为我试图获取堆栈跟踪的点在线程内部吗?这在多线程环境中不起作用吗?

hof1towb

hof1towb1#

absl::GetStackTrace只返回代码地址(程序计数器),而不是函数名,所以你不能像处理字符串一样处理printf(“%s”)。要将代码地址转换为函数名,你需要像Symbolize这样的东西,代码来自https://clickhouse.com/codebrowser/ClickHouse/contrib/abseil-cpp/absl/debugging/symbolize_elf.inc.html#_ZN4absl12lts_202111029SymbolizeEPKvPci:

bool Symbolize(const void *pc, char *out, int out_size) {
  // Symbolization is very slow under tsan.
  ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
  SAFE_ASSERT(out_size >= 0);
  debugging_internal::Symbolizer *s = debugging_internal::AllocateSymbolizer();
  const char *name = s->GetSymbol(pc);
  bool ok = false;
  if (name != nullptr && out_size > 0) {
    strncpy(out, name, out_size);
    ok = true;
    if (out[out_size - 1] != '\0') {
      // strncpy() does not '\0' terminate when it truncates.  Do so, with
      // trailing ellipsis.
      static constexpr char kEllipsis[] = "...";
      int ellipsis_size =
          std::min(implicit_cast<int>(strlen(kEllipsis)), out_size - 1);
      memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size);
      out[out_size - 1] = '\0';
    }
  }
  debugging_internal::FreeSymbolizer(s);
  ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END();
  return ok;
}

相关问题