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: lab...@google.com > Date: Tue, 19 May 2015 11:35:32 +0100 > Subject: Re: [lldb-dev] LLDB blocks progress of program that handles SIGSEGV > To: eugen...@hotmail.com > CC: lldb-dev@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 <eugen...@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@cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev > >
_______________________________________________ lldb-dev mailing list lldb-dev@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev