forked from OSchip/llvm-project
Implement -target-attach and -target-detach
Summary: This changes add -target-attach and -target-detach. -target-attach allows lldb-mi to attach to an existing process by it's process id, matching gdb mi's syntax of '-target-attach <pid'. Additionally, support has been added for attaching to a process by name using '-target-attach -n <name>'. Combining this with --waitfor will allow lldb mi to attach to a process by name when the process starts. -target-detach simply detaches from the current process Patch from chuckr@microsoft.com Test Plan: I have added three tests, one each for -target-attach <pid>, -target-attach -n <name>, and -target-attach -n <name> --waitfor Reviewers: paulmaybee, abidh, ChuckR Subscribers: greggm, lldb-commits Differential Revision: http://reviews.llvm.org/D9484 llvm-svn: 236705
This commit is contained in:
parent
065397be00
commit
7bb59b360b
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := test_attach.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -0,0 +1,125 @@
|
|||
"""
|
||||
Test lldb-mi -target-xxx commands.
|
||||
"""
|
||||
|
||||
import lldbmi_testcase
|
||||
from lldbtest import *
|
||||
import unittest2
|
||||
|
||||
class MiTargetTestCase(lldbmi_testcase.MiTestCaseBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
@lldbmi_test
|
||||
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
|
||||
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
|
||||
@skipIfLinux # cannot attach to process on linux
|
||||
def test_lldbmi_target_attach_wait_for(self):
|
||||
"""Test that 'lldb-mi --interpreter' works for -target-attach -n <name> --waitfor."""
|
||||
|
||||
# Build target executable with unique name
|
||||
exeName = self.testMethodName
|
||||
d = {'EXE': exeName}
|
||||
self.buildProgram("test_attach.cpp", exeName)
|
||||
self.addTearDownCleanup(dictionary=d)
|
||||
|
||||
self.spawnLldbMi(args = None)
|
||||
|
||||
# Load executable
|
||||
# FIXME: -file-exec-and-sybmols is not required for target attach, but the test will not pass without this
|
||||
self.runCmd("-file-exec-and-symbols %s" % exeName)
|
||||
self.expect("\^done")
|
||||
|
||||
# Set up attach
|
||||
self.runCmd("-target-attach -n %s --waitfor" % exeName)
|
||||
time.sleep(4) # Give attach time to setup
|
||||
|
||||
# Start target process
|
||||
self.spawnSubprocess(os.path.join(os.path.dirname(__file__), exeName));
|
||||
self.addTearDownHook(self.cleanupSubprocesses)
|
||||
self.expect("\^done")
|
||||
|
||||
# Set breakpoint on printf
|
||||
line = line_number('test_attach.cpp', '// BP_i++')
|
||||
self.runCmd("-break-insert -f test_attach.cpp:%d" % line)
|
||||
self.expect("\^done,bkpt={number=\"1\"")
|
||||
|
||||
# Continue to breakpoint
|
||||
self.runCmd("-exec-continue")
|
||||
self.expect("\*stopped,reason=\"breakpoint-hit\"")
|
||||
|
||||
# Detach
|
||||
self.runCmd("-target-detach")
|
||||
self.expect("\^done")
|
||||
|
||||
@lldbmi_test
|
||||
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
|
||||
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
|
||||
@skipIfLinux # cannot attach to process on linux
|
||||
def test_lldbmi_target_attach_name(self):
|
||||
"""Test that 'lldb-mi --interpreter' works for -target-attach -n <name>."""
|
||||
|
||||
# Build target executable with unique name
|
||||
exeName = self.testMethodName
|
||||
d = {'EXE': exeName}
|
||||
self.buildProgram("test_attach.cpp", exeName)
|
||||
self.addTearDownCleanup(dictionary=d)
|
||||
|
||||
# Start target process
|
||||
targetProcess = self.spawnSubprocess(os.path.join(os.path.dirname(__file__), exeName));
|
||||
self.addTearDownHook(self.cleanupSubprocesses)
|
||||
|
||||
self.spawnLldbMi(args = None)
|
||||
|
||||
# Set up atatch
|
||||
self.runCmd("-target-attach -n %s" % exeName)
|
||||
self.expect("\^done")
|
||||
|
||||
# Set breakpoint on printf
|
||||
line = line_number('test_attach.cpp', '// BP_i++')
|
||||
self.runCmd("-break-insert -f test_attach.cpp:%d" % line)
|
||||
self.expect("\^done,bkpt={number=\"1\"")
|
||||
|
||||
# Continue to breakpoint
|
||||
self.runCmd("-exec-continue")
|
||||
self.expect("\*stopped,reason=\"breakpoint-hit\"")
|
||||
|
||||
# Detach
|
||||
self.runCmd("-target-detach")
|
||||
self.expect("\^done")
|
||||
|
||||
@lldbmi_test
|
||||
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
|
||||
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
|
||||
@skipIfLinux # cannot attach to process on linux
|
||||
def test_lldbmi_target_attach_pid(self):
|
||||
"""Test that 'lldb-mi --interpreter' works for -target-attach <pid>."""
|
||||
|
||||
# Build target executable with unique name
|
||||
exeName = self.testMethodName
|
||||
d = {'EXE': exeName}
|
||||
self.buildProgram("test_attach.cpp", exeName)
|
||||
self.addTearDownCleanup(dictionary=d)
|
||||
|
||||
# Start target process
|
||||
targetProcess = self.spawnSubprocess(os.path.join(os.path.dirname(__file__), exeName));
|
||||
self.addTearDownHook(self.cleanupSubprocesses)
|
||||
|
||||
self.spawnLldbMi(args = None)
|
||||
|
||||
# Set up atatch
|
||||
self.runCmd("-target-attach %d" % targetProcess.pid)
|
||||
self.expect("\^done")
|
||||
|
||||
# Set breakpoint on printf
|
||||
line = line_number('test_attach.cpp', '// BP_i++')
|
||||
self.runCmd("-break-insert -f test_attach.cpp:%d" % line)
|
||||
self.expect("\^done,bkpt={number=\"1\"")
|
||||
|
||||
# Continue to breakpoint
|
||||
self.runCmd("-exec-continue")
|
||||
self.expect("\*stopped,reason=\"breakpoint-hit\"")
|
||||
|
||||
# Detach
|
||||
self.runCmd("-target-detach")
|
||||
self.expect("\^done")
|
|
@ -0,0 +1,21 @@
|
|||
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
int
|
||||
main(int argc, char const *argv[])
|
||||
{
|
||||
int i = 0;
|
||||
for (;;)
|
||||
{
|
||||
i++; // BP_i++
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -22,6 +22,9 @@
|
|||
#include "MICmnLLDBDebugger.h"
|
||||
#include "MICmnLLDBDebugSessionInfo.h"
|
||||
#include "MICmdArgValString.h"
|
||||
#include "MICmdArgValOptionLong.h"
|
||||
#include "MICmdArgValOptionShort.h"
|
||||
#include "MICmdArgValNumber.h"
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: CMICmdCmdTargetSelect constructor.
|
||||
|
@ -204,3 +207,263 @@ CMICmdCmdTargetSelect::CreateSelf(void)
|
|||
{
|
||||
return new CMICmdCmdTargetSelect();
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: CMICmdCmdTargetAttach constructor.
|
||||
// Type: Method.
|
||||
// Args: None.
|
||||
// Return: None.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMICmdCmdTargetAttach::CMICmdCmdTargetAttach(void)
|
||||
: m_constStrArgPid("pid")
|
||||
, m_constStrArgNamedFile("n")
|
||||
, m_constStrArgWaitFor("waitfor")
|
||||
{
|
||||
// Command factory matches this name with that received from the stdin stream
|
||||
m_strMiCmd = "target-attach";
|
||||
|
||||
// Required by the CMICmdFactory when registering *this command
|
||||
m_pSelfCreatorFn = &CMICmdCmdTargetAttach::CreateSelf;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: CMICmdCmdTargetAttach destructor.
|
||||
// Type: Overrideable.
|
||||
// Args: None.
|
||||
// Return: None.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMICmdCmdTargetAttach::~CMICmdCmdTargetAttach(void)
|
||||
{
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: The invoker requires this function. The parses the command line options
|
||||
// arguments to extract values for each of those arguments.
|
||||
// Type: Overridden.
|
||||
// Args: None.
|
||||
// Return: MIstatus::success - Functional succeeded.
|
||||
// MIstatus::failure - Functional failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmdCmdTargetAttach::ParseArgs(void)
|
||||
{
|
||||
bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPid, false, true)));
|
||||
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgNamedFile, false, true,
|
||||
CMICmdArgValListBase::eArgValType_String, 1)));
|
||||
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgWaitFor, false, true)));
|
||||
return (bOk && ParseValidateCmdOptions());
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: The invoker requires this function. The command does work in this function.
|
||||
// The command is likely to communicate with the LLDB SBDebugger in here.
|
||||
// Synopsis: -target-attach file
|
||||
// Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
|
||||
// Type: Overridden.
|
||||
// Args: None.
|
||||
// Return: MIstatus::success - Functional succeeded.
|
||||
// MIstatus::failure - Functional failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmdCmdTargetAttach::Execute(void)
|
||||
{
|
||||
CMICMDBASE_GETOPTION(pArgPid, Number, m_constStrArgPid);
|
||||
CMICMDBASE_GETOPTION(pArgFile, OptionShort, m_constStrArgNamedFile);
|
||||
CMICMDBASE_GETOPTION(pArgWaitFor, OptionLong, m_constStrArgWaitFor);
|
||||
|
||||
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
||||
|
||||
// If the current target is invalid, create one
|
||||
lldb::SBTarget target = rSessionInfo.GetTarget();
|
||||
if (!target.IsValid())
|
||||
{
|
||||
target = rSessionInfo.GetDebugger().CreateTarget(NULL);
|
||||
if (!target.IsValid())
|
||||
{
|
||||
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT), m_cmdData.strMiCmd.c_str()));
|
||||
return MIstatus::failure;
|
||||
}
|
||||
}
|
||||
|
||||
lldb::SBError error;
|
||||
lldb::SBListener listener;
|
||||
if (pArgPid->GetFound() && pArgPid->GetValid())
|
||||
{
|
||||
lldb::pid_t pid;
|
||||
pid = pArgPid->GetValue();
|
||||
target.AttachToProcessWithID(listener, pid, error);
|
||||
}
|
||||
else if (pArgFile->GetFound() && pArgFile->GetValid())
|
||||
{
|
||||
bool bWaitFor = (pArgWaitFor->GetFound());
|
||||
CMIUtilString file;
|
||||
pArgFile->GetExpectedOption<CMICmdArgValString>(file);
|
||||
target.AttachToProcessWithName(listener, file.c_str(), bWaitFor, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ATTACH_BAD_ARGS), m_cmdData.strMiCmd.c_str()));
|
||||
return MIstatus::failure;
|
||||
}
|
||||
|
||||
lldb::SBStream errMsg;
|
||||
if (error.Fail())
|
||||
{
|
||||
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_ATTACH_FAILED), m_cmdData.strMiCmd.c_str(), errMsg.GetData()));
|
||||
return MIstatus::failure;
|
||||
}
|
||||
|
||||
return MIstatus::success;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: The invoker requires this function. The command prepares a MI Record Result
|
||||
// for the work carried out in the Execute().
|
||||
// Type: Overridden.
|
||||
// Args: None.
|
||||
// Return: MIstatus::success - Functional succeeded.
|
||||
// MIstatus::failure - Functional failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmdCmdTargetAttach::Acknowledge(void)
|
||||
{
|
||||
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
||||
m_miResultRecord = miRecordResult;
|
||||
|
||||
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
||||
lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
|
||||
// Prod the client i.e. Eclipse with out-of-band results to help it 'continue' because it is using LLDB debugger
|
||||
// Give the client '=thread-group-started,id="i1"'
|
||||
m_bHasResultRecordExtra = true;
|
||||
const CMICmnMIValueConst miValueConst2("i1");
|
||||
const CMICmnMIValueResult miValueResult2("id", miValueConst2);
|
||||
const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
|
||||
const CMICmnMIValueConst miValueConst(strPid);
|
||||
const CMICmnMIValueResult miValueResult("pid", miValueConst);
|
||||
CMICmnMIOutOfBandRecord miOutOfBand(CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, miValueResult2);
|
||||
miOutOfBand.Add(miValueResult);
|
||||
m_miResultRecordExtra = miOutOfBand.GetString();
|
||||
|
||||
return MIstatus::success;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: Required by the CMICmdFactory when registering *this command. The factory
|
||||
// calls this function to create an instance of *this command.
|
||||
// Type: Static method.
|
||||
// Args: None.
|
||||
// Return: CMICmdBase * - Pointer to a new command.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMICmdBase *
|
||||
CMICmdCmdTargetAttach::CreateSelf(void)
|
||||
{
|
||||
return new CMICmdCmdTargetAttach();
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: CMICmdCmdTargetDetach constructor.
|
||||
// Type: Method.
|
||||
// Args: None.
|
||||
// Return: None.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMICmdCmdTargetDetach::CMICmdCmdTargetDetach()
|
||||
{
|
||||
// Command factory matches this name with that received from the stdin stream
|
||||
m_strMiCmd = "target-detach";
|
||||
|
||||
// Required by the CMICmdFactory when registering *this command
|
||||
m_pSelfCreatorFn = &CMICmdCmdTargetDetach::CreateSelf;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: CMICmdCmdTargetDetach destructor.
|
||||
// Type: Overrideable.
|
||||
// Args: None.
|
||||
// Return: None.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMICmdCmdTargetDetach::~CMICmdCmdTargetDetach(void)
|
||||
{
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: The invoker requires this function. The parses the command line options
|
||||
// arguments to extract values for each of those arguments.
|
||||
// Type: Overridden.
|
||||
// Args: None.
|
||||
// Return: MIstatus::success - Functional succeeded.
|
||||
// MIstatus::failure - Functional failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmdCmdTargetDetach::ParseArgs(void)
|
||||
{
|
||||
return MIstatus::success;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: The invoker requires this function. The command does work in this function.
|
||||
// The command is likely to communicate with the LLDB SBDebugger in here.
|
||||
// Synopsis: -target-attach file
|
||||
// Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
|
||||
// Type: Overridden.
|
||||
// Args: None.
|
||||
// Return: MIstatus::success - Functional succeeded.
|
||||
// MIstatus::failure - Functional failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmdCmdTargetDetach::Execute(void)
|
||||
{
|
||||
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
|
||||
|
||||
lldb::SBProcess process = rSessionInfo.GetProcess();
|
||||
|
||||
if (!process.IsValid())
|
||||
{
|
||||
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str()));
|
||||
return MIstatus::failure;
|
||||
}
|
||||
|
||||
process.Detach();
|
||||
|
||||
return MIstatus::success;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: The invoker requires this function. The command prepares a MI Record Result
|
||||
// for the work carried out in the Execute().
|
||||
// Type: Overridden.
|
||||
// Args: None.
|
||||
// Return: MIstatus::success - Functional succeeded.
|
||||
// MIstatus::failure - Functional failed.
|
||||
// Throws: None.
|
||||
//--
|
||||
bool
|
||||
CMICmdCmdTargetDetach::Acknowledge(void)
|
||||
{
|
||||
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
||||
m_miResultRecord = miRecordResult;
|
||||
return MIstatus::success;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: Required by the CMICmdFactory when registering *this command. The factory
|
||||
// calls this function to create an instance of *this command.
|
||||
// Type: Static method.
|
||||
// Args: None.
|
||||
// Return: CMICmdBase * - Pointer to a new command.
|
||||
// Throws: None.
|
||||
//--
|
||||
CMICmdBase *
|
||||
CMICmdCmdTargetDetach::CreateSelf(void)
|
||||
{
|
||||
return new CMICmdCmdTargetDetach();
|
||||
}
|
||||
|
|
|
@ -58,3 +58,62 @@ class CMICmdCmdTargetSelect : public CMICmdBase
|
|||
const CMIUtilString m_constStrArgNamedType;
|
||||
const CMIUtilString m_constStrArgNamedParameters;
|
||||
};
|
||||
|
||||
//++ ============================================================================
|
||||
// Details: MI command class. MI commands derived from the command base class.
|
||||
// *this class implements MI command "target-attach".
|
||||
// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
|
||||
//--
|
||||
class CMICmdCmdTargetAttach : public CMICmdBase
|
||||
{
|
||||
// Statics:
|
||||
public:
|
||||
// Required by the CMICmdFactory when registering *this command
|
||||
static CMICmdBase *CreateSelf(void);
|
||||
|
||||
// Methods:
|
||||
public:
|
||||
/* ctor */ CMICmdCmdTargetAttach(void);
|
||||
|
||||
// Overridden:
|
||||
public:
|
||||
// From CMICmdInvoker::ICmd
|
||||
virtual bool Execute(void);
|
||||
virtual bool Acknowledge(void);
|
||||
virtual bool ParseArgs(void);
|
||||
// From CMICmnBase
|
||||
/* dtor */ virtual ~CMICmdCmdTargetAttach(void);
|
||||
|
||||
// Attributes:
|
||||
private:
|
||||
const CMIUtilString m_constStrArgPid;
|
||||
const CMIUtilString m_constStrArgNamedFile;
|
||||
const CMIUtilString m_constStrArgWaitFor;
|
||||
};
|
||||
|
||||
//++ ============================================================================
|
||||
// Details: MI command class. MI commands derived from the command base class.
|
||||
// *this class implements MI command "target-attach".
|
||||
// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Target-Manipulation.html#GDB_002fMI-Target-Manipulation
|
||||
//--
|
||||
class CMICmdCmdTargetDetach : public CMICmdBase
|
||||
{
|
||||
// Statics:
|
||||
public:
|
||||
// Required by the CMICmdFactory when registering *this command
|
||||
static CMICmdBase *CreateSelf(void);
|
||||
|
||||
// Methods:
|
||||
public:
|
||||
/* ctor */ CMICmdCmdTargetDetach(void);
|
||||
|
||||
// Overridden:
|
||||
public:
|
||||
// From CMICmdInvoker::ICmd
|
||||
virtual bool Execute(void);
|
||||
virtual bool Acknowledge(void);
|
||||
virtual bool ParseArgs(void);
|
||||
// From CMICmnBase
|
||||
/* dtor */ virtual ~CMICmdCmdTargetDetach(void);
|
||||
};
|
||||
|
||||
|
|
|
@ -121,6 +121,8 @@ MICmnCommands::RegisterAll(void)
|
|||
bOk &= Register<CMICmdCmdSupportListFeatures>();
|
||||
bOk &= Register<CMICmdCmdSymbolListLines>();
|
||||
bOk &= Register<CMICmdCmdTargetSelect>();
|
||||
bOk &= Register<CMICmdCmdTargetAttach>();
|
||||
bOk &= Register<CMICmdCmdTargetDetach>();
|
||||
bOk &= Register<CMICmdCmdThreadInfo>();
|
||||
bOk &= Register<CMICmdCmdVarAssign>();
|
||||
bOk &= Register<CMICmdCmdVarCreate>();
|
||||
|
|
|
@ -250,7 +250,9 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
|
|||
{IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION, "'print' error. The option '%s' not found"},
|
||||
{IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS, "'print' expects option-name and \"on\" or \"off\""},
|
||||
{IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION, "'print' error. The option '%s' not found"},
|
||||
{IDS_CMD_ERR_EXPR_INVALID, "Failed to evaluate expression: %s"}};
|
||||
{IDS_CMD_ERR_EXPR_INVALID, "Failed to evaluate expression: %s"},
|
||||
{IDS_CMD_ERR_ATTACH_FAILED, "Command '%s'. Attach to processs failed: %s"},
|
||||
{IDS_CMD_ERR_ATTACH_BAD_ARGS, "Command '%s'. Must specify either a PID or a Name"}};
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: CMICmnResources constructor.
|
||||
|
|
|
@ -268,7 +268,9 @@ enum
|
|||
IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION,
|
||||
IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS,
|
||||
IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION,
|
||||
IDS_CMD_ERR_EXPR_INVALID
|
||||
IDS_CMD_ERR_EXPR_INVALID,
|
||||
IDS_CMD_ERR_ATTACH_FAILED,
|
||||
IDS_CMD_ERR_ATTACH_BAD_ARGS
|
||||
};
|
||||
|
||||
//++ ============================================================================
|
||||
|
|
|
@ -91,3 +91,13 @@ The =library-loaded notification has 3 extra fields:
|
|||
For example:
|
||||
=library-loaded,id="/Users/IliaK/p/hello",target-name="/Users/IliaK/p/hello",host-name="/Users/IliaK/p/hello",symbols-loaded="1",symbols-path="/Users/IliaK/p/hello.dSYM/Contents/Resources/DWARF/hello",loaded_addr="-"
|
||||
=library-loaded,id="/usr/lib/dyld",target-name="/usr/lib/dyld",host-name="/usr/lib/dyld",symbols-loaded="0",loaded_addr="0x00007fff5fc00000"
|
||||
|
||||
# -target-attach
|
||||
|
||||
Synopsis
|
||||
|
||||
Additional syntax provided by lldb-mi:
|
||||
-target-attach -n <executable-name> [--waitfor]
|
||||
|
||||
Attach to an executable. Using -n allows specifying an executable name to attach to.
|
||||
Using this with --watifor can do a deffered attach. The flags -n and --waitfor match the syntax of lldb proper's 'process attach' command.
|
||||
|
|
Loading…
Reference in New Issue