Jak ustawić warunkowy punkt przerwania w gdb, gdy char * x wskazuje na ciąg, którego wartość jest równa „hello”?

164

Czy mogę określić, że chcę, aby gdb przerywał w linii x, gdy char* xwskazuje ciąg, którego wartość jest równa "hello"? Jeśli tak, w jaki sposób?

341008
źródło
Uwaga: strncmpi strstrinne przydatne funkcje zapytań C.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

198

Możesz użyć strcmp:

break x:20 if strcmp(y, "hello") == 0

20to numer wiersza, xdowolna nazwa pliku i ydowolna zmienna.

Nathan Fellman
źródło
9
Uwaga: musisz już uruchomić program, aby GDB zobaczył stdlib. W przeciwnym razie:No symbol "strcmp" in current context.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
@CiroSantilli 六四 事件 法轮功 包 卓 轩: Jak skonfigurować gdb, aby zobaczyć stdlib?
naiwny 231
@ naive231 przez "zobacz" Mam na myśli zobacz funkcje, abyś mógł je złamać, a nie źródło: musisz to zrobić run, aby biblioteki dynamiczne zostały załadowane. Aby uzyskać źródło,
wygoogluj
1
Ta metoda może mieć skutki uboczne. $_streqmetoda z @tlwhitec jest lepsza.
rools
55
break x if ((int)strcmp(y, "hello")) == 0

W niektórych implementacjach gdb może nie znać zwracanego typu strcmp. Oznacza to, że musiałbyś rzucić, w przeciwnym razie zawsze zostanie ocenione jako prawda!

Tobias Domhan
źródło
46

Od GDB 7.5 możesz używać tych natywnych funkcji wygodnych :

$_memeq(buf1, buf2, length)
$_regex(str, regex)
$_streq(str1, str2)
$_strlen(str)

Wydaje się to znacznie mniej problematyczne niż konieczność wykonywania „obcego” strcmp()na stosie procesu za każdym razem, gdy trafiony jest punkt przerwania. Jest to szczególnie prawdziwe w przypadku debugowania procesów wielowątkowych.

Zauważ, że twój GDB musi być skompilowany z obsługą Pythona, co nie jest problemem w obecnych dystrybucjach Linuksa. Aby mieć pewność, możesz to sprawdzić, uruchamiając show configurationw GDB i wyszukując --with-python. Ten mały oneliner też się sprawdza:

$ gdb -n -quiet -batch -ex 'show configuration' | grep 'with-python'
             --with-python=/usr (relocatable)

W przypadku wersji demonstracyjnej użycie byłoby

break <where> if $_streq(x, "hello")

lub, jeśli punkt przerwania już istnieje i chcesz po prostu dodać do niego warunek

condition <breakpoint number> $_streq(x, "hello")

$_streqdopasowuje tylko cały ciąg, więc jeśli chcesz czegoś bardziej przebiegłego, powinieneś użyć $_regex, który obsługuje składnię wyrażeń regularnych Pythona .

tlwhitec
źródło