2006/10/06

Stack trace linuxilla (osa 2)

Ensimmäisessä osassa käsiteltiin pinolistauksen tulostamista backtrace- ja backtrace_symbols-funktioiden avulla. Tarkempaa tietoa, kuten tiedostonnimi ja rivinumero, saa ohjelmalla addr2line(1).
addr2line translates addresses into file names and line numbers. Given an address in an executable or an offset in a section of a relocatable object, it uses the debugging information to figure out which file name and line number are associated with it.
Addr2line:n syntaksi on seuraava: -f-vipu tulostaa funktion, -C-dekoodaa sen (demangle) ja -e:llä määritellään binääri. Ohjelma haluaa vielä osoitteen johonkin kohtaan ohjelmassa. Esimerkkikäyttö, joka lukee a.out tiedoston: "addr2line 0x8048796 -f -C".

Osoite, jonka addr2line haluaa on sama, joka löytyy backtrace_symbolsin palauttamasta taulukosta. Osoite on hakasulkujen välissä (./a.out(_Z5tracev+0x20) [0x8048956]).

Testihjelma:
#include <execinfo.h>
#include <iostream>

void trace()
{
const int ARRAY_SIZE = 5;
void *array[ARRAY_SIZE];

int size = backtrace (array, ARRAY_SIZE);
char **strings = backtrace_symbols(array, size);
if(strings == NULL)
return;

for( int i=0; i<size; ++i)
std::cout << strings[i] << std::endl;

free(strings);
}

void funktio()
{
trace();
}

int main()
{
funktio();
return 0;
}
Jos ohjelman kääntää normaalisti (g++ trace.cc) saadaan addr2linen tulostukseksi seuraavaa. Kuten huomaat niin funktio nimi näkyy ilman -rdynamic-vipua.
trace()
??:0
Jos rivinumerot ja tiedosto halutaan näkyviin, pitää ohjelmaan lisätä debug-tietoa -g-vivulla.
trace()
/home/bjqcqafprnj/stacktrace/trace.cc:10
Ohjelman sisällä addr2linen voi suorittaa esimerkiksi funktiolla popen(3).

Ei kommentteja: