Author: axeld Date: 2010-04-14 20:03:48 +0200 (Wed, 14 Apr 2010) New Revision: 36265 Changeset: http://dev.haiku-os.org/changeset/36265/haiku Modified: haiku/trunk/headers/os/kernel/debugger.h haiku/trunk/src/servers/debug/DebugServer.cpp haiku/trunk/src/system/kernel/team.cpp Log: * 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. Modified: haiku/trunk/headers/os/kernel/debugger.h =================================================================== --- haiku/trunk/headers/os/kernel/debugger.h 2010-04-14 17:52:12 UTC (rev 36264) +++ haiku/trunk/headers/os/kernel/debugger.h 2010-04-14 18:03:48 UTC (rev 36265) @@ -5,6 +5,7 @@ #ifndef _DEBUGGER_H #define _DEBUGGER_H + #include <signal.h> #include <image.h> @@ -17,6 +18,7 @@ #include <arch/mipsel/arch_debugger.h> #include <arch/arm/arch_debugger.h> + #ifdef __INTEL__ typedef struct x86_debug_cpu_state debug_cpu_state; #elif __POWERPC__ @@ -64,6 +66,7 @@ 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, Modified: haiku/trunk/src/servers/debug/DebugServer.cpp =================================================================== --- haiku/trunk/src/servers/debug/DebugServer.cpp 2010-04-14 17:52:12 UTC (rev 36264) +++ haiku/trunk/src/servers/debug/DebugServer.cpp 2010-04-14 18:03:48 UTC (rev 36265) @@ -3,6 +3,7 @@ * Distributed under the terms of the MIT License. */ + #include <map> #include <errno.h> @@ -25,6 +26,7 @@ #include <util/DoublyLinkedList.h> + #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 *kGDBPath = "/bin/gdb"; -// KillTeam static void KillTeam(team_id team, const char *appName = NULL) { @@ -71,7 +74,7 @@ // #pragma mark - -// DebugMessage + class DebugMessage : public DoublyLinkedListLinkImpl<DebugMessage> { public: DebugMessage() @@ -92,7 +95,6 @@ typedef DoublyLinkedList<DebugMessage> DebugMessageList; -// TeamDebugHandler class TeamDebugHandler : public BLocker { public: TeamDebugHandler(team_id team); @@ -144,11 +146,11 @@ }; -// TeamDebugHandlerRoster class TeamDebugHandlerRoster : public BLocker { private: TeamDebugHandlerRoster() - : BLocker("team debug handler roster") + : + BLocker("team debug handler roster") { } @@ -259,7 +261,6 @@ TeamDebugHandlerRoster *TeamDebugHandlerRoster::sRoster = NULL; -// DebugServer class DebugServer : public BServer { public: DebugServer(status_t &error); @@ -285,13 +286,14 @@ // #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 @@ fExecutablePath[0] = '\0'; } -// destructor + TeamDebugHandler::~TeamDebugHandler() { // delete the message count semaphore and wait for the thread to die @@ -322,7 +324,7 @@ } } -// Init + status_t TeamDebugHandler::Init(port_id nubPort) { @@ -352,6 +354,13 @@ 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 @@ return B_OK; } -// Team + team_id TeamDebugHandler::Team() const { return fTeam; } -// PushMessage + status_t TeamDebugHandler::PushMessage(DebugMessage *message) { @@ -396,7 +405,7 @@ return B_OK; } -// _PopMessage + status_t TeamDebugHandler::_PopMessage(DebugMessage *&message) { @@ -418,7 +427,7 @@ return B_OK; } -// _EnterDebugger + thread_id TeamDebugHandler::_EnterDebugger() { @@ -482,14 +491,14 @@ return thread; } -// _KillTeam + void TeamDebugHandler::_KillTeam() { KillTeam(fTeam, fTeamInfo.args); } -// _HandleMessage + bool TeamDebugHandler::_HandleMessage(DebugMessage *message) { @@ -577,7 +586,7 @@ return kill; } -// _LookupSymbolAddress + void TeamDebugHandler::_LookupSymbolAddress( debug_symbol_lookup_context *lookupContext, const void *address, @@ -631,7 +640,7 @@ } } -// _PrintStackTrace + void TeamDebugHandler::_PrintStackTrace(thread_id thread) { @@ -707,7 +716,6 @@ } -// _InitGUI status_t TeamDebugHandler::_InitGUI() { @@ -716,14 +724,14 @@ return app->InitGUIContext(); } -// _HandlerThreadEntry + status_t TeamDebugHandler::_HandlerThreadEntry(void *data) { return ((TeamDebugHandler*)data)->_HandlerThread(); } -// _HandlerThread + status_t TeamDebugHandler::_HandlerThread() { @@ -806,35 +814,35 @@ 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 @@ return _IsAppServer() || _IsInputServer() || _IsRegistrar(); } -// _LastPathComponent + const char * TeamDebugHandler::_LastPathComponent(const char *path) { @@ -850,7 +858,7 @@ return lastSlash ? lastSlash + 1 : path; } -// _FindTeam + team_id TeamDebugHandler::_FindTeam(const char *name) { @@ -868,7 +876,7 @@ return B_ENTRY_NOT_FOUND; } -// _AreGUIServersAlive + bool TeamDebugHandler::_AreGUIServersAlive() { @@ -879,16 +887,17 @@ // #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 @@ 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 @@ return false; } -// _ListenerEntry + status_t DebugServer::_ListenerEntry(void *data) { return ((DebugServer*)data)->_Listener(); } -// _Listener + status_t DebugServer::_Listener() { @@ -963,7 +973,7 @@ // #pragma mark - -// main + int main() { Modified: haiku/trunk/src/system/kernel/team.cpp =================================================================== --- haiku/trunk/src/system/kernel/team.cpp 2010-04-14 17:52:12 UTC (rev 36264) +++ haiku/trunk/src/system/kernel/team.cpp 2010-04-14 18:03:48 UTC (rev 36265) @@ -3496,7 +3496,8 @@ _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 @@ 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); }