1. 可以使用 commands 命令來設定條件式中斷
break foo
commands
if x>0
continue
else
printf "x is %d\n",x
end
end
2. 問題在於如何比較字串,以下整理網路上找到的幾種作法。若gdb版本較舊,則可能需要找尋其他方法。
方法一:使用 strcmp
(gdb) set $x = malloc(strlen("foobar") + 1)
(gdb) call strcpy($x, "foobar")
(gdb) break a_leg if strcmp(foo, $x) == 0
方法二:透過 python
可以直接使用下列函數 (Convenient functions)
$_memeq(
buf1,
buf2,
length)
Returns one if the length bytes at the addresses given by buf1 and buf2 are equal. Otherwise it returns zero.
$_regex(
str,
regex)
Returns one if the string str matches the regular expression regex. Otherwise it returns zero. The syntax of the regular expression is that specified byPython
's regular expression support.
$_streq(
str1,
str2)
Returns one if the strings str1 and str2 are equal. Otherwise it returns zero.
也可以自行實作 strcmp
(gdb) define strcmp
>py print cmp(gdb.execute("output $arg0", to_string=True).strip('"'), $arg1)
>end
(gdb) strcmp $x "hello"
0
針對舊版本的 gdb,例如我所使用的 gdb 7.1,並不支援上述函數,因此需要自行實作一個 conevenient function,範例如下:
py
class MyStrcmp (gdb.Function):
"""My Own Strcmp"""
def __init__ (self):
super (MyStrcmp, self).__init__ ("mystrcmp")
def invoke (self, arg0, arg1):
print "input '" + arg0.string() + "' and '" + arg1.string() + "'"
if arg0.string() == arg1.string() :
print "equal"
return 0
else:
print "not equal"
return 1
MyStrcmp()
end
用法:
print $mystrcmp("hello", "hello")
方法三:使用 gdb script 實作 strcmp
set var $_isEq=0
# Yes! GDB_STRCMP, below, is a gdb function.
# Function that provides strcmp-like functionality for gdb script;
# this function will be used to match the password string provided in command line argument
# with the string argument of strcmp in program
define GDB_STRCMP
set var $_i=0
set var $_c1= *(unsigned char *) ($arg0 + $_i)
set var $_c2= *(unsigned char *) ($arg1 + $_i)
while ( ($_c1 != 0x0) && ($_c2 != 0x0) && ($_c1 == $_c2) )
#printf "\n i=%d, addr1=%x(%d,%c), addr2=%x(%d,%c)", $_i, ($arg0 + $_i),$_c1, $_c1, ($arg1 + $_i), $_c2,$_c2
set $_i++
set $_c1= *(unsigned char *) ($arg0 + $_i)
set $_c2= *(unsigned char *) ($arg1 + $_i)
#while end
end
if( $_c1 == $_c2)
set $_isEq=1
else
set $_isEq=0
end
#GDB_STRCMP end
end
Reference:
- https://sourceware.org/gdb/onlinedocs/gdb/Break-Commands.html
- http://stackoverflow.com/questions/13961368/conditional-breakpoint-using-strcmp-in-gdb-on-mac-os-x-conflicts-with-objectiv
- https://sourceware.org/gdb/current/onlinedocs/gdb/Convenience-Funs.html
- http://stackoverflow.com/questions/7423577/how-to-compare-a-stored-string-variable-in-gdb
- http://www.opensourceforu.com/2011/09/modify-function-return-value-hack-part-2/