С помощью
#include <execinfo.h>
Можно получить доступ к методам для размотки стека, по крайней мере, в большинстве конфигураций Linux. Тем не менее, это позволяет извлечь char * в некоторую NTBS (байтовую строку с нулевым символом в конце), которая показывает некоторую информацию, но не всю, особенно нет:
Я написал bash-скрипт, который может определить номер строки и файл, используя objdump и текстовый адрес инструкции, однако его использование утомительно, поскольку мне приходится копировать и вставлять в него адрес нескольких кадров стека вручную.
Учитывая, что g ++ позволяет включать символы отладки с параметром командной строки -g, как я могу анализировать и обращаться к ним в c ++ программно? Отладчики, такие как gdb и valgrind, также могут каким-то образом получать доступ к этой информации во время выполнения: я предполагаю, что они используют какую-то библиотеку для этого или, если они реализуют ее, сами экспортируют функциональность в виде API. Например, valgrind определяет некоторые интересные объявления функций в include / pub_tool_debuginfo.h. К сожалению, я не смог найти ничего другого. Я создал это как отправную точку:
#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;
}}
источник: http://ideone.com/RWoADT
Есть ли какие-либо предложения по добавлению этого кода для вывода удобной для чтения отладочной информации?
Как примечание, я реализую это для использования с mex, компилятором matlab, который использует g [++ | cc]. Всякий раз, когда я использую функциональность, программа находится в «хорошем» состоянии, то есть обнаружена ошибка, но действительно замечено, что это произошло; как ошибка сегментации.
Например, можно проверить, является ли аргумент sqrt неотрицательным, и если нет, использовать stck :: stacktrace, чтобы показать, где это произошло.
Я думаю, что информация не доступна напрямую во время выполнения (хотя я не уверен), но доступна только в исполняемом файле файл, не в исполняемом файле текст в памяти. (Пожалуйста, поправьте меня, если я ошибаюсь.
Следовательно, я думаю, что нет никакого способа разбора исполняемого файла файл, например через 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;
}}
Задача ещё не решена.