forked from OSchip/llvm-project
[debugserver] Add option to propagate SIGSEGV to target process
Adds a command line option that makes debugserver propagate the SIGSEGV signal to the target process. Motivation: I'm one of the maintainers of Delve [1] a debugger for Go. We use debugserver as our backend on macOS and one of the most often reported bugs is that, on macOS, we don't propagate SIGSEGV back to the target process [2]. Sometimes some programs will actually cause a SIGSEGV, by design, and then handle it. Those programs can not be debugged at all. Since catching signals isn't very important for a Go debugger I'd much rather have a command line option in debugserver that causes it to let SIGSEGV go directly to the target process. [1] https://github.com/go-delve/delve/ [2] https://github.com/go-delve/delve/issues/852 Differential revision: https://reviews.llvm.org/D89315
This commit is contained in:
parent
8a4fe75d70
commit
27012c0f75
|
@ -319,20 +319,21 @@ static bool spawn_waitpid_thread(pid_t pid) {
|
|||
}
|
||||
|
||||
nub_process_t DNBProcessLaunch(
|
||||
const char *path, char const *argv[], const char *envp[],
|
||||
RNBContext *ctx, const char *path, char const *argv[], const char *envp[],
|
||||
const char *working_directory, // NULL => don't change, non-NULL => set
|
||||
// working directory for inferior to this
|
||||
const char *stdin_path, const char *stdout_path, const char *stderr_path,
|
||||
bool no_stdio, nub_launch_flavor_t launch_flavor, int disable_aslr,
|
||||
const char *event_data, char *err_str, size_t err_len) {
|
||||
DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, "
|
||||
bool no_stdio, int disable_aslr, const char *event_data, char *err_str,
|
||||
size_t err_len) {
|
||||
DNBLogThreadedIf(LOG_PROCESS,
|
||||
"%s ( path='%s', argv = %p, envp = %p, "
|
||||
"working_dir=%s, stdin=%s, stdout=%s, "
|
||||
"stderr=%s, no-stdio=%i, launch_flavor = %u, "
|
||||
"disable_aslr = %d, err = %p, err_len = "
|
||||
"%llu) called...",
|
||||
__FUNCTION__, path, static_cast<void *>(argv),
|
||||
static_cast<void *>(envp), working_directory, stdin_path,
|
||||
stdout_path, stderr_path, no_stdio, launch_flavor,
|
||||
stdout_path, stderr_path, no_stdio, ctx->LaunchFlavor(),
|
||||
disable_aslr, static_cast<void *>(err_str),
|
||||
static_cast<uint64_t>(err_len));
|
||||
|
||||
|
@ -349,10 +350,10 @@ nub_process_t DNBProcessLaunch(
|
|||
MachProcessSP processSP(new MachProcess);
|
||||
if (processSP.get()) {
|
||||
DNBError launch_err;
|
||||
pid_t pid = processSP->LaunchForDebug(path, argv, envp, working_directory,
|
||||
stdin_path, stdout_path, stderr_path,
|
||||
no_stdio, launch_flavor, disable_aslr,
|
||||
event_data, launch_err);
|
||||
pid_t pid = processSP->LaunchForDebug(
|
||||
path, argv, envp, working_directory, stdin_path, stdout_path,
|
||||
stderr_path, no_stdio, ctx->LaunchFlavor(), disable_aslr, event_data,
|
||||
ctx->GetUnmaskSignals(), launch_err);
|
||||
if (err_str) {
|
||||
*err_str = '\0';
|
||||
if (launch_err.Fail()) {
|
||||
|
@ -412,7 +413,8 @@ nub_process_t DNBProcessGetPIDByName(const char *name) {
|
|||
}
|
||||
|
||||
nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
|
||||
char *err_str, size_t err_len) {
|
||||
bool unmask_signals, char *err_str,
|
||||
size_t err_len) {
|
||||
if (err_str && err_len > 0)
|
||||
err_str[0] = '\0';
|
||||
std::vector<struct kinfo_proc> matching_proc_infos;
|
||||
|
@ -433,12 +435,12 @@ nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
|
|||
}
|
||||
|
||||
return DNBProcessAttach(matching_proc_infos[0].kp_proc.p_pid, timeout,
|
||||
err_str, err_len);
|
||||
unmask_signals, err_str, err_len);
|
||||
}
|
||||
|
||||
nub_process_t DNBProcessAttach(nub_process_t attach_pid,
|
||||
struct timespec *timeout, char *err_str,
|
||||
size_t err_len) {
|
||||
struct timespec *timeout, bool unmask_signals,
|
||||
char *err_str, size_t err_len) {
|
||||
if (err_str && err_len > 0)
|
||||
err_str[0] = '\0';
|
||||
|
||||
|
@ -480,7 +482,8 @@ nub_process_t DNBProcessAttach(nub_process_t attach_pid,
|
|||
if (processSP.get()) {
|
||||
DNBLogThreadedIf(LOG_PROCESS, "(DebugNub) attaching to pid %d...",
|
||||
attach_pid);
|
||||
pid = processSP->AttachForDebug(attach_pid, err_str, err_len);
|
||||
pid =
|
||||
processSP->AttachForDebug(attach_pid, unmask_signals, err_str, err_len);
|
||||
|
||||
if (pid != INVALID_NUB_PROCESS) {
|
||||
bool res = AddProcessToMap(pid, processSP);
|
||||
|
@ -667,15 +670,18 @@ GetAllInfosMatchingName(const char *full_process_name,
|
|||
return matching_proc_infos.size();
|
||||
}
|
||||
|
||||
nub_process_t DNBProcessAttachWait(
|
||||
const char *waitfor_process_name, nub_launch_flavor_t launch_flavor,
|
||||
nub_process_t
|
||||
DNBProcessAttachWait(RNBContext *ctx, const char *waitfor_process_name,
|
||||
bool ignore_existing, struct timespec *timeout_abstime,
|
||||
useconds_t waitfor_interval, char *err_str, size_t err_len,
|
||||
DNBShouldCancelCallback should_cancel_callback, void *callback_data) {
|
||||
DNBShouldCancelCallback should_cancel_callback,
|
||||
void *callback_data) {
|
||||
DNBError prepare_error;
|
||||
std::vector<struct kinfo_proc> exclude_proc_infos;
|
||||
size_t num_exclude_proc_infos;
|
||||
|
||||
nub_launch_flavor_t launch_flavor = ctx->LaunchFlavor();
|
||||
|
||||
// If the PrepareForAttach returns a valid token, use MachProcess to check
|
||||
// for the process, otherwise scan the process table.
|
||||
|
||||
|
@ -771,8 +777,8 @@ nub_process_t DNBProcessAttachWait(
|
|||
if (waitfor_pid != INVALID_NUB_PROCESS) {
|
||||
DNBLogThreadedIf(LOG_PROCESS, "Attaching to %s with pid %i...\n",
|
||||
waitfor_process_name, waitfor_pid);
|
||||
waitfor_pid =
|
||||
DNBProcessAttach(waitfor_pid, timeout_abstime, err_str, err_len);
|
||||
waitfor_pid = DNBProcessAttach(waitfor_pid, timeout_abstime,
|
||||
ctx->GetUnmaskSignals(), err_str, err_len);
|
||||
}
|
||||
|
||||
bool success = waitfor_pid != INVALID_NUB_PROCESS;
|
||||
|
|
|
@ -18,10 +18,11 @@
|
|||
#include "MacOSX/DarwinLog/DarwinLogEvent.h"
|
||||
#include "MacOSX/Genealogy.h"
|
||||
#include "MacOSX/ThreadInfo.h"
|
||||
#include <mach/thread_info.h>
|
||||
#include <string>
|
||||
#include "RNBContext.h"
|
||||
#include <Availability.h>
|
||||
#include <mach/machine.h>
|
||||
#include <mach/thread_info.h>
|
||||
#include <string>
|
||||
|
||||
#define DNB_EXPORT __attribute__((visibility("default")))
|
||||
|
||||
|
@ -42,22 +43,25 @@ nub_bool_t DNBSetArchitecture(const char *arch);
|
|||
|
||||
// Process control
|
||||
nub_process_t DNBProcessLaunch(
|
||||
const char *path, char const *argv[], const char *envp[],
|
||||
RNBContext *ctx, const char *path, char const *argv[], const char *envp[],
|
||||
const char *working_directory, // NULL => don't change, non-NULL => set
|
||||
// working directory for inferior to this
|
||||
const char *stdin_path, const char *stdout_path, const char *stderr_path,
|
||||
bool no_stdio, nub_launch_flavor_t launch_flavor, int disable_aslr,
|
||||
const char *event_data, char *err_str, size_t err_len);
|
||||
bool no_stdio, int disable_aslr, const char *event_data, char *err_str,
|
||||
size_t err_len);
|
||||
|
||||
nub_process_t DNBProcessGetPIDByName(const char *name);
|
||||
nub_process_t DNBProcessAttach(nub_process_t pid, struct timespec *timeout,
|
||||
char *err_str, size_t err_len);
|
||||
bool unmask_signals, char *err_str,
|
||||
size_t err_len);
|
||||
nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
|
||||
char *err_str, size_t err_len);
|
||||
nub_process_t
|
||||
DNBProcessAttachWait(const char *wait_name, nub_launch_flavor_t launch_flavor,
|
||||
bool ignore_existing, struct timespec *timeout,
|
||||
useconds_t interval, char *err_str, size_t err_len,
|
||||
bool unmask_signals, char *err_str,
|
||||
size_t err_len);
|
||||
nub_process_t DNBProcessAttachWait(RNBContext *ctx, const char *wait_name,
|
||||
bool ignore_existing,
|
||||
struct timespec *timeout,
|
||||
useconds_t interval, char *err_str,
|
||||
size_t err_len,
|
||||
DNBShouldCancelCallback should_cancel = NULL,
|
||||
void *callback_data = NULL);
|
||||
// Resume a process with exact instructions on what to do with each thread:
|
||||
|
|
|
@ -78,12 +78,14 @@ public:
|
|||
};
|
||||
|
||||
// Child process control
|
||||
pid_t AttachForDebug(pid_t pid, char *err_str, size_t err_len);
|
||||
pid_t AttachForDebug(pid_t pid, bool unmask_signals, char *err_str,
|
||||
size_t err_len);
|
||||
pid_t LaunchForDebug(const char *path, char const *argv[], char const *envp[],
|
||||
const char *working_directory, const char *stdin_path,
|
||||
const char *stdout_path, const char *stderr_path,
|
||||
bool no_stdio, nub_launch_flavor_t launch_flavor,
|
||||
int disable_aslr, const char *event_data, DNBError &err);
|
||||
int disable_aslr, const char *event_data,
|
||||
bool unmask_signals, DNBError &err);
|
||||
|
||||
static uint32_t GetCPUTypeForLocalProcess(pid_t pid);
|
||||
static pid_t ForkChildForPTraceDebugging(const char *path, char const *argv[],
|
||||
|
@ -107,7 +109,7 @@ public:
|
|||
pid_t BoardServiceLaunchForDebug(const char *app_bundle_path,
|
||||
char const *argv[], char const *envp[],
|
||||
bool no_stdio, bool disable_aslr,
|
||||
const char *event_data,
|
||||
const char *event_data, bool unmask_signals,
|
||||
DNBError &launch_err);
|
||||
pid_t BoardServiceForkChildForPTraceDebugging(
|
||||
const char *path, char const *argv[], char const *envp[], bool no_stdio,
|
||||
|
@ -128,7 +130,7 @@ public:
|
|||
#ifdef WITH_SPRINGBOARD
|
||||
pid_t SBLaunchForDebug(const char *app_bundle_path, char const *argv[],
|
||||
char const *envp[], bool no_stdio, bool disable_aslr,
|
||||
DNBError &launch_err);
|
||||
bool unmask_signals, DNBError &launch_err);
|
||||
static pid_t SBForkChildForPTraceDebugging(const char *path,
|
||||
char const *argv[],
|
||||
char const *envp[], bool no_stdio,
|
||||
|
|
|
@ -2600,7 +2600,8 @@ void *MachProcess::ProfileThread(void *arg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pid_t MachProcess::AttachForDebug(pid_t pid, char *err_str, size_t err_len) {
|
||||
pid_t MachProcess::AttachForDebug(pid_t pid, bool unmask_signals, char *err_str,
|
||||
size_t err_len) {
|
||||
// Clear out and clean up from any current state
|
||||
Clear();
|
||||
if (pid != 0) {
|
||||
|
@ -2617,7 +2618,7 @@ pid_t MachProcess::AttachForDebug(pid_t pid, char *err_str, size_t err_len) {
|
|||
|
||||
SetState(eStateAttaching);
|
||||
m_pid = pid;
|
||||
if (!m_task.StartExceptionThread(err)) {
|
||||
if (!m_task.StartExceptionThread(unmask_signals, err)) {
|
||||
const char *err_cstr = err.AsString();
|
||||
::snprintf(err_str, err_len, "%s",
|
||||
err_cstr ? err_cstr : "unable to start the exception thread");
|
||||
|
@ -3077,7 +3078,7 @@ pid_t MachProcess::LaunchForDebug(
|
|||
// working directory for inferior to this
|
||||
const char *stdin_path, const char *stdout_path, const char *stderr_path,
|
||||
bool no_stdio, nub_launch_flavor_t launch_flavor, int disable_aslr,
|
||||
const char *event_data, DNBError &launch_err) {
|
||||
const char *event_data, bool unmask_signals, DNBError &launch_err) {
|
||||
// Clear out and clean up from any current state
|
||||
Clear();
|
||||
|
||||
|
@ -3182,7 +3183,7 @@ pid_t MachProcess::LaunchForDebug(
|
|||
for (i = 0; (arg = argv[i]) != NULL; i++)
|
||||
m_args.push_back(arg);
|
||||
|
||||
m_task.StartExceptionThread(launch_err);
|
||||
m_task.StartExceptionThread(unmask_signals, launch_err);
|
||||
if (launch_err.Fail()) {
|
||||
if (launch_err.AsString() == NULL)
|
||||
launch_err.SetErrorString("unable to start the exception thread");
|
||||
|
@ -3525,7 +3526,8 @@ static CFStringRef CopyBundleIDForPath(const char *app_bundle_path,
|
|||
|
||||
pid_t MachProcess::SBLaunchForDebug(const char *path, char const *argv[],
|
||||
char const *envp[], bool no_stdio,
|
||||
bool disable_aslr, DNBError &launch_err) {
|
||||
bool disable_aslr, bool unmask_signals,
|
||||
DNBError &launch_err) {
|
||||
// Clear out and clean up from any current state
|
||||
Clear();
|
||||
|
||||
|
@ -3541,7 +3543,7 @@ pid_t MachProcess::SBLaunchForDebug(const char *path, char const *argv[],
|
|||
char const *arg;
|
||||
for (i = 0; (arg = argv[i]) != NULL; i++)
|
||||
m_args.push_back(arg);
|
||||
m_task.StartExceptionThread(launch_err);
|
||||
m_task.StartExceptionThread(unmask_signals, launch_err);
|
||||
|
||||
if (launch_err.Fail()) {
|
||||
if (launch_err.AsString() == NULL)
|
||||
|
@ -3738,7 +3740,8 @@ pid_t MachProcess::SBForkChildForPTraceDebugging(
|
|||
#if defined(WITH_BKS) || defined(WITH_FBS)
|
||||
pid_t MachProcess::BoardServiceLaunchForDebug(
|
||||
const char *path, char const *argv[], char const *envp[], bool no_stdio,
|
||||
bool disable_aslr, const char *event_data, DNBError &launch_err) {
|
||||
bool disable_aslr, const char *event_data, bool unmask_signals,
|
||||
DNBError &launch_err) {
|
||||
DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv)", __FUNCTION__, path);
|
||||
|
||||
// Fork a child process for debugging
|
||||
|
@ -3751,7 +3754,7 @@ pid_t MachProcess::BoardServiceLaunchForDebug(
|
|||
char const *arg;
|
||||
for (i = 0; (arg = argv[i]) != NULL; i++)
|
||||
m_args.push_back(arg);
|
||||
m_task.StartExceptionThread(launch_err);
|
||||
m_task.StartExceptionThread(unmask_signals, launch_err);
|
||||
|
||||
if (launch_err.Fail()) {
|
||||
if (launch_err.AsString() == NULL)
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
kern_return_t RestoreExceptionPortInfo();
|
||||
kern_return_t ShutDownExcecptionThread();
|
||||
|
||||
bool StartExceptionThread(DNBError &err);
|
||||
bool StartExceptionThread(bool unmask_signals, DNBError &err);
|
||||
nub_addr_t GetDYLDAllImageInfosAddress(DNBError &err);
|
||||
kern_return_t BasicInfo(struct task_basic_info *info);
|
||||
static kern_return_t BasicInfo(task_t task, struct task_basic_info *info);
|
||||
|
|
|
@ -595,7 +595,7 @@ bool MachTask::IsValid(task_t task) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool MachTask::StartExceptionThread(DNBError &err) {
|
||||
bool MachTask::StartExceptionThread(bool unmask_signals, DNBError &err) {
|
||||
DNBLogThreadedIf(LOG_EXCEPTIONS, "MachTask::%s ( )", __FUNCTION__);
|
||||
|
||||
task_t task = TaskPortForProcessID(err);
|
||||
|
@ -624,6 +624,12 @@ bool MachTask::StartExceptionThread(DNBError &err) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (unmask_signals) {
|
||||
m_exc_port_info.mask = m_exc_port_info.mask &
|
||||
~(EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION |
|
||||
EXC_MASK_ARITHMETIC);
|
||||
}
|
||||
|
||||
// Set the ability to get all exceptions on this port
|
||||
err = ::task_set_exception_ports(
|
||||
task, m_exc_port_info.mask, m_exception_port,
|
||||
|
|
|
@ -124,6 +124,11 @@ public:
|
|||
void SetDetachOnError(bool detach) { m_detach_on_error = detach; }
|
||||
bool GetDetachOnError() { return m_detach_on_error; }
|
||||
|
||||
void SetUnmaskSignals(bool unmask_signals) {
|
||||
m_unmask_signals = unmask_signals;
|
||||
}
|
||||
bool GetUnmaskSignals() { return m_unmask_signals; }
|
||||
|
||||
protected:
|
||||
// Classes that inherit from RNBContext can see and modify these
|
||||
nub_process_t m_pid;
|
||||
|
@ -147,6 +152,7 @@ protected:
|
|||
void StartProcessStatusThread();
|
||||
void StopProcessStatusThread();
|
||||
static void *ThreadFunctionProcessStatus(void *arg);
|
||||
bool m_unmask_signals;
|
||||
|
||||
private:
|
||||
RNBContext(const RNBContext &rhs) = delete;
|
||||
|
|
|
@ -3927,8 +3927,8 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
|
|||
}
|
||||
const bool ignore_existing = true;
|
||||
attach_pid = DNBProcessAttachWait(
|
||||
attach_name.c_str(), m_ctx.LaunchFlavor(), ignore_existing, NULL,
|
||||
1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
|
||||
&m_ctx, attach_name.c_str(), ignore_existing, NULL, 1000, err_str,
|
||||
sizeof(err_str), RNBRemoteShouldCancelCallback);
|
||||
|
||||
} else if (strstr(p, "vAttachOrWait;") == p) {
|
||||
p += strlen("vAttachOrWait;");
|
||||
|
@ -3939,8 +3939,8 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
|
|||
}
|
||||
const bool ignore_existing = false;
|
||||
attach_pid = DNBProcessAttachWait(
|
||||
attach_name.c_str(), m_ctx.LaunchFlavor(), ignore_existing, NULL,
|
||||
1000, err_str, sizeof(err_str), RNBRemoteShouldCancelCallback);
|
||||
&m_ctx, attach_name.c_str(), ignore_existing, NULL, 1000, err_str,
|
||||
sizeof(err_str), RNBRemoteShouldCancelCallback);
|
||||
} else if (strstr(p, "vAttachName;") == p) {
|
||||
p += strlen("vAttachName;");
|
||||
if (!GetProcessNameFrom_vAttach(p, attach_name)) {
|
||||
|
@ -3948,7 +3948,8 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
|
|||
__FILE__, __LINE__, p, "non-hex char in arg on 'vAttachName' pkt");
|
||||
}
|
||||
|
||||
attach_pid = DNBProcessAttachByName(attach_name.c_str(), NULL, err_str,
|
||||
attach_pid = DNBProcessAttachByName(attach_name.c_str(), NULL,
|
||||
Context().GetUnmaskSignals(), err_str,
|
||||
sizeof(err_str));
|
||||
|
||||
} else if (strstr(p, "vAttach;") == p) {
|
||||
|
@ -3961,7 +3962,7 @@ rnb_err_t RNBRemote::HandlePacket_v(const char *p) {
|
|||
struct timespec attach_timeout_abstime;
|
||||
DNBTimer::OffsetTimeOfDay(&attach_timeout_abstime, 30, 0);
|
||||
attach_pid = DNBProcessAttach(pid_attaching_to, &attach_timeout_abstime,
|
||||
err_str, sizeof(err_str));
|
||||
false, err_str, sizeof(err_str));
|
||||
}
|
||||
} else {
|
||||
return HandlePacket_UNIMPLEMENTED(p);
|
||||
|
|
|
@ -245,8 +245,8 @@ RNBRunLoopMode RNBRunLoopLaunchInferior(RNBRemote *remote,
|
|||
: ctx.GetWorkingDirectory());
|
||||
const char *process_event = ctx.GetProcessEvent();
|
||||
nub_process_t pid = DNBProcessLaunch(
|
||||
resolved_path, &inferior_argv[0], &inferior_envp[0], cwd, stdin_path,
|
||||
stdout_path, stderr_path, no_stdio, launch_flavor, g_disable_aslr,
|
||||
&ctx, resolved_path, &inferior_argv[0], &inferior_envp[0], cwd,
|
||||
stdin_path, stdout_path, stderr_path, no_stdio, g_disable_aslr,
|
||||
process_event, launch_err_str, sizeof(launch_err_str));
|
||||
|
||||
g_pid = pid;
|
||||
|
@ -368,7 +368,8 @@ RNBRunLoopMode RNBRunLoopLaunchAttaching(RNBRemote *remote,
|
|||
DNBLogThreadedIf(LOG_RNB_MINIMAL, "%s Attaching to pid %i...", __FUNCTION__,
|
||||
attach_pid);
|
||||
char err_str[1024];
|
||||
pid = DNBProcessAttach(attach_pid, NULL, err_str, sizeof(err_str));
|
||||
pid = DNBProcessAttach(attach_pid, NULL, ctx.GetUnmaskSignals(), err_str,
|
||||
sizeof(err_str));
|
||||
g_pid = pid;
|
||||
|
||||
if (pid == INVALID_NUB_PROCESS) {
|
||||
|
@ -889,6 +890,10 @@ static struct option g_long_options[] = {
|
|||
'F'}, // When debugserver launches the process, forward debugserver's
|
||||
// current environment variables to the child process ("./debugserver
|
||||
// -F localhost:1234 -- /bin/ls"
|
||||
{"unmask-signals", no_argument, NULL,
|
||||
'U'}, // debugserver will ignore EXC_MASK_BAD_ACCESS,
|
||||
// EXC_MASK_BAD_INSTRUCTION and EXC_MASK_ARITHMETIC, which results in
|
||||
// SIGSEGV, SIGILL and SIGFPE being propagated to the target process.
|
||||
{NULL, 0, NULL, 0}};
|
||||
|
||||
int communication_fd = -1;
|
||||
|
@ -1260,6 +1265,10 @@ int main(int argc, char *argv[]) {
|
|||
forward_env = true;
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
ctx.SetUnmaskSignals(true);
|
||||
break;
|
||||
|
||||
case '2':
|
||||
// File descriptor passed to this process during fork/exec and is already
|
||||
// open and ready for communication.
|
||||
|
@ -1514,8 +1523,8 @@ int main(int argc, char *argv[]) {
|
|||
RNBLogSTDOUT("Waiting to attach to process %s...\n",
|
||||
waitfor_pid_name.c_str());
|
||||
nub_process_t pid = DNBProcessAttachWait(
|
||||
waitfor_pid_name.c_str(), launch_flavor, ignore_existing,
|
||||
timeout_ptr, waitfor_interval, err_str, sizeof(err_str));
|
||||
&ctx, waitfor_pid_name.c_str(), ignore_existing, timeout_ptr,
|
||||
waitfor_interval, err_str, sizeof(err_str));
|
||||
g_pid = pid;
|
||||
|
||||
if (pid == INVALID_NUB_PROCESS) {
|
||||
|
@ -1550,7 +1559,8 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
RNBLogSTDOUT("Attaching to process %s...\n", attach_pid_name.c_str());
|
||||
nub_process_t pid = DNBProcessAttachByName(
|
||||
attach_pid_name.c_str(), timeout_ptr, err_str, sizeof(err_str));
|
||||
attach_pid_name.c_str(), timeout_ptr, ctx.GetUnmaskSignals(),
|
||||
err_str, sizeof(err_str));
|
||||
g_pid = pid;
|
||||
if (pid == INVALID_NUB_PROCESS) {
|
||||
ctx.LaunchStatus().SetError(-1, DNBError::Generic);
|
||||
|
|
Loading…
Reference in New Issue