From a608485f26d1e806f7e4d595a8a6eeafad36bd43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 14 Apr 2010 18:03:48 +0000 Subject: [PATCH] * Added new team flag B_TEAM_DEBUG_PREVENT_EXIT that prevents teams from exiting via exit() (the calling thread will drop into the debugger instead). * The DebugServer now uses this flag by default. * Added TODO comment: the default debugger should already be able to set a flag like this in order to close a race condition between dropping a thread into the debugger and setting the flag. * Cleaned up the debug_server sources a bit. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36265 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/kernel/debugger.h | 3 + src/servers/debug/DebugServer.cpp | 94 +++++++++++++++++-------------- src/system/kernel/team.cpp | 10 +++- 3 files changed, 64 insertions(+), 43 deletions(-) diff --git a/headers/os/kernel/debugger.h b/headers/os/kernel/debugger.h index fc7faec4ae..12add40d00 100644 --- a/headers/os/kernel/debugger.h +++ b/headers/os/kernel/debugger.h @@ -5,6 +5,7 @@ #ifndef _DEBUGGER_H #define _DEBUGGER_H + #include #include @@ -17,6 +18,7 @@ #include #include + #ifdef __INTEL__ typedef struct x86_debug_cpu_state debug_cpu_state; #elif __POWERPC__ @@ -64,6 +66,7 @@ enum { B_TEAM_DEBUG_TEAM_CREATION = 0x00080000, B_TEAM_DEBUG_THREADS = 0x00100000, B_TEAM_DEBUG_IMAGES = 0x00200000, + B_TEAM_DEBUG_PREVENT_EXIT = 0x00400000, // new thread handling B_TEAM_DEBUG_STOP_NEW_THREADS = 0x01000000, diff --git a/src/servers/debug/DebugServer.cpp b/src/servers/debug/DebugServer.cpp index 04a2bbe685..ffdb480491 100644 --- a/src/servers/debug/DebugServer.cpp +++ b/src/servers/debug/DebugServer.cpp @@ -3,6 +3,7 @@ * Distributed under the terms of the MIT License. */ + #include #include @@ -25,6 +26,7 @@ #include + #define USE_GUI true // define to false if the debug server shouldn't use GUI (i.e. an alert) @@ -35,9 +37,11 @@ # define TRACE(x) ; #endif + using std::map; using std::nothrow; + static const char *kSignature = "application/x-vnd.Haiku-debug_server"; // paths to the apps used for debugging @@ -46,7 +50,6 @@ static const char *kTerminalPath = "/boot/system/apps/Terminal"; static const char *kGDBPath = "/bin/gdb"; -// KillTeam static void KillTeam(team_id team, const char *appName = NULL) { @@ -71,7 +74,7 @@ KillTeam(team_id team, const char *appName = NULL) // #pragma mark - -// DebugMessage + class DebugMessage : public DoublyLinkedListLinkImpl { public: DebugMessage() @@ -92,7 +95,6 @@ private: typedef DoublyLinkedList DebugMessageList; -// TeamDebugHandler class TeamDebugHandler : public BLocker { public: TeamDebugHandler(team_id team); @@ -144,11 +146,11 @@ private: }; -// TeamDebugHandlerRoster class TeamDebugHandlerRoster : public BLocker { private: TeamDebugHandlerRoster() - : BLocker("team debug handler roster") + : + BLocker("team debug handler roster") { } @@ -259,7 +261,6 @@ private: TeamDebugHandlerRoster *TeamDebugHandlerRoster::sRoster = NULL; -// DebugServer class DebugServer : public BServer { public: DebugServer(status_t &error); @@ -285,13 +286,14 @@ private: // #pragma mark - -// constructor + TeamDebugHandler::TeamDebugHandler(team_id team) - : BLocker("team debug handler"), - fMessages(), - fMessageCountSem(-1), - fTeam(team), - fHandlerThread(-1) + : + BLocker("team debug handler"), + fMessages(), + fMessageCountSem(-1), + fTeam(team), + fHandlerThread(-1) { fDebugContext.nub_port = -1; fDebugContext.reply_port = -1; @@ -299,7 +301,7 @@ TeamDebugHandler::TeamDebugHandler(team_id team) fExecutablePath[0] = '\0'; } -// destructor + TeamDebugHandler::~TeamDebugHandler() { // delete the message count semaphore and wait for the thread to die @@ -322,7 +324,7 @@ TeamDebugHandler::~TeamDebugHandler() } } -// Init + status_t TeamDebugHandler::Init(port_id nubPort) { @@ -352,6 +354,13 @@ TeamDebugHandler::Init(port_id nubPort) return error; } + // set team flags + debug_nub_set_team_flags message; + message.flags = B_TEAM_DEBUG_PREVENT_EXIT; + + send_debug_message(&fDebugContext, B_DEBUG_MESSAGE_SET_TEAM_FLAGS, &message, + sizeof(message), NULL, 0); + // create the message count semaphore char name[B_OS_NAME_LENGTH]; snprintf(name, sizeof(name), "team %ld message count", fTeam); @@ -377,14 +386,14 @@ TeamDebugHandler::Init(port_id nubPort) return B_OK; } -// Team + team_id TeamDebugHandler::Team() const { return fTeam; } -// PushMessage + status_t TeamDebugHandler::PushMessage(DebugMessage *message) { @@ -396,7 +405,7 @@ TeamDebugHandler::PushMessage(DebugMessage *message) return B_OK; } -// _PopMessage + status_t TeamDebugHandler::_PopMessage(DebugMessage *&message) { @@ -418,7 +427,7 @@ TeamDebugHandler::_PopMessage(DebugMessage *&message) return B_OK; } -// _EnterDebugger + thread_id TeamDebugHandler::_EnterDebugger() { @@ -482,14 +491,14 @@ TeamDebugHandler::_EnterDebugger() return thread; } -// _KillTeam + void TeamDebugHandler::_KillTeam() { KillTeam(fTeam, fTeamInfo.args); } -// _HandleMessage + bool TeamDebugHandler::_HandleMessage(DebugMessage *message) { @@ -577,7 +586,7 @@ TeamDebugHandler::_HandleMessage(DebugMessage *message) return kill; } -// _LookupSymbolAddress + void TeamDebugHandler::_LookupSymbolAddress( debug_symbol_lookup_context *lookupContext, const void *address, @@ -631,7 +640,7 @@ TeamDebugHandler::_LookupSymbolAddress( } } -// _PrintStackTrace + void TeamDebugHandler::_PrintStackTrace(thread_id thread) { @@ -707,7 +716,6 @@ TeamDebugHandler::_NotifyRegistrar(team_id team, bool openAlert, } -// _InitGUI status_t TeamDebugHandler::_InitGUI() { @@ -716,14 +724,14 @@ TeamDebugHandler::_InitGUI() return app->InitGUIContext(); } -// _HandlerThreadEntry + status_t TeamDebugHandler::_HandlerThreadEntry(void *data) { return ((TeamDebugHandler*)data)->_HandlerThread(); } -// _HandlerThread + status_t TeamDebugHandler::_HandlerThread() { @@ -806,35 +814,35 @@ TeamDebugHandler::_HandlerThread() return B_OK; } -// _ExecutableNameEquals + bool TeamDebugHandler::_ExecutableNameEquals(const char *name) const { return strcmp(_LastPathComponent(fExecutablePath), name) == 0; } -// _IsAppServer + bool TeamDebugHandler::_IsAppServer() const { return _ExecutableNameEquals("app_server"); } -// _IsInputServer + bool TeamDebugHandler::_IsInputServer() const { return _ExecutableNameEquals("input_server"); } -// _IsRegistrar + bool TeamDebugHandler::_IsRegistrar() const { return _ExecutableNameEquals("registrar"); } -// _IsGUIServer + bool TeamDebugHandler::_IsGUIServer() const { @@ -842,7 +850,7 @@ TeamDebugHandler::_IsGUIServer() const return _IsAppServer() || _IsInputServer() || _IsRegistrar(); } -// _LastPathComponent + const char * TeamDebugHandler::_LastPathComponent(const char *path) { @@ -850,7 +858,7 @@ TeamDebugHandler::_LastPathComponent(const char *path) return lastSlash ? lastSlash + 1 : path; } -// _FindTeam + team_id TeamDebugHandler::_FindTeam(const char *name) { @@ -868,7 +876,7 @@ TeamDebugHandler::_FindTeam(const char *name) return B_ENTRY_NOT_FOUND; } -// _AreGUIServersAlive + bool TeamDebugHandler::_AreGUIServersAlive() { @@ -879,16 +887,17 @@ TeamDebugHandler::_AreGUIServersAlive() // #pragma mark - -// constructor + DebugServer::DebugServer(status_t &error) - : BServer(kSignature, false, &error), - fListenerPort(-1), - fListener(-1), - fTerminating(false) + : + BServer(kSignature, false, &error), + fListenerPort(-1), + fListener(-1), + fTerminating(false) { } -// Init + status_t DebugServer::Init() { @@ -904,6 +913,7 @@ DebugServer::Init() return fListener; // register as default debugger + // TODO: could set default flags status_t error = install_default_debugger(fListenerPort); if (error != B_OK) return error; @@ -922,14 +932,14 @@ DebugServer::QuitRequested() return false; } -// _ListenerEntry + status_t DebugServer::_ListenerEntry(void *data) { return ((DebugServer*)data)->_Listener(); } -// _Listener + status_t DebugServer::_Listener() { @@ -963,7 +973,7 @@ message->Data().origin.team, code)); // #pragma mark - -// main + int main() { diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 0e7b271f1e..6d330c09b4 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -3496,7 +3496,8 @@ void _user_exit_team(status_t returnValue) { struct thread* thread = thread_get_current_thread(); - struct thread* mainThread = thread->team->main_thread; + struct team* team = thread->team; + struct thread* mainThread = team->main_thread; mainThread->exit.status = returnValue; mainThread->exit.reason = THREAD_RETURN_EXIT; @@ -3507,6 +3508,13 @@ _user_exit_team(status_t returnValue) thread->exit.reason = THREAD_RETURN_EXIT; } + if ((atomic_get(&team->debug_info.flags) & B_TEAM_DEBUG_PREVENT_EXIT) + != 0) { + // This team is currently being debugged, and requested that teams + // should not be exited. + user_debug_stop_thread(); + } + send_signal(thread->id, SIGKILL); }