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

Eugene Birukov eugenebi at hotmail.com
Tue May 19 09:22:11 PDT 2015


Pavel,
 
Thanks for reply. You are right, it is reported as exception, here is the portion of MonitorSignal routine on Linux:
 
    case SIGSEGV:
    case SIGILL:
    case SIGFPE:
    case SIGBUS:
        if (thread_sp)
            std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetCrashedWithException (*info);
        break;
    default:
        // This is just a pre-signal-delivery notification of the incoming signal.
        if (thread_sp)
            std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetStoppedBySignal (signo);
 
 
I have no knowledge about LLGS (yet :)) but I'd vote for the second way: current LLDB behavior makes total sense for a "normal" application which is not in the business of managing its address space. The same applies to illegal instruction - the program could be self-modifying (say, JIT compiling).  Exceptions are signals on Unix from the day one and we'd better not meddle with this long-established abstraction.
 
I think we also need to give the choice to the developer during interactive debugging: i.e. "continue" command better have a flag that tells if to pass signal to the application or not.
 
Thanks,
Eugene
 
> From: labath at google.com
> Date: Tue, 19 May 2015 11:35:32 +0100
> Subject: Re: [lldb-dev] LLDB blocks progress of program that handles SIGSEGV
> To: eugenebi at hotmail.com
> CC: lldb-dev at cs.uiuc.edu
> 
> 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
> >
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20150519/668f4b46/attachment.html>


More information about the lldb-dev mailing list