kernel/debug: Report killing signals
Adds a `signal` field to the `team_deleted` event. Since killing signals like `SIGKILL` and `SIGKILLTHR` do not generate a `signal_received` event, debuggers would only see a `team_deleted` message with the `status` field set to 0. This makes debuggers like GDB think that the debuggee has exited with a status code of 0. To correctly report these signals, when a killing signal is sent to a team, this signal is relayed to the main thread instead of defaulting to just a `SIGKILLTHR` for both cases. Change-Id: If69c9e2e4d87bfbd31f654f5cb6f696ac69ef777 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7756 Tested-by: Commit checker robot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
9e2c51c22f
commit
f3cb51a85a
@@ -561,6 +561,7 @@ typedef struct {
|
||||
debug_origin origin; // thread is < 0, team is the deleted team
|
||||
// (asynchronous message)
|
||||
status_t status; // the exit code of the team
|
||||
int signal; // the signal causing the exit, < 0 if none
|
||||
team_usage_info usage; // the usage info of the team
|
||||
} debug_team_deleted;
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ bool user_debug_handle_signal(int signal, struct sigaction *handler,
|
||||
void user_debug_stop_thread();
|
||||
void user_debug_team_created(team_id teamID);
|
||||
void user_debug_team_deleted(team_id teamID, port_id debuggerPort, status_t status,
|
||||
team_usage_info* usageInfo);
|
||||
int signal, team_usage_info* usageInfo);
|
||||
void user_debug_team_exec();
|
||||
void user_debug_update_new_thread_flags(Thread* thread);
|
||||
void user_debug_thread_created(thread_id threadID);
|
||||
|
||||
@@ -1000,7 +1000,7 @@ user_debug_team_created(team_id teamID)
|
||||
|
||||
|
||||
void
|
||||
user_debug_team_deleted(team_id teamID, port_id debuggerPort, status_t status,
|
||||
user_debug_team_deleted(team_id teamID, port_id debuggerPort, status_t status, int signal,
|
||||
team_usage_info* usageInfo)
|
||||
{
|
||||
if (debuggerPort >= 0) {
|
||||
@@ -1012,6 +1012,7 @@ user_debug_team_deleted(team_id teamID, port_id debuggerPort, status_t status,
|
||||
message.origin.team = teamID;
|
||||
message.origin.nub_port = -1;
|
||||
message.status = status;
|
||||
message.signal = signal;
|
||||
message.usage = *usageInfo;
|
||||
write_port_etc(debuggerPort, B_DEBUGGER_MESSAGE_TEAM_DELETED, &message,
|
||||
sizeof(message), B_RELATIVE_TIMEOUT, 0);
|
||||
|
||||
@@ -1654,7 +1654,7 @@ send_signal_to_team_locked(Team* team, uint32 signalNumber, Signal* signal,
|
||||
// (only the main thread shuts down the team).
|
||||
Thread* mainThread = team->main_thread;
|
||||
if (mainThread != NULL) {
|
||||
mainThread->AddPendingSignal(SIGKILLTHR);
|
||||
mainThread->AddPendingSignal(signalNumber);
|
||||
|
||||
// wake up main thread
|
||||
mainThread->going_to_suspend = false;
|
||||
|
||||
@@ -3345,7 +3345,17 @@ team_delete_team(Team* team, port_id debuggerPort)
|
||||
}
|
||||
|
||||
// get team exit information
|
||||
status_t exitStatus = team->exit.status;
|
||||
status_t exitStatus = -1;
|
||||
int signal = -1;
|
||||
|
||||
switch (team->exit.reason) {
|
||||
case CLD_EXITED:
|
||||
exitStatus = team->exit.status;
|
||||
break;
|
||||
case CLD_KILLED:
|
||||
signal = team->exit.signal;
|
||||
break;
|
||||
}
|
||||
|
||||
teamLocker.Unlock();
|
||||
|
||||
@@ -3371,7 +3381,7 @@ team_delete_team(Team* team, port_id debuggerPort)
|
||||
team->ReleaseReference();
|
||||
|
||||
// notify the debugger, that the team is gone
|
||||
user_debug_team_deleted(teamID, debuggerPort, exitStatus, &usageInfo);
|
||||
user_debug_team_deleted(teamID, debuggerPort, exitStatus, signal, &usageInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user