Debugger: Start watching signal events.
TeamDebugger: - Add signal events to debug event mask. Upon receipt of such an event, stop the target thread. WIP.
This commit is contained in:
@@ -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<SignalReceivedEvent*>(event));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case B_DEBUGGER_MESSAGE_PRE_SYSCALL:
|
||||
case B_DEBUGGER_MESSAGE_PROFILER_UPDATE:
|
||||
case B_DEBUGGER_MESSAGE_HANDED_OVER:
|
||||
// not interested
|
||||
|
||||
@@ -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<Team> 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)
|
||||
{
|
||||
|
||||
@@ -57,6 +57,8 @@ public:
|
||||
SingleStepEvent* event);
|
||||
bool HandleExceptionOccurred(
|
||||
ExceptionOccurredEvent* event);
|
||||
bool HandleSignalReceived(
|
||||
SignalReceivedEvent* event);
|
||||
|
||||
void HandleThreadAction(uint32 action,
|
||||
target_addr_t address);
|
||||
|
||||
Reference in New Issue
Block a user