Since Bryan solved my last puzzle a little too quickly, this post will serve as a followup puzzle that may or may not be easier. All I know is that Bryan is ineligible this time around 😉
Once again, the rules are simple. The solution must be a single line dcmd that produces precise output without any additional steps or post processing. For this puzzle, you’re actually allowed two commands: one for your dcmd, and another for ‘::run’. For this puzzle, we’ll be using the following test program:
#include int main(int argc, char **argv) { int i; srand(time(NULL)); for (i = 0; i < 100; i++) write(rand() % 10, NULL, 0); return (0); }
The puzzle itself demonstrates how conditional breakpoints can be implemented on top of existing functionality:
Stop the test program on entry to the write() system call only when the file descriptor number is 7
I thought this one would be harder than the last, but now I’m not so sure, especially once you absorb some of the finer points from the last post.
Technorati Tag: MDB
6 Responses
Hi all,
where is my chocolate ? 🙂
>4::sysbp -c ‘<o0=K | ::grep “.!=7” | ::eval ::cont’
>::run
Vita –
Congrats. I would have also accepted x86 answers with <tt><esp+4/K</tt> or <tt><rsi=K</tt>. I’ll be adding these useful tricks to the MDB community page shortly. You have my utmost respect as an MDB hacker…
It’s a shame you limited it to mdb 😉
dtrace -w -c ./testprog -n ‘pid$target::write:entry /arg0 == 7/ {stop();}’
This will actually stop it before we do the trap to the system call 😉
You could then gcore it and look what’s happenning, or even attach an mdb with the -p argument.
alan.
Eric,
How do you know that you should use esp+4?
Is it about the number of arguments to write()?
sitchai –
We use <tt>esp+4</tt> due to the way arguments are passed on 32-bit x86. Arguments are pushed onto the stack, so the first argument to the function is the first item on the stack. Except that when we issued the <tt>call</tt> instruction to get here, we pushed the return PC as well. You can find more information about argument passing on x86 (and why I hate amd64 from a debugging perspective) from an old blog entry.
Note that once you’re in the body of the function, we will have executed the standard <tt>pushl %ebp</tt>, <tt>movl %esp, %ebp</tt>, at which point the standard way to access the first argument is <tt>%ebp+8</tt>.
Thanks Eric.
I read you old post and seems like it will be more difficult on amd64.