2014-11-12 9 views
9

Chcę ustawić punkt przerwania dla parametru funkcji, jeśli jest on większy niż pewna wartość. Kod manekin poniżej:Parametr funkcji warunkowego przerwania GDB

int main(void) 
{ 
    uint64_t num = 123456; 
    uint64_t x = 847534; 

    uint64_t other = (num*x) - (x/num); 

    .... other stuff here (multithreaded stuff) 

    calc(other); 
} 

void calc(uint64_t size) 
{ 
    ...do some stuff with size 
} 

Próbowałem ustawić punkt przerwania przez:

(gdb) b calc if size == 852479 

ale nie wiem, jaki rozmiar jest ponieważ jest to parametr zgaduję. Jak bym się zepsuł, gdyby parametr był równy określonej liczbie. NIE jest to opcja włamania się do wszystkich wywołań tej funkcji, ponieważ nazywa się ją miliard razy w środowisku wielowątkowym.

+0

możliwy duplikat [W jaki sposób ustawić warunkowy punkt przerwania w gdb, gdy znak \ * x wskazuje na ciąg o wartości równej "hello"?] (Http://stackoverflow.com/questions/4183871/how-do -i-set-a-conditional-breakpoint-in-gdb-when-char-x-points-to-a-string-wh) –

+0

Czy próbowałeś ustawić punkt przerwania w pierwszym wierszu kodu funkcji? – Leeor

+1

@RickyMutschlechner Spojrzałem na to 1 i nie jest to duplikat, ponieważ w przypadku tego kodu x (rozpatrywana zmienna) zakłada się, że gdb będzie mógł się włamać, ponieważ jest to zmienna zadeklarowana poza funkcją. W moim przypadku ta zmienna jest parametrem funkcji. Z powodzeniem potrafię przełamać zmienne zadeklarowane poza funkcją, ale nie mogę przełamać parametrów poprzez przerwanie warunkowe. –

Odpowiedz

3

z wiersza gdb:

break "file.c":100 if (size=852479) 

lub

break "file.c":100 if (size>852479) 

tu jestem zakładając chcesz przerwania warunkowego na linii 100 i pliku src jest file.c

czyli jeśli chcesz przerwać na linii, która nazywa calc, to byłaby linia 100 - odpowiednio zmodyfikować (trzeba by również zastąpić size z other w tym przypadku)

jeśli użyłeś linii nr. to był jeden z 1. sprawozdania w funkcji calc wtedy będzie trzymać size

+0

Problem, który mam, to gdb nie jest świadom "rozmiaru" przed uruchomieniem programu prawdopodobnie dlatego, że jest to nazwa parametru, a nie zmienna zadeklarowana poza funkcją. Jedną rzeczą, którą próbuję teraz, jest ustawienie punktu przerwania funkcji, uruchomienie programu, teraz gdb jest świadomy zmiennej wielkości i teraz robię podział warunków na tę zmienną. Poniższy przykład (gdb) Podział file.c: obliczono (gdb) przebiegają Załamanie 1, obliczono (rozmiar = 48) przy file.c: 67 \t w file.c (gdb) b = jeżeli rozmiar 852479 // To jest, gdzie rozmiar jest faktycznie rozpoznawany przez gdb (gdb) c –

+0

jest gdb świadomy czegokolwiek * przed * rozpoczęciem programu? "other" jest zmienną, która jest deklarowana i tworzona w instancji przed wywołaniem kalc - dlatego nie powinieneś mieć problemu z ustawieniem na niej warunkowego punktu przerwania (być może nadal nie rozumiem tutaj tego pytania?) – bph

4

Zakładając x86-64 calling conventions na GNU/platformie Linux można zbadać %rdi (64-bit) zarejestrować się bezpośrednio do sprawdzenia funkcja jest pierwszy parametr:

b calc if $rdi == 852479 

Pozwala to na włamanie się do funkcji calc, nawet jeśli nie masz załadowanych symboli debugowania (a więc brak listy kodów, np. list calc).

Należy zauważyć, że ta metoda zakończy się niepowodzeniem, jeśli funkcja jest oparta na numerze optimizing compiler.

2

Jeśli break foo if arg1 == 14 nie działa z jakiegoś powodu (napotkałem niektóre funkcje/pliki binarne, gdzie się znajduje, a gdzie nie), można spróbować zastąpić je commands.

pozwala ustawić niektóre polecenia gdb, które będą uruchamiane za każdym razem, gdy zostanie uderzony punkt przerwania. Aby osiągnąć pożądany efekt - warunkową przerwania - można wykonać następujące czynności:

(gdb) b foo 
Breakpoint 1 at 0x400633: file test.c, line 6. 
(gdb) commands 1 
Type commands for breakpoint(s) 1, one per line. 
End with a line saying just "end". 
>silent 
>if arg1 != 14 
>cont 
>end 
>end 

Wykonanie zatrzyma się przerwania tylko jeśli arg1 == 14.

Jedyną wadą jest to, że silent tłumi typowy komunikat "hit punktu krytycznego". Możesz usunąć silent, ale wtedy gdb wydrukuje wiadomość, nawet jeśli punkt przerwania zostanie pominięty przez skrypt commands, co jest niepożądane, jeśli punkt przerwania jest trafiony bardzo często.

Można jednak dodać niestandardowe powiadomienie w skrypcie command.