Я пытаюсь определить, как хранить и затем печатать текущий стек в моих приложениях на C++ в Mac OS X. Основная проблема заключается в том, чтобы заставить dladdr вернуть правильный символ когда задан адрес внутри основного исполняемого файла. Я подозреваю, что проблема на самом деле является компилятором, но я не уверен.Получение текущей трассировки стека в Mac OS X
Я пробовал код backtrace от Darwin/Leopard, но он вызывает dladdr и имеет ту же проблему, что и мой собственный код, вызывающий dladdr.
Оригинальное сообщение: В настоящее время я захватывая стек с этим кодом:
int BackTrace(Addr *buffer, int max_frames)
{
void **frame = (void **)__builtin_frame_address(0);
void **bp = (void **)(*frame);
void *ip = frame[1];
int i;
for (i = 0; bp && ip && i < max_frames; i++)
{
*(buffer++) = ip;
ip = bp[1];
bp = (void**)(bp[0]);
}
return i;
}
который, кажется, работает нормально. Затем, чтобы напечатать стек я ищу на использование dladdr так:
Dl_info dli;
if (dladdr(Ip, &dli))
{
ptrdiff_t offset;
int c = 0;
if (dli.dli_fname && dli.dli_fbase)
{
offset = (ptrdiff_t)Ip - (ptrdiff_t)dli.dli_fbase;
c = snprintf(buf, buflen, "%s+0x%x", dli.dli_fname, offset);
}
if (dli.dli_sname && dli.dli_saddr)
{
offset = (ptrdiff_t)Ip - (ptrdiff_t)dli.dli_saddr;
c += snprintf(buf+c, buflen-c, "(%s+0x%x)", dli.dli_sname, offset);
}
if (c > 0)
snprintf(buf+c, buflen-c, " [%p]", Ip);
который почти работает, некоторый пример вывода:
/Users/matthew/Library/Frameworks/Lgi.framework/Versions/A/Lgi+0x2473d(LgiStackTrace+0x5d) [0x102c73d]
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x2a006(tart+0x28e72) [0x2b006]
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x2f438(tart+0x2e2a4) [0x30438]
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x35e9c(tart+0x34d08) [0x36e9c]
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x1296(tart+0x102) [0x2296]
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x11bd(tart+0x29) [0x21bd]
Это становится имя метода право для общего объекта, но не для основное приложение. Они просто отображают «tart» (или «start» минус первый символ).
В идеале мне бы хотелось указать номера строк, а также имя метода в этой точке. Но я соглашусь на правильное имя функции/метода для стартеров. Возможно, стреляйте по номерам строк после этого, в Linux я слышал, что вам нужно написать собственный синтаксический анализатор для частного блока ELF, у которого есть собственный набор команд. Звучит страшно.
В любом случае, может ли кто-нибудь отсортировать этот код, чтобы он правильно получил имена методов?
В настоящее время я нацелен на текущие и предыдущие версии, то есть Leopard и Tiger. Также у меня есть Tiger на моем Macbook. Поэтому до тех пор, пока не появится снежный барс, мне нужно будет скомпилировать/запустить Tiger. – user33847 2008-11-14 21:50:02