Add some unconditional logging on the failure points when attaching
to a process so we'll always get messages in the console logs. Also make the "is frontboard process" / "is backboard process" determination lazy, specifically take it out of the MachProcess::AttachForDebug codepath when we are attaching to a process, to simplify attaching. <rdar://problem/47982516> <rdar://problem/48060134> llvm-svn: 354181
This commit is contained in:
parent
78b84cf991
commit
3bf883eac9
|
@ -331,12 +331,11 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcessUsingSpringBoard() const {
|
void CalculateBoardStatus();
|
||||||
return (m_flags & eMachProcessFlagsUsingSBS) != 0;
|
|
||||||
}
|
bool ProcessUsingBackBoard();
|
||||||
bool ProcessUsingBackBoard() const {
|
|
||||||
return (m_flags & eMachProcessFlagsUsingBKS) != 0;
|
bool ProcessUsingFrontBoard();
|
||||||
}
|
|
||||||
|
|
||||||
Genealogy::ThreadActivitySP GetGenealogyInfoForThread(nub_thread_t tid,
|
Genealogy::ThreadActivitySP GetGenealogyInfoForThread(nub_thread_t tid,
|
||||||
bool &timed_out);
|
bool &timed_out);
|
||||||
|
@ -349,9 +348,9 @@ private:
|
||||||
enum {
|
enum {
|
||||||
eMachProcessFlagsNone = 0,
|
eMachProcessFlagsNone = 0,
|
||||||
eMachProcessFlagsAttached = (1 << 0),
|
eMachProcessFlagsAttached = (1 << 0),
|
||||||
eMachProcessFlagsUsingSBS = (1 << 1),
|
eMachProcessFlagsUsingBKS = (1 << 2), // only read via ProcessUsingBackBoard()
|
||||||
eMachProcessFlagsUsingBKS = (1 << 2),
|
eMachProcessFlagsUsingFBS = (1 << 3), // only read via ProcessUsingFrontBoard()
|
||||||
eMachProcessFlagsUsingFBS = (1 << 3)
|
eMachProcessFlagsBoardCalculated = (1 << 4)
|
||||||
};
|
};
|
||||||
void Clear(bool detaching = false);
|
void Clear(bool detaching = false);
|
||||||
void ReplyToAllExceptions();
|
void ReplyToAllExceptions();
|
||||||
|
|
|
@ -2463,45 +2463,29 @@ pid_t MachProcess::AttachForDebug(pid_t pid, char *err_str, size_t err_len) {
|
||||||
const char *err_cstr = err.AsString();
|
const char *err_cstr = err.AsString();
|
||||||
::snprintf(err_str, err_len, "%s",
|
::snprintf(err_str, err_len, "%s",
|
||||||
err_cstr ? err_cstr : "No such process");
|
err_cstr ? err_cstr : "No such process");
|
||||||
|
DNBLogError ("MachProcess::AttachForDebug pid %d does not exist", pid);
|
||||||
return INVALID_NUB_PROCESS;
|
return INVALID_NUB_PROCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetState(eStateAttaching);
|
SetState(eStateAttaching);
|
||||||
m_pid = pid;
|
m_pid = pid;
|
||||||
// Let ourselves know we are going to be using SBS or BKS if the correct flag
|
|
||||||
// bit is set...
|
|
||||||
#if defined(WITH_FBS) || defined(WITH_BKS)
|
|
||||||
bool found_app_flavor = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(WITH_FBS)
|
|
||||||
if (!found_app_flavor && IsFBSProcess(pid)) {
|
|
||||||
found_app_flavor = true;
|
|
||||||
m_flags |= eMachProcessFlagsUsingFBS;
|
|
||||||
}
|
|
||||||
#elif defined(WITH_BKS)
|
|
||||||
if (!found_app_flavor && IsBKSProcess(pid)) {
|
|
||||||
found_app_flavor = true;
|
|
||||||
m_flags |= eMachProcessFlagsUsingBKS;
|
|
||||||
}
|
|
||||||
#elif defined(WITH_SPRINGBOARD)
|
|
||||||
if (IsSBProcess(pid))
|
|
||||||
m_flags |= eMachProcessFlagsUsingSBS;
|
|
||||||
#endif
|
|
||||||
if (!m_task.StartExceptionThread(err)) {
|
if (!m_task.StartExceptionThread(err)) {
|
||||||
const char *err_cstr = err.AsString();
|
const char *err_cstr = err.AsString();
|
||||||
::snprintf(err_str, err_len, "%s",
|
::snprintf(err_str, err_len, "%s",
|
||||||
err_cstr ? err_cstr : "unable to start the exception thread");
|
err_cstr ? err_cstr : "unable to start the exception thread");
|
||||||
DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", pid);
|
DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", pid);
|
||||||
|
DNBLogError ("MachProcess::AttachForDebug failed to start exception thread: %s", err_str);
|
||||||
m_pid = INVALID_NUB_PROCESS;
|
m_pid = INVALID_NUB_PROCESS;
|
||||||
return INVALID_NUB_PROCESS;
|
return INVALID_NUB_PROCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (::ptrace(PT_ATTACHEXC, pid, 0, 0))
|
if (::ptrace(PT_ATTACHEXC, pid, 0, 0)) {
|
||||||
err.SetError(errno);
|
err.SetError(errno);
|
||||||
else
|
DNBLogError ("MachProcess::AttachForDebug failed to ptrace(PT_ATTACHEXC): %s", err.AsString());
|
||||||
|
} else {
|
||||||
err.Clear();
|
err.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (err.Success()) {
|
if (err.Success()) {
|
||||||
m_flags |= eMachProcessFlagsAttached;
|
m_flags |= eMachProcessFlagsAttached;
|
||||||
|
@ -2513,7 +2497,17 @@ pid_t MachProcess::AttachForDebug(pid_t pid, char *err_str, size_t err_len) {
|
||||||
return m_pid;
|
return m_pid;
|
||||||
} else {
|
} else {
|
||||||
::snprintf(err_str, err_len, "%s", err.AsString());
|
::snprintf(err_str, err_len, "%s", err.AsString());
|
||||||
DNBLogThreadedIf(LOG_PROCESS, "error: failed to attach to pid %d", pid);
|
DNBLogError ("MachProcess::AttachForDebug error: failed to attach to pid %d", pid);
|
||||||
|
|
||||||
|
struct kinfo_proc kinfo;
|
||||||
|
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
|
||||||
|
size_t len = sizeof(struct kinfo_proc);
|
||||||
|
if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &kinfo, &len, NULL, 0) == 0 && len > 0) {
|
||||||
|
if (kinfo.kp_proc.p_flag & P_TRACED) {
|
||||||
|
::snprintf(err_str, err_len, "%s - process %d is already being debugged", err.AsString(), pid);
|
||||||
|
DNBLogError ("MachProcess::AttachForDebug pid %d is already being debugged", pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return INVALID_NUB_PROCESS;
|
return INVALID_NUB_PROCESS;
|
||||||
|
@ -2945,7 +2939,7 @@ pid_t MachProcess::LaunchForDebug(
|
||||||
const char *app_ext = strstr(path, ".app");
|
const char *app_ext = strstr(path, ".app");
|
||||||
if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) {
|
if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) {
|
||||||
std::string app_bundle_path(path, app_ext + strlen(".app"));
|
std::string app_bundle_path(path, app_ext + strlen(".app"));
|
||||||
m_flags |= eMachProcessFlagsUsingFBS;
|
m_flags |= (eMachProcessFlagsUsingFBS | eMachProcessFlagsBoardCalculated);
|
||||||
if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
|
if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
|
||||||
no_stdio, disable_aslr, event_data,
|
no_stdio, disable_aslr, event_data,
|
||||||
launch_err) != 0)
|
launch_err) != 0)
|
||||||
|
@ -2961,7 +2955,7 @@ pid_t MachProcess::LaunchForDebug(
|
||||||
const char *app_ext = strstr(path, ".app");
|
const char *app_ext = strstr(path, ".app");
|
||||||
if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) {
|
if (app_ext && (app_ext[4] == '\0' || app_ext[4] == '/')) {
|
||||||
std::string app_bundle_path(path, app_ext + strlen(".app"));
|
std::string app_bundle_path(path, app_ext + strlen(".app"));
|
||||||
m_flags |= eMachProcessFlagsUsingBKS;
|
m_flags |= (eMachProcessFlagsUsingBKS | eMachProcessFlagsBoardCalculated);
|
||||||
if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
|
if (BoardServiceLaunchForDebug(app_bundle_path.c_str(), argv, envp,
|
||||||
no_stdio, disable_aslr, event_data,
|
no_stdio, disable_aslr, event_data,
|
||||||
launch_err) != 0)
|
launch_err) != 0)
|
||||||
|
@ -3379,7 +3373,6 @@ pid_t MachProcess::SBLaunchForDebug(const char *path, char const *argv[],
|
||||||
m_pid = MachProcess::SBForkChildForPTraceDebugging(path, argv, envp, no_stdio,
|
m_pid = MachProcess::SBForkChildForPTraceDebugging(path, argv, envp, no_stdio,
|
||||||
this, launch_err);
|
this, launch_err);
|
||||||
if (m_pid != 0) {
|
if (m_pid != 0) {
|
||||||
m_flags |= eMachProcessFlagsUsingSBS;
|
|
||||||
m_path = path;
|
m_path = path;
|
||||||
size_t i;
|
size_t i;
|
||||||
char const *arg;
|
char const *arg;
|
||||||
|
@ -3734,7 +3727,7 @@ pid_t MachProcess::BoardServiceForkChildForPTraceDebugging(
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
#ifdef WITH_BKS
|
#ifdef WITH_BKS
|
||||||
if (m_flags & eMachProcessFlagsUsingBKS) {
|
if (ProcessUsingBackBoard()) {
|
||||||
options =
|
options =
|
||||||
BKSCreateOptionsDictionary(app_bundle_path, launch_argv, launch_envp,
|
BKSCreateOptionsDictionary(app_bundle_path, launch_argv, launch_envp,
|
||||||
stdio_path, disable_aslr, event_data);
|
stdio_path, disable_aslr, event_data);
|
||||||
|
@ -3743,7 +3736,7 @@ pid_t MachProcess::BoardServiceForkChildForPTraceDebugging(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_FBS
|
#ifdef WITH_FBS
|
||||||
if (m_flags & eMachProcessFlagsUsingFBS) {
|
if (ProcessUsingFrontBoard()) {
|
||||||
options =
|
options =
|
||||||
FBSCreateOptionsDictionary(app_bundle_path, launch_argv, launch_envp,
|
FBSCreateOptionsDictionary(app_bundle_path, launch_argv, launch_envp,
|
||||||
stdio_path, disable_aslr, event_data);
|
stdio_path, disable_aslr, event_data);
|
||||||
|
@ -3779,12 +3772,12 @@ bool MachProcess::BoardServiceSendEvent(const char *event_data,
|
||||||
// This is an event I cooked up. What you actually do is foreground the system
|
// This is an event I cooked up. What you actually do is foreground the system
|
||||||
// app, so:
|
// app, so:
|
||||||
#ifdef WITH_BKS
|
#ifdef WITH_BKS
|
||||||
if (m_flags & eMachProcessFlagsUsingBKS) {
|
if (ProcessUsingBackBoard()) {
|
||||||
return_value = BKSCallOpenApplicationFunction(nil, nil, send_err, NULL);
|
return_value = BKSCallOpenApplicationFunction(nil, nil, send_err, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_FBS
|
#ifdef WITH_FBS
|
||||||
if (m_flags & eMachProcessFlagsUsingFBS) {
|
if (ProcessUsingFrontBoard()) {
|
||||||
return_value = FBSCallOpenApplicationFunction(nil, nil, send_err, NULL);
|
return_value = FBSCallOpenApplicationFunction(nil, nil, send_err, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3808,7 +3801,7 @@ bool MachProcess::BoardServiceSendEvent(const char *event_data,
|
||||||
NSMutableDictionary *options = [NSMutableDictionary dictionary];
|
NSMutableDictionary *options = [NSMutableDictionary dictionary];
|
||||||
|
|
||||||
#ifdef WITH_BKS
|
#ifdef WITH_BKS
|
||||||
if (m_flags & eMachProcessFlagsUsingBKS) {
|
if (ProcessUsingBackBoard()) {
|
||||||
if (!BKSAddEventDataToOptions(options, event_data, send_err)) {
|
if (!BKSAddEventDataToOptions(options, event_data, send_err)) {
|
||||||
[pool drain];
|
[pool drain];
|
||||||
return false;
|
return false;
|
||||||
|
@ -3820,7 +3813,7 @@ bool MachProcess::BoardServiceSendEvent(const char *event_data,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_FBS
|
#ifdef WITH_FBS
|
||||||
if (m_flags & eMachProcessFlagsUsingFBS) {
|
if (ProcessUsingFrontBoard()) {
|
||||||
if (!FBSAddEventDataToOptions(options, event_data, send_err)) {
|
if (!FBSAddEventDataToOptions(options, event_data, send_err)) {
|
||||||
[pool drain];
|
[pool drain];
|
||||||
return false;
|
return false;
|
||||||
|
@ -3916,3 +3909,36 @@ void MachProcess::FBSCleanupAfterAttach(const void *attach_token,
|
||||||
[pool drain];
|
[pool drain];
|
||||||
}
|
}
|
||||||
#endif // WITH_FBS
|
#endif // WITH_FBS
|
||||||
|
|
||||||
|
|
||||||
|
void MachProcess::CalculateBoardStatus()
|
||||||
|
{
|
||||||
|
if (m_flags & eMachProcessFlagsBoardCalculated)
|
||||||
|
return;
|
||||||
|
if (m_pid == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool found_app_flavor = false;
|
||||||
|
#if defined(WITH_FBS)
|
||||||
|
if (!found_app_flavor && IsFBSProcess(m_pid)) {
|
||||||
|
found_app_flavor = true;
|
||||||
|
m_flags |= eMachProcessFlagsUsingFBS;
|
||||||
|
}
|
||||||
|
#elif defined(WITH_BKS)
|
||||||
|
if (!found_app_flavor && IsBKSProcess(m_pid)) {
|
||||||
|
found_app_flavor = true;
|
||||||
|
m_flags |= eMachProcessFlagsUsingBKS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
m_flags |= eMachProcessFlagsBoardCalculated;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MachProcess::ProcessUsingBackBoard() {
|
||||||
|
CalculateBoardStatus();
|
||||||
|
return (m_flags & eMachProcessFlagsUsingBKS) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MachProcess::ProcessUsingFrontBoard() {
|
||||||
|
CalculateBoardStatus();
|
||||||
|
return (m_flags & eMachProcessFlagsUsingFBS) != 0;
|
||||||
|
}
|
||||||
|
|
|
@ -495,8 +495,10 @@ task_t MachTask::TaskPortForProcessID(pid_t pid, DNBError &err,
|
||||||
"pid = %d, &task ) => err = 0x%8.8x (%s)",
|
"pid = %d, &task ) => err = 0x%8.8x (%s)",
|
||||||
task_self, pid, err.Status(),
|
task_self, pid, err.Status(),
|
||||||
err.AsString() ? err.AsString() : "success");
|
err.AsString() ? err.AsString() : "success");
|
||||||
if (err.Fail())
|
if (err.Fail()) {
|
||||||
err.SetErrorString(str);
|
err.SetErrorString(str);
|
||||||
|
DNBLogError ("MachTask::TaskPortForProcessID task_for_pid failed: %s", str);
|
||||||
|
}
|
||||||
err.LogThreaded(str);
|
err.LogThreaded(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue