[lldb-dev] LLDB blocks progress of program that handles SIGSEGV

Pavel Labath labath at google.com
Tue May 19 03:35:32 PDT 2015


Hello Eugene,

thanks for the report. What you are describing sounds like a genuine
LLDB problem. I have created a bug
<https://llvm.org/bugs/show_bug.cgi?id=23571> so we don't forget about
this. It looks like LLGS (server component of lldb) is reporting this
segfault to LLDB as an "exception" rather than a signal
(reason:expection in the stop-reply packet). This causes LLDB to not
reinject the signal when continuing the inferior. Now there are two
places we can fix this:
- have LLGS report this event as a signal. Then LLDB should be able to
reinject the signal correctly.
- teach LLDB to reinject the signal even in when the stop was reported
as an exception.

I'm inclined to do the first thing but I am not sure. Could somebody
with more LLDB knowledge shed some light on this? What is the intended
usage/behavior in case LLGS reports reason:exception?

cheers,
pl



On 18 May 2015 at 18:27, Eugene Birukov <eugenebi at hotmail.com> wrote:
>  Hello,
>
> I am running Linux Ubuntu 14.04 and I tried both LLDB-3.6 (installed
> binaries using apt-get) and LLDB-3.7 (built from sources sync'ed to trunk),
> the result is the same.
>
> I have a simple program (the source code is at the bottom of the message)
> that maps a page of memory as not accessible, installs a SIGSEGV handler
> that remaps this page as read-write, and then tries to read from it. So, the
> expected result is that program initially receives SIGSEGV but happily
> continues after the handler fixes the problem.
>
> The program runs as expected, both standalone and under GDB:
>
>
> $ ./mm
> signal 11 received
> success 777
>
>
> $ gdb --quiet ./mm
> Reading symbols from ./mm...done.
> (gdb) r
> Starting program: /home/eugene/tmp/mm
> Program received signal SIGSEGV, Segmentation fault.
> 0x0000000000400acc in main () at mm.cpp:27
> 27          int x = *(int*)address;
> (gdb) c
> Continuing.
> signal 11 received
> success 777
> [Inferior 1 (process 14155) exited normally]
> (gdb) q
>
> But under LLDB it spins forever on failing instruction without invoking the
> signal handler. Also, setting "process handle" does not have any effect at
> all:
>
>
> $ ~/llvm/bin/lldb ./mm
> (lldb) target create "./mm"
> Current executable set to './mm' (x86_64).
> (lldb) br se -b main
> Breakpoint 1: where = mm`main + 30 at mm.cpp:24, address =
> 0x0000000000400a7e
> (lldb) pr lau
> Process 14194 launched: './mm' (x86_64)
> Process 14194 stopped
> * thread #1: tid = 14194, 0x0000000000400a7e mm`main + 30 at mm.cpp:24, name
> = 'mm', stop reason = breakpoint 1.1
>     frame #0: 0x0000000000400a7e mm`main + 30 at mm.cpp:24
>    21
>    22   int main()
>    23   {
> -> 24       sigset(SIGSEGV, handler);
>    25
>    26       address = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS |
> MAP_PRIVATE, -1, 0);
>    27       int x = *(int*)address;
> (lldb) pr ha SIGSEGV -s false -p true -n false
> NAME        PASS   STOP   NOTIFY
> ==========  =====  =====  ======
> SIGSEGV     true   false  false
> (lldb) c
> Process 14194 resuming
> Process 14194 stopped
> * thread #1: tid = 14194, 0x0000000000400acc mm`main + 108 at mm.cpp:27,
> name = 'mm', stop reason = address access protected (fault address:
> 0x7ffff7ff7000)
>     frame #0: 0x0000000000400acc mm`main + 108 at mm.cpp:27
>    24       sigset(SIGSEGV, handler);
>    25
>    26       address = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS |
> MAP_PRIVATE, -1, 0);
> -> 27       int x = *(int*)address;
>    28       std::cout << (signaled ? "success " : "failure ") << x << "\n";
>    29   }
> (lldb) c
> Process 14194 resuming
> Process 14194 stopped
> * thread #1: tid = 14194, 0x0000000000400acc mm`main + 108 at mm.cpp:27,
> name = 'mm', stop reason = address access protected (fault address:
> 0x7ffff7ff7000)
>     frame #0: 0x0000000000400acc mm`main + 108 at mm.cpp:27
>    24       sigset(SIGSEGV, handler);
>    25
>    26       address = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS |
> MAP_PRIVATE, -1, 0);
> -> 27       int x = *(int*)address;
>    28       std::cout << (signaled ? "success " : "failure ") << x << "\n";
>    29   }
> (lldb) c
> Process 14194 resuming
> Process 14194 stopped
> * thread #1: tid = 14194, 0x0000000000400acc mm`main + 108 at mm.cpp:27,
> name = 'mm', stop reason = address access protected (fault address:
> 0x7ffff7ff7000)
>     frame #0: 0x0000000000400acc mm`main + 108 at mm.cpp:27
>    24       sigset(SIGSEGV, handler);
>    25
>    26       address = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS |
> MAP_PRIVATE, -1, 0);
> -> 27       int x = *(int*)address;
>    28       std::cout << (signaled ? "success " : "failure ") << x << "\n";
>    29   }
> (lldb)
>
> So, do I miss some LLDB setting?
> Here is the program code:
>
>
> $ cat mm.cpp
> #include <iostream>
> #include <sys/mman.h>
> #include <signal.h>
> #include <assert.h>
> #include <sys/types.h>
> #include <unistd.h>
>
> void* address;
> size_t size = 0x1000;
> bool signaled = false;
>
> void handler(int sig)
> {
>     std::cout << "signal " << sig << " received\n";
>     signaled = true;
>     munmap(address, size);
>     void* newaddr = mmap(address, size, PROT_READ | PROT_WRITE,
> MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1, 0);
>     assert(newaddr == address);
>     *(int*)newaddr = 777;
> }
>
> int main()
> {
>     sigset(SIGSEGV, handler);
>     address = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1,
> 0);
>     int x = *(int*)address;
>     std::cout << (signaled ? "success " : "failure ") << x << "\n";
> }
> $
>
> Thanks,
> Eugene
>
>
>
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>



More information about the lldb-dev mailing list