debug server: Offer option to write a core file
... when a team crashes/hits a debug event.
This commit is contained in:
@@ -39,6 +39,7 @@
|
|||||||
enum {
|
enum {
|
||||||
kActionKillTeam,
|
kActionKillTeam,
|
||||||
kActionDebugTeam,
|
kActionDebugTeam,
|
||||||
|
kActionWriteCoreFile,
|
||||||
kActionSaveReportTeam,
|
kActionSaveReportTeam,
|
||||||
kActionPromptUser
|
kActionPromptUser
|
||||||
};
|
};
|
||||||
@@ -82,7 +83,8 @@ action_for_string(const char* action, int32& _action)
|
|||||||
else if (strcmp(action, "log") == 0
|
else if (strcmp(action, "log") == 0
|
||||||
|| strcmp(action, "report") == 0) {
|
|| strcmp(action, "report") == 0) {
|
||||||
_action = kActionSaveReportTeam;
|
_action = kActionSaveReportTeam;
|
||||||
}
|
} else if (strcasecmp(action, "core") == 0)
|
||||||
|
_action = kActionWriteCoreFile;
|
||||||
else if (strcasecmp(action, "user") == 0)
|
else if (strcasecmp(action, "user") == 0)
|
||||||
_action = kActionPromptUser;
|
_action = kActionPromptUser;
|
||||||
else
|
else
|
||||||
@@ -116,8 +118,8 @@ match_team_name(const char* teamName, const char* parameterName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static status_t
|
||||||
status_t action_for_team(const char* teamName, int32& _action,
|
action_for_team(const char* teamName, int32& _action,
|
||||||
bool& _explicitActionFound)
|
bool& _explicitActionFound)
|
||||||
{
|
{
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
@@ -223,6 +225,7 @@ private:
|
|||||||
|
|
||||||
thread_id _EnterDebugger(bool saveReport);
|
thread_id _EnterDebugger(bool saveReport);
|
||||||
status_t _SetupGDBArguments(BStringList &arguments, bool usingConsoled);
|
status_t _SetupGDBArguments(BStringList &arguments, bool usingConsoled);
|
||||||
|
status_t _WriteCoreFile();
|
||||||
void _KillTeam();
|
void _KillTeam();
|
||||||
|
|
||||||
int32 _HandleMessage(DebugMessage *message);
|
int32 _HandleMessage(DebugMessage *message);
|
||||||
@@ -745,6 +748,72 @@ TeamDebugHandler::_KillTeam()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TeamDebugHandler::_WriteCoreFile()
|
||||||
|
{
|
||||||
|
// get a usable path for the core file
|
||||||
|
BPath directoryPath;
|
||||||
|
status_t error = find_directory(B_DESKTOP_DIRECTORY, &directoryPath);
|
||||||
|
if (error != B_OK) {
|
||||||
|
debug_printf("debug_server: Couldn't get desktop directory: %s\n",
|
||||||
|
strerror(error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* executableName = strrchr(fExecutablePath, '/');
|
||||||
|
if (executableName == NULL)
|
||||||
|
executableName = fExecutablePath;
|
||||||
|
else
|
||||||
|
executableName++;
|
||||||
|
|
||||||
|
BString fileBaseName("core-");
|
||||||
|
fileBaseName << executableName << '-' << fTeam;
|
||||||
|
BPath filePath;
|
||||||
|
|
||||||
|
for (int32 index = 0;; index++) {
|
||||||
|
BString fileName(fileBaseName);
|
||||||
|
if (index > 0)
|
||||||
|
fileName << '-' << index;
|
||||||
|
|
||||||
|
error = filePath.SetTo(directoryPath.Path(), fileName.String());
|
||||||
|
if (error != B_OK) {
|
||||||
|
debug_printf("debug_server: Couldn't get core file path for team %"
|
||||||
|
B_PRId32 ": %s\n", fTeam, strerror(error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (lstat(filePath.Path(), &st) != 0) {
|
||||||
|
if (errno == B_ENTRY_NOT_FOUND)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > 1000) {
|
||||||
|
debug_printf("debug_server: Couldn't get usable core file path for "
|
||||||
|
"team %" B_PRId32 "\n", fTeam);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_nub_write_core_file message;
|
||||||
|
message.reply_port = fDebugContext.reply_port;
|
||||||
|
strlcpy(message.path, filePath.Path(), sizeof(message.path));
|
||||||
|
|
||||||
|
debug_nub_write_core_file_reply reply;
|
||||||
|
|
||||||
|
error = send_debug_message(&fDebugContext, B_DEBUG_WRITE_CORE_FILE,
|
||||||
|
&message, sizeof(message), &reply, sizeof(reply));
|
||||||
|
if (error == B_OK)
|
||||||
|
error = reply.error;
|
||||||
|
if (error != B_OK) {
|
||||||
|
debug_printf("debug_server: Failed to write core file for team %"
|
||||||
|
B_PRId32 ": %s\n", fTeam, strerror(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
TeamDebugHandler::_HandleMessage(DebugMessage *message)
|
TeamDebugHandler::_HandleMessage(DebugMessage *message)
|
||||||
{
|
{
|
||||||
@@ -832,14 +901,12 @@ TeamDebugHandler::_HandleMessage(DebugMessage *message)
|
|||||||
|
|
||||||
// TODO: It would be nice if the alert would go away automatically
|
// TODO: It would be nice if the alert would go away automatically
|
||||||
// if someone else kills our teams.
|
// if someone else kills our teams.
|
||||||
#ifdef HANDOVER_USE_DEBUGGER
|
|
||||||
BAlert *alert = new BAlert(NULL, buffer.String(),
|
BAlert *alert = new BAlert(NULL, buffer.String(),
|
||||||
B_TRANSLATE("Terminate"), B_TRANSLATE("Debug"),
|
B_TRANSLATE("Terminate"), B_TRANSLATE("Debug"),
|
||||||
B_TRANSLATE("Save report"), B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
B_TRANSLATE("Write core file"),
|
||||||
#else
|
|
||||||
BAlert *alert = new BAlert(NULL, buffer.String(),
|
|
||||||
B_TRANSLATE("Kill"), B_TRANSLATE("Debug"), NULL,
|
|
||||||
B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
||||||
|
#ifdef HANDOVER_USE_DEBUGGER
|
||||||
|
alert->AddButton(B_TRANSLATE("Save report"));
|
||||||
#endif
|
#endif
|
||||||
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
|
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
|
||||||
debugAction = alert->Go();
|
debugAction = alert->Go();
|
||||||
@@ -1027,6 +1094,9 @@ TeamDebugHandler::_HandlerThread()
|
|||||||
// The team shall be killed. Since that is also the handling in case
|
// The team shall be killed. Since that is also the handling in case
|
||||||
// an error occurs while handing over the team to the debugger, we do
|
// an error occurs while handing over the team to the debugger, we do
|
||||||
// nothing here.
|
// nothing here.
|
||||||
|
} else if (debugAction == kActionWriteCoreFile) {
|
||||||
|
_WriteCoreFile();
|
||||||
|
debugAction = kActionKillTeam;
|
||||||
} else if ((debuggerThread = _EnterDebugger(
|
} else if ((debuggerThread = _EnterDebugger(
|
||||||
debugAction == kActionSaveReportTeam)) >= 0) {
|
debugAction == kActionSaveReportTeam)) >= 0) {
|
||||||
// wait for the "handed over" or a "team deleted" message
|
// wait for the "handed over" or a "team deleted" message
|
||||||
|
|||||||
Reference in New Issue
Block a user