Ladění problému ve stacku

Tomáš Janoušek pytt_l na nomi.cz
Pátek Září 17 11:33:24 CEST 2010


Zdravím,

On Fri, Sep 17, 2010 at 08:03:27AM +0200, Ladislav Vaiz wrote:
> 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.

Pořád to ještě může být přetečení zásobníku, protože ty registry se při volání
funkcí musí zazálohovat na zásobník (nicméně je celkem pravděpodobné, že když
už by to šáhlo na zásobník, udělalo by to trochu větší paseku, než jen změnilo
n). Více info např. v [1].

Pokud máte podezření, že je chyba někde tu, tak vždy po volání funkce přes
disassemble zjistěte, kam se %r13 zazálohoval, a dejte na to místo watchpoint.
Stejně tak můžete prostě projít tu hlavní fci pomocí next a po každým řádku
vypsat n („display n“ anebo „display $r13“), abyste aspoň tušil, při volání
čeho se to rozbije.

[1] http://www.cs.cmu.edu/~fp/courses/15213-s06/misc/asm64-handout.pdf

> 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?

V gdb se dá udělat „disassemble /m <název fce>“ (pozor, pořadí řádků bude
odpovídat kódu v C, nikoliv strojovému). Gcc má parametr „-S“, který způsobí,
že výstup jde do souboru něco.s a je tam jen asm kód (může být přehlednější,
protože tam jsou labely atd.). A pak existuje ještě „objdump -d -S“, který to
vypisuje úplně zmateně :-).

Watchpoint na registr se přidá pomocí „watch $r13“.

> Jaký druh programátorské chyby by mohl způsobit něco takového?

To si netroufám tipnout :-)

S pozdravem,
-- 
Tomáš Janoušek, a.k.a. Liskni_si, http://work.lisk.in/



Další informace o konferenci Linux