2.15 GDB断点后处理commands中finish/until/tb带来的问题
http://scz.617.cn/unix/200901071528.txt
Q:
我现在拦截recvmsg(),有几个目的:
- 获取UDP报文的源IP、源PORT
- 观察接收到的数据
由于recvmsg()被频繁调用,我需要设置条件断点,比如当源IP、源PORT、接收到的 数据满足一定条件时再命中断点。对于recvmsg()来说,这些信息都是函数返回之后 才能获取的,因此我设想了这样一种断点设置方式:
b recvmsg commands silent set $x=(struct msghdr )((unsigned int *)($esp+8)) finish if ($x->msg_name!=0&&$x->msg_namelen==16) set $y=(struct sockaddr_in *)$x->msg_name if ( ntohl( $y->sin_addr.s_addr )==<...>) else c end else c end end
但这个断点不能达到预期效果,commands中finish之后的脚本未被执行,可能是BUG, 也可能是GDB就是这样实现的。将finish换成until ((unsigned int *)$esp),情 况依旧。后来我试图将finish换成tb ((unsigned int *)$esp),并针对tb设置后 处理commands,但GDB不允许这样做:
Can't use the "commands" command among a breakpoint's commands.
用define也无法绕过上述限制。
A: coolq@nsfocus 2009-01-07 14:20
用如下办法变通满足原始需求:
define finish_recvmsg finish if ($x->msg_name!=0&&$x->msg_namelen==16) set $y=(struct sockaddr_in *)$x->msg_name if ( ntohl( $y->sin_addr.s_addr )==<...>) else c end else c end end
A: emacsen@SMTH 2009-01-07 12:33:14
emacsen建议用hook试试,用Google搜"gdb hook"找到类似资料:
define hook-echo // 定义echo命令的"前处理" echo [ end
define hookpost-echo // 定义echo命令的"后处理" echo ]\n end
据此测试了hookpost-finish,也能满足原始需求: