Programmatically get debug information

烈酒焚心 提交于 2020-06-16 05:59:11

问题


Using

#include <execinfo.h>

one can access methods for unwinding the stack, at least on a most linux configurations. However, this allows one to fetch a char * to some NTBS (null terminated byte string) which shows some information, but not all of it, especially not:

  • file names
  • line numbers
  • function names

I have written a bash-script which can deduce a line number and a file using objdump and the text address of the instruction, however its use is tedious as I have to copy paste the address of multiple stack frames to it manually.

Given that g++ allows one to include debugging symbols with the -g command line option, how can I parse and access them in c++ programmatically? Debuggers like gdb and valgrind are also capable of accessing this information at runtime somehow: I'm assuming they use some library for that or if they implement it themselves export the functionality as an API. For example, valgrind defines some interesting function declarations in include/pub_tool_debuginfo.h. Unfortunately, I couldn't find anything else. I created this as a starting point:

#include <execinfo.h>

namespace stck {


class stacktrace_t {};

stacktrace_t stacktrace;

std::ostream &operator<<(std::ostream &out, stacktrace_t) {
  out << "stacktrace:\n";

  size_t max = 256;
  void **stackframes = new void *[max];
  size_t numel;
  while ((numel = backtrace(stackframes, max)) >= max) {
    max *= 2;
    delete[] stackframes;
    stackframes = new void *[max];
  }

  char **symbols = backtrace_symbols(stackframes, numel);
  for(size_t i = 0; i < numel; ++i)
    out << symbols[i] << '\n';

  delete[] stackframes;
  return out;
}


}

source: http://ideone.com/RWoADT

Are there any suggestions to append this code to also output human readable debugging information?

As a note, I'm implementing this for usage with mex, a matlab compiler which uses g[++|cc]. Whenever I'm using the functionality, the program is in a 'good' state, that is an error is detected but noting really has has happened; like a segmentation fault.

For example, one could check if the argument of sqrt is non-negative, and if not use the stck::stacktrace to show where this happened.

update

I think the information is not directly available at runtime (although I'm not sure), but is only available in the executable file, not in the executable text in memory. (Please correct me if I'm wrong.

Hence I think there is no way around parsing the executable file, for example via addre2line:

namespace stck {

std::string getstackframe(char *frame) {
  std::string fr(frame);
  size_t loc0 = fr.find("(");
  size_t loc1 = fr.find(")");
  std::stringstream ss;
  ss << "addr2line -e " << fr.substr(0, loc0) << " -pfC " << fr.substr(loc0 + 2, loc1 - loc0 - 2);

  FILE* pipe = popen(ss.str().c_str(), "r");
  char buffer[128];

  std::stringstream result;
  while(!feof(pipe))
    if (fgets(buffer, 128, pipe) != NULL)
      result << buffer;

  pclose(pipe);
  return result.str();
}

class stacktrace_t {};

stacktrace_t stacktrace;

std::ostream &operator<<(std::ostream &out, stacktrace_t) {
  out << "stacktrace:\n";

  size_t max = 256;
  void **stackframes = new void *[max];
  size_t numel;
  while ((numel = backtrace(stackframes, max)) >= max) {
    max *= 2;
    delete[] stackframes;
    stackframes = new void *[max];
  }

  char **symbols = backtrace_symbols(stackframes, numel);
  for(size_t i = 0; i < numel; ++i)
    out << getstackframe(symbols[i]);

  out << '\n';

  delete[] stackframes;
  return out;
}


}

来源:https://stackoverflow.com/questions/27112514/programmatically-get-debug-information

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!