[Lldb-commits] Patch proposal: Bug 16769 - LLDB on Mac OS X crashes while running TestLongjmp

Mattias Hogstrom mhogstrom at emailgroups.net
Tue Sep 23 13:34:14 PDT 2014

I am new to both llvm and lldb development,
someone has to be kind and make the patching for me :)

I was analyzing a bug case and found several issues with the test
itself, not with lldb.
My patch is for the test code that tests lldb.

1. The crash doesn't seem to be reproducible any longer.
2. The function clock() is called in a test and the author expected it
to always return 0
This is wrong.  "The clock() function determines the amount of processor
time used since the invocation of the calling process, measured in
CLOCKS_PER_SECs of a second.". On my Mac the clock function always
returns a positive value.

This is the location where I found the test

// snippet from the test code

void do_jump(void)
    // We can't let the compiler know this will always happen or it
    might make
    // optimizations that break our test.
    if (!clock())
        longjmp(j, 1); // non-local goto

On my Mac OS X 10.9.5 machine, the longjmp is never called.

(lldb) dis
a.out`do_jump at longjmp.c:16:
   0x100000ee0:  pushq  %rbp
   0x100000ee1:  movq   %rsp, %rbp
   0x100000ee4:  callq  0x100000f5c               ; symbol stub for:
-> 0x100000ee9:  cmpq   $0x0, %rax
   0x100000eef:  jne    0x100000f06               ; do_jump + 38 at
   0x100000ef5:  leaq   0x134(%rip), %rdi
   0x100000efc:  movl   $0x1, %esi
   0x100000f01:  callq  0x100000f62               ; symbol stub for:
   0x100000f06:  popq   %rbp
   0x100000f07:  retq   

a.out`do_jump + 40:
   0x100000f08:  nopl   (%rax,%rax)
(lldb) register read rax
     rax = 0x000000000000149b

rax contains the result from the clock function, so longjmp is skipped.

I tried the clock function in linux under a virtual machine. It gives
back 0, so the longjmp is called. After that I tried it in linux on an
old powerpc mac I have. Same result. It gives 0 back. I think the test
does not consider different clock resolutions. It seems that the Mac has
a high resolution clock, which makes the test skip the call to the
longjmp function, which it doesn't on other architectures. I would
consider replacing the call to clock with a test variable declared

I believe that it crashed before because when the branch is skipped the
test code that performs  "step over", "step out", "step into" didn't
make sense and lldb didn't handle that well and crashed.
It seems that lldb has better error handling now.
So now it doesn't crash anymore.

3. Fixing the test code
I removed the call to clock and substituted the call with a volatile
Then I added the __attribute((noinline)) in order to avoid inlining.
Step in, step out, doesn't make sense of course if the function is
Only a problem when compiling with optimisations of course.
I am unsure if the tests are run with optimisations or not. Nevertheless
it works with both now.

volatile int WillEnter = 1;

__attribute((noinline)) void do_jump(void)
    // We can't let the compiler know this will always happen or it
    might make
    // optimizations that break our test.
    if (WillEnter)
        longjmp(j, 1); // non-local goto

4. Rerunning the tests
The 3 tests passes now under Mac OS X.

5. I saw that the tests were commented out for FreeBSD too,
it might be worth rerunning the test to see if it also passes there.
It might have failed for the same reason.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: longjump_patch.diff
Type: application/octet-stream
Size: 1869 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20140923/11f04113/attachment.obj>

More information about the lldb-commits mailing list