[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