diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index 9374459b5e..395ecb6f9e 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -454,7 +454,7 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, int argc, // set team debugging flags fDebuggerInterface->SetTeamDebuggingFlags( B_TEAM_DEBUG_THREADS | B_TEAM_DEBUG_IMAGES - | B_TEAM_DEBUG_POST_SYSCALL); + | B_TEAM_DEBUG_POST_SYSCALL | B_TEAM_DEBUG_SIGNALS); // get the initial state of the team AutoLocker< ::Team> teamLocker(fTeam); @@ -1617,8 +1617,18 @@ TeamDebugger::_HandleDebuggerMessage(DebugEvent* event) } break; } - case B_DEBUGGER_MESSAGE_PRE_SYSCALL: case B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED: + { + TRACE_EVENTS("B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED: thread: %" + B_PRId32 "\n", event->Thread()); + + if (handler != NULL) { + handled = handler->HandleSignalReceived( + dynamic_cast(event)); + } + break; + } + case B_DEBUGGER_MESSAGE_PRE_SYSCALL: case B_DEBUGGER_MESSAGE_PROFILER_UPDATE: case B_DEBUGGER_MESSAGE_HANDED_OVER: // not interested diff --git a/src/apps/debugger/controllers/ThreadHandler.cpp b/src/apps/debugger/controllers/ThreadHandler.cpp index 8978d883a6..838b8ffd59 100644 --- a/src/apps/debugger/controllers/ThreadHandler.cpp +++ b/src/apps/debugger/controllers/ThreadHandler.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010-2014, Rene Gollent, rene@gollent.com. + * Copyright 2010-2015, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -26,6 +26,7 @@ #include "Jobs.h" #include "MessageCodes.h" #include "Register.h" +#include "SignalDispositionTypes.h" #include "SourceCode.h" #include "SourceLanguage.h" #include "SpecificImageDebugInfo.h" @@ -246,6 +247,59 @@ ThreadHandler::HandleExceptionOccurred(ExceptionOccurredEvent* event) } +bool +ThreadHandler::HandleSignalReceived(SignalReceivedEvent* event) +{ + ::Team* team = fThread->GetTeam(); + AutoLocker locker(team); + + const SignalInfo& info = event->GetSignalInfo(); + int32 signal = info.Signal(); + int32 disposition = team->SignalDispositionFor(signal); + + switch (disposition) { + case SIGNAL_DISPOSITION_IGNORE: + return false; + case SIGNAL_DISPOSITION_STOP_AT_SIGNAL_HANDLER: + { + const struct sigaction& handlerInfo = info.Handler(); + target_addr_t address = 0; + if ((handlerInfo.sa_flags & SA_SIGINFO) != 0) + address = (target_addr_t)handlerInfo.sa_sigaction; + else + address = (target_addr_t)handlerInfo.sa_handler; + + if (address == (target_addr_t)SIG_DFL + || address == (target_addr_t)SIG_IGN + || address == (target_addr_t)SIG_HOLD) { + address = 0; + } + + if (address != 0 && _InstallTemporaryBreakpoint(address) == B_OK + && fDebuggerInterface->ContinueThread(ThreadID()) == B_OK) { + fStepMode = STEP_UNTIL; + return true; + } + + // fall through if no handler or if we failed to + // set a breakpoint at the handler + } + case SIGNAL_DISPOSITION_STOP_AT_RECEIPT: + { + BString stopReason; + stopReason.SetToFormat("Received signal %" B_PRId32 " (%s)", + signal, strsignal(signal)); + return _HandleThreadStopped(NULL, THREAD_STOPPED_DEBUGGED, + stopReason); + } + default: + break; + } + + return false; +} + + void ThreadHandler::HandleThreadAction(uint32 action, target_addr_t address) { diff --git a/src/apps/debugger/controllers/ThreadHandler.h b/src/apps/debugger/controllers/ThreadHandler.h index eb34741d02..432eac1e9f 100644 --- a/src/apps/debugger/controllers/ThreadHandler.h +++ b/src/apps/debugger/controllers/ThreadHandler.h @@ -57,6 +57,8 @@ public: SingleStepEvent* event); bool HandleExceptionOccurred( ExceptionOccurredEvent* event); + bool HandleSignalReceived( + SignalReceivedEvent* event); void HandleThreadAction(uint32 action, target_addr_t address);