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:
#includeint 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
where is my chocolate ? :)
>4::sysbp -c '<o0=K | ::grep ".!=7" | ::eval ::cont'
>::run
Posted by Vita Batrla on June 24, 2005 at 08:33 AM PDT #
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...
Posted by Eric Schrock on June 24, 2005 at 09:21 AM PDT #
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.
Posted by Alan Hargreaves on June 24, 2005 at 05:10 PM PDT #
Posted by sitchai on June 26, 2005 at 09:16 PM PDT #
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>.
Posted by Eric Schrock on June 26, 2005 at 09:22 PM PDT #
Posted by sitchai on June 27, 2005 at 12:20 AM PDT #