debug_server: Add default action support.
- debug_server now supports user configuration of both the general default
action to be taken on crashes, and per-app overrides. These are stored
config/settings/system/debug_server/settings. In the absence of the file,
behavior defaults to prompting the user for an action as before.
The file takes on a driver_settings style format as follows:
---
default_action user
executable_actions {
app1 log
/path/app2* debug
}
---
Valid values for an action are:
- user = prompt user for action.
- kill = silently terminate the crashing team.
- debug = attach the debugger to the crashing team. in the debugger.
- log / report = save a crash report and terminate the team.
If no default_action is specified, "user" is assumed.
The executable_actions subsection contains individual overrides of the
default. These take the form above, where the individual lines can be
only a team name, or a path, with wildcards.
Implements first part of #10301.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2012, Rene Gollent, [email protected].
|
||||
* Copyright 2011-2013, Rene Gollent, [email protected].
|
||||
* Copyright 2005-2009, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
@@ -25,7 +25,9 @@
|
||||
#include <Locale.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <DriverSettings.h>
|
||||
#include <MessengerPrivate.h>
|
||||
#include <RegExp.h>
|
||||
#include <RegistrarDefs.h>
|
||||
#include <RosterPrivate.h>
|
||||
#include <Server.h>
|
||||
@@ -37,7 +39,8 @@
|
||||
enum {
|
||||
kActionKillTeam,
|
||||
kActionDebugTeam,
|
||||
kActionSaveReportTeam
|
||||
kActionSaveReportTeam,
|
||||
kActionPromptUser
|
||||
};
|
||||
|
||||
|
||||
@@ -65,6 +68,95 @@ using std::nothrow;
|
||||
static const char *kSignature = "application/x-vnd.Haiku-debug_server";
|
||||
|
||||
|
||||
static status_t
|
||||
action_for_string(const char* action, int32& _action)
|
||||
{
|
||||
if (strcmp(action, "kill") == 0)
|
||||
_action = kActionKillTeam;
|
||||
else if (strcmp(action, "debug") == 0)
|
||||
_action = kActionDebugTeam;
|
||||
else if (strcmp(action, "log") == 0
|
||||
|| strcmp(action, "report") == 0) {
|
||||
_action = kActionSaveReportTeam;
|
||||
}
|
||||
else if (strcasecmp(action, "user") == 0)
|
||||
_action = kActionPromptUser;
|
||||
else
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
match_team_name(const char* teamName, const char* parameterName)
|
||||
{
|
||||
RegExp expressionMatcher;
|
||||
if (expressionMatcher.SetPattern(parameterName,
|
||||
RegExp::PATTERN_TYPE_WILDCARD)) {
|
||||
BString value = teamName;
|
||||
if (parameterName[0] != '/') {
|
||||
// the expression in question is a team name match only,
|
||||
// so we need to extract that.
|
||||
BPath path(teamName);
|
||||
if (path.InitCheck() == B_OK)
|
||||
value = path.Leaf();
|
||||
}
|
||||
|
||||
RegExp::MatchResult match = expressionMatcher.Match(value);
|
||||
if (match.HasMatched())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
status_t action_for_team(const char* teamName, int32& _action,
|
||||
bool& _explicitActionFound)
|
||||
{
|
||||
status_t error = B_OK;
|
||||
BPath path;
|
||||
error = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
path.Append("system/debug_server/settings");
|
||||
BDriverSettings settings;
|
||||
error = settings.Load(path.Path());
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
int32 tempAction;
|
||||
if (action_for_string(settings.GetParameterValue("default_action",
|
||||
"user", "user"), tempAction) == B_OK) {
|
||||
_action = tempAction;
|
||||
} else
|
||||
_action = kActionPromptUser;
|
||||
_explicitActionFound = false;
|
||||
|
||||
BDriverParameter parameter = settings.GetParameter("executable_actions");
|
||||
for (BDriverParameterIterator iterator = parameter.ParameterIterator();
|
||||
iterator.HasNext();) {
|
||||
BDriverParameter child = iterator.Next();
|
||||
if (!match_team_name(teamName, child.Name()))
|
||||
continue;
|
||||
|
||||
if (child.CountValues() > 0) {
|
||||
if (action_for_string(child.ValueAt(0), tempAction) == B_OK) {
|
||||
_action = tempAction;
|
||||
_explicitActionFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
KillTeam(team_id team, const char *appName = NULL)
|
||||
{
|
||||
@@ -275,6 +367,7 @@ private:
|
||||
TeamDebugHandlerMap fHandlers;
|
||||
};
|
||||
|
||||
|
||||
TeamDebugHandlerRoster *TeamDebugHandlerRoster::sRoster = NULL;
|
||||
|
||||
|
||||
@@ -693,13 +786,22 @@ TeamDebugHandler::_HandleMessage(DebugMessage *message)
|
||||
|
||||
_PrintStackTrace(thread);
|
||||
|
||||
int32 debugAction = kActionKillTeam;
|
||||
int32 debugAction;
|
||||
bool explicitActionFound;
|
||||
if (action_for_team(fExecutablePath, debugAction, explicitActionFound)
|
||||
!= B_OK) {
|
||||
debugAction = kActionPromptUser;
|
||||
explicitActionFound = false;
|
||||
}
|
||||
|
||||
// ask the user whether to debug or kill the team
|
||||
if (_IsGUIServer()) {
|
||||
// App server, input server, or registrar. We always debug those.
|
||||
debugAction = kActionDebugTeam;
|
||||
} else if (USE_GUI && _AreGUIServersAlive() && _InitGUI() == B_OK) {
|
||||
// if not specifically overridden.
|
||||
if (!explicitActionFound)
|
||||
debugAction = kActionDebugTeam;
|
||||
} else if (debugAction == kActionPromptUser && USE_GUI
|
||||
&& _AreGUIServersAlive() && _InitGUI() == B_OK) {
|
||||
// normal app -- tell the user
|
||||
_NotifyAppServer(fTeam);
|
||||
_NotifyRegistrar(fTeam, true, false);
|
||||
|
||||
@@ -4,6 +4,7 @@ UsePrivateHeaders app ;
|
||||
UsePrivateHeaders debug ;
|
||||
UsePrivateHeaders kernel ;
|
||||
UsePrivateHeaders shared ;
|
||||
UsePrivateHeaders storage ;
|
||||
|
||||
AddResources debug_server : debug_server.rdef ;
|
||||
|
||||
@@ -13,6 +14,7 @@ Server debug_server
|
||||
:
|
||||
be
|
||||
libdebug.so
|
||||
libshared.a
|
||||
$(TARGET_LIBSTDC++)
|
||||
localestub
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user