Abseil's GetStackTrace function returns back nothing

416 views Asked by At
    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]);
        }
     }

I was using this function get stacktrace at a certain point in a large code base. I know for a fact that the point at which I am trying to get stacktrace at is at 10 function calls deep(Previously I caused a segmentation fault at this point and I looked the stack trace using GDB.) However I am getting no stack-trace back at all. I.e. the trace_size that Abseil is returning back is 0. Why is this not working?

Is it because the point at which I am trying to obtain a stack-trace is inside a thread? Does this not work in a multithreaded environment?

1

There are 1 answers

0
Binglin Chang On

absl::GetStackTrace only return the code address(program counter), it's not the function name, so you cannot do printf("%s") stuff as if it's a string. To convert code address to function name, you need something like Symbolize, code from 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;
}