airmax: (Default)
[personal profile] airmax
собственно, продолжение http://www.livejournal.com/users/airmax/60695.html#cutid1


во-первых, никто не отменял чтение документации перед употреблением системных функций :
вызывайте free на результат backtrace_symbols

во-вторых, хотя контекст вызова bt и понятен по первому элементу стека, всё-таки удобней передавать ей имя блока для вывода в лог


void bt(char* fooname)
{
int c, i;
void *addresses[10];
char **strings;

c = backtrace(addresses, 10) ;
strings = backtrace_symbols(addresses,c);
err_report(errfd, "backtrace of %s returned: %d\n", fooname, c);
for(i = 0; i < c; i++) {
err_report(errfd, "[bt] %d: %X %s\n", i, (int)addresses[i], strings[i]);
free(strings);
}
}



в-третьих, для нормального употребления, рекомендуется компилировать со следующими ключами:
g++ -g -fPIC -O -rdynamic

и кормить порожденный лог утилитам c++filt или addr2line.
первая делает demangle имени C++ функции/метода.
вторая берет адрес в бинарнике и пытается получить по нему имя файла и номер строки


собственно, ловушка на слонопотама теперь выглядит так (tee и ключ -f добавлены чтобы и на терминале любоваться):
tail -f /home/responder/logs/errors | grep "\[bt\]" | awk '{ print "echo \"",$1,$2,$3,"\" `addr2line -C -s -e responder "$4"` \"",$5,$6,$7,"\""}' | sh | tee -a backtrace.log


где /home/responder/logs/errors - имя файла, в который фигачит err_repost,
responder - имя бинарника, который падает, гад.
backtrace.log - имя лога, в который сваливается только

если выводить также и имя функции, а не только номер строки - добавляете -f к addr2line - но при этом вывод сильно разъезжается если используются С++-ные std классы =)
поэтому, далее - кастуем фильтр, сворачивающий шаблоны STL до удобоваримых std::string, std::vector и т.п.

Качаем:
wget "http://www.downloadcounter.com/cgi-bin/download.pl?username=leor&account=5" | tar -xf gstlfilt.tar gSTLFilt.pl

Используем:
tail -f /home/responder/logs/errors | grep "\[bt\]" | awk '{ print "echo \"",$1,$2,$3,"\" `addr2line -C -s -e responder "$4" | perl gSTLFilt.pl ` \"",$5,$6,$7,"\""}' | sh | tee -a backtrace.log


А теперь, внимание, вопрос: кто мне сможет объяснить, почему когда perl gSTLFilt.pl подается на вход строчка
"CDbImpl::SelectMap(char const* (*) [2], ...", выдается "CDbImpl::SelectMap(char const errors.log backtrace.log gSTLFilt.pl ..."

То есть, какое-то нездоровое поведение перла, видимо - первый "*" разворачивает в имена всех файлов в текущем каталоге. Как этого избежать?

Update: все неправы, ха-ха-ха. Точнее, более всего прав Бреслав - двойные кавычки нужно убрать. Только нужно не заменить их все на одинарные - это тут просто не прокатит, а перед `addr2line, и, соответственно, после gSTLFilt.pl ` - убрать \".
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

airmax: (Default)
airmax

April 2011

S M T W T F S
      12
345 6 7 89
10 11 12 131415 16
17181920212223
24252627282930

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 26th, 2025 03:29 pm
Powered by Dreamwidth Studios