Ticket #10301: 0001-debug_server-Add-default-action-support.patch

File 0001-debug_server-Add-default-action-support.patch, 7.1 KB (added by anevilyak, 11 years ago)
  • src/servers/debug/DebugServer.cpp

    From 7db4a655b56b2a99f9c5be7d4780a9a336c366e7 Mon Sep 17 00:00:00 2001
    From: Rene Gollent <rene@gollent.com>
    Date: Sun, 15 Dec 2013 10:57:23 -0500
    Subject: [PATCH] debug_server: Add default action support.
    
    - TeamDebugHandlerRoster now stores both a global default action to be taken
    when a team crashes, as well as one or more pattern matches to override said
    default for particular teams. These mappings are looked for in the settings
    file system/debug_server/settings. In the absence of the file, behavior
    defaults to prompting the user for an action as before. The file's format is
    driver_settings style, and follows the parameter names specified in ticket
    10301.
    ---
     src/servers/debug/DebugServer.cpp | 122 +++++++++++++++++++++++++++++++++++---
     src/servers/debug/Jamfile         |   1 +
     2 files changed, 116 insertions(+), 7 deletions(-)
    
    diff --git a/src/servers/debug/DebugServer.cpp b/src/servers/debug/DebugServer.cpp
    index 9a8ec74..68fa185 100644
    a b  
    11/*
    2  * Copyright 2011-2012, Rene Gollent, rene@gollent.com.
     2 * Copyright 2011-2013, Rene Gollent, rene@gollent.com.
    33 * Copyright 2005-2009, Ingo Weinhold, bonefish@users.sf.net.
    44 * Distributed under the terms of the MIT License.
    55 */
     
    1919#include <Autolock.h>
    2020#include <Catalog.h>
    2121#include <debug_support.h>
     22#include <driver_settings.h>
    2223#include <Entry.h>
    2324#include <FindDirectory.h>
    2425#include <Invoker.h>
     
    2627#include <Path.h>
    2728
    2829#include <MessengerPrivate.h>
     30#include <RegExp.h>
    2931#include <RegistrarDefs.h>
    3032#include <RosterPrivate.h>
    3133#include <Server.h>
     
    3739enum {
    3840    kActionKillTeam,
    3941    kActionDebugTeam,
    40     kActionSaveReportTeam
     42    kActionSaveReportTeam,
     43    kActionPromptUser
    4144};
    4245
    4346
    using std::nothrow;  
    6568static const char *kSignature = "application/x-vnd.Haiku-debug_server";
    6669
    6770
     71static int32 action_for_string(const char* action, int32 defaultAction)
     72{
     73    if (strcasecmp(action, "kill") == 0)
     74        return kActionKillTeam;
     75    else if (strcasecmp(action, "debug") == 0)
     76        return kActionDebugTeam;
     77    else if (strcasecmp(action, "log") == 0)
     78        return kActionSaveReportTeam;
     79    else if (strcasecmp(action, "user") == 0)
     80        return kActionPromptUser;
     81
     82    return defaultAction;
     83}
     84
     85
    6886static void
    6987KillTeam(team_id team, const char *appName = NULL)
    7088{
    class TeamDebugHandlerRoster : public BLocker {  
    167185private:
    168186    TeamDebugHandlerRoster()
    169187        :
    170         BLocker("team debug handler roster")
     188        BLocker("team debug handler roster"),
     189        fDefaultDebugAction(kActionPromptUser)
    171190    {
    172191    }
    173192
    public:  
    185204        return sRoster;
    186205    }
    187206
     207    status_t Init()
     208    {
     209        status_t error = B_OK;
     210        BPath path;
     211        error = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
     212        if (error != B_OK)
     213            return error;
     214
     215        path.Append("system/debug_server/settings");
     216        void* handle = load_driver_settings(path.Path());
     217        if (handle) {
     218            const driver_settings* settings = get_driver_settings(handle);
     219            for (int i = 0; i < settings->parameter_count; i++) {
     220                const driver_parameter& parameter = settings->parameters[i];
     221                if (strcasecmp(parameter.name, "default_action") == 0
     222                        && parameter.value_count > 0) {
     223                    fDefaultDebugAction = action_for_string(
     224                        parameter.values[0], fDefaultDebugAction);
     225                } else if (strcasecmp(parameter.name, "executable_actions")
     226                        == 0) {
     227                    for (int j = 0; j < parameter.parameter_count; j++) {
     228                        const driver_parameter &execParameter
     229                            = parameter.parameters[j];
     230                        if (execParameter.value_count > 0) {
     231                            fDefaultActions[execParameter.name]
     232                                = action_for_string(execParameter.values[0],
     233                                    fDefaultDebugAction);
     234                        }
     235                    }
     236                }
     237            }
     238
     239            unload_driver_settings(handle);
     240        }
     241
     242        return B_OK;
     243    }
     244
    188245    bool AddHandler(TeamDebugHandler *handler)
    189246    {
    190247        if (!handler)
    public:  
    225282        return handler;
    226283    }
    227284
     285    int32 DefaultActionForTeam(const BString& teamName, bool& _matchFound) const
     286    {
     287        _matchFound = false;
     288        RegExp expressionMatcher;
     289        for (DefaultActionMap::const_iterator it = fDefaultActions.begin();
     290                it != fDefaultActions.end(); ++it) {
     291            if (expressionMatcher.SetPattern(it->first,
     292                    RegExp::PATTERN_TYPE_WILDCARD)) {
     293                BString value = teamName;
     294                if (it->first[0] != '/') {
     295                    // the expression in question is a team name match only,
     296                    // so we need to extract that.
     297                    BPath path(teamName);
     298                    if (path.InitCheck() == B_OK)
     299                        value = path.Leaf();
     300                }
     301                RegExp::MatchResult match = expressionMatcher.Match(value);
     302                if (match.HasMatched()) {
     303                    _matchFound = true;
     304                    return it->second;
     305                }
     306            }
     307        }
     308
     309        return fDefaultDebugAction;
     310    }
     311
    228312    status_t DispatchMessage(DebugMessage *message)
    229313    {
    230314        if (!message)
    public:  
    269353
    270354private:
    271355    typedef map<team_id, TeamDebugHandler*> TeamDebugHandlerMap;
     356    typedef map<BString, int32> DefaultActionMap;
    272357
    273358    static TeamDebugHandlerRoster   *sRoster;
    274359
    275360    TeamDebugHandlerMap             fHandlers;
     361
     362    int32                           fDefaultDebugAction;
     363                                        // this indicates the default action
     364                                        // to take on crash in the absence of
     365                                        // a more specific match in the map.
     366    DefaultActionMap                fDefaultActions;
     367                                        // contains a set of string->action
     368                                        // mappings for team names. Can contain
     369                                        // wild cards.
     370
    276371};
    277372
    278373TeamDebugHandlerRoster *TeamDebugHandlerRoster::sRoster = NULL;
    TeamDebugHandler::_HandleMessage(DebugMessage *message)  
    693788
    694789    _PrintStackTrace(thread);
    695790
    696     int32 debugAction = kActionKillTeam;
     791    bool explicitActionFound = false;
     792    int32 debugAction = TeamDebugHandlerRoster::Default()
     793        ->DefaultActionForTeam(fExecutablePath, explicitActionFound);
    697794
    698795    // ask the user whether to debug or kill the team
    699796    if (_IsGUIServer()) {
    700797        // App server, input server, or registrar. We always debug those.
    701         debugAction = kActionDebugTeam;
    702     } else if (USE_GUI && _AreGUIServersAlive() && _InitGUI() == B_OK) {
     798        // if not specifically overridden.
     799        if (!explicitActionFound)
     800            debugAction = kActionDebugTeam;
     801    } else if (debugAction == kActionPromptUser && USE_GUI
     802        && _AreGUIServersAlive() && _InitGUI() == B_OK) {
    703803        // normal app -- tell the user
    704804        _NotifyAppServer(fTeam);
    705805        _NotifyRegistrar(fTeam, true, false);
    main()  
    11541254    close(console);
    11551255
    11561256    // create the team debug handler roster
    1157     if (!TeamDebugHandlerRoster::CreateDefault()) {
     1257    TeamDebugHandlerRoster* roster = TeamDebugHandlerRoster::CreateDefault();
     1258    if (!roster) {
    11581259        debug_printf("debug_server: Failed to create team debug handler "
    11591260            "roster.\n");
    11601261        exit(1);
    11611262    }
    11621263
     1264    // initialize roster settings
     1265    if (roster->Init() != B_OK) {
     1266        debug_printf("debug_server: Failed to initialize team debug handler "
     1267            "roster.\n");
     1268        exit(1);
     1269    }
     1270
    11631271    // create application
    11641272    DebugServer server(error);
    11651273    if (error != B_OK) {
  • src/servers/debug/Jamfile

    diff --git a/src/servers/debug/Jamfile b/src/servers/debug/Jamfile
    index e9a07d4..bb13d6a 100644
    a b Server debug_server  
    1313    :
    1414    be
    1515    libdebug.so
     16    libshared.a
    1617    $(TARGET_LIBSTDC++)
    1718    localestub
    1819;