Ladění problému ve stacku
Ladislav Vaiz
spam na nagano.cz
Pátek Září 17 08:03:27 CEST 2010
> Toto leccos naznačuje. Buď gcc generuje špatný kód (nepravděpodobné), anebo
> někde děláte něco, co nemá jasně definované chování, a při optimalizaci se to
> rozbije.
>
> Každopádně odsud těžko soudit co, takže zkusme ještě to gdb. Dejte si break
> někam na ten řádek s tím scandirem (při -O2 se stane, že ta proměnná předtím
> prostě neexistuje) a dejte „print &n“.
Can't take address of "n" which isn't an lvalue.
> Dostanete adresu toho n a poté by mělo
> snad jít přidat watchpoint na tu adresu pomocí „watch * (int *) <adresa>“.
> Pokud to nepůjde, nejspíš to i řekne, proč (například, že n je v registru
> anebo že ještě neexistuje). V takovém případě zkuste prostě do kódu napsat
> „printf("0x%lx\n", &n);“.
A heleme se, hw breakpointy už fungují :-)
(gdb) p &n
$1 = (int *) 0x7fff05621cec
(gdb) watch n
Hardware watchpoint 2: n
(gdb)
Ale moc to nepomohlo:
(gdb) c
Continuing.
Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
menu_load_contest (dir=<value optimized out>, unused=<value optimized
out>) at menu.c:105
Tato funkce volá tu naši, kde je n automatickou proměnnou. Takže chyba v
tomto případě nenastane :-(
> Je samozřejmě možné, že se pak chyba přestane
> projevovat, a pak už asi bude nejlepší si prostě přečíst ten asm kód, co gcc
> vyrobí.
>
Hmm, assemblerem jsem se zabyval naposledy před >10lety pod DOSem,
linuxovou AT&T syntaxi jsem nějak nerozdýchal. Navíc zatím nebyl důvod
lámat to přes koleno.
Chápu to ale dobře, že chyba nastane pouze když n je v registru? Pak to
asi nebude přetečení pole v zásobníku, ale čuju problém v gcc. Byť se mi
to zdá divné, je to gcc z distribuce, kterým patrně byla celá distribuce
zkompilována.
Zkoušel jsem přidat volatile a chyba nenastává. Koukal jsem do
assemblereu, bez volatile (když padá), se návratový kód uloží do %r13, s
volatile do 0x14c(%rsp). Pokud to dobře chápu, tak v prvním případě do
registru, ve druhém do stacku. Lze nějak disassamblovat celou funkci do
souboru, abych mohl hledat, co se děje s %r13 ? Nebo na něj nastavit
watchpoint?
Jaký druh programátorské chyby by mohl způsobit něco takového?
Láďa
Další informace o konferenci Linux