Report more precise error message when attach fails

Summary:
If the remote stub sends a specific error message instead of just a E??
code, we can use this to display a more informative error message
instead of just the generic "unable to attach" message.

I write a test for this using the SB API.
On the console this will show up like:
(lldb) process attach ...
error: attach failed: <STUB-MESSAGE>

if the stub supports error messages, or:
error: attach failed: Error ??

if it doesn't.

Reviewers: jingham, JDevlieghere

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D45573

llvm-svn: 330247
This commit is contained in:
Pavel Labath 2018-04-18 11:56:21 +00:00
parent 90d141a295
commit acebc43799
3 changed files with 39 additions and 5 deletions

View File

@ -11,3 +11,28 @@ class TestGDBRemoteClient(GDBRemoteTestBase):
target = self.createTarget("a.yaml")
process = self.connect(target)
self.assertPacketLogContains(["qProcessInfo", "qfThreadInfo"])
def test_attach_fail(self):
error_msg = "mock-error-msg"
class MyResponder(MockGDBServerResponder):
# Pretend we don't have any process during the initial queries.
def qC(self):
return "E42"
def qfThreadInfo(self):
return "OK" # No threads.
# Then, when we are asked to attach, error out.
def vAttach(self, pid):
return "E42;" + error_msg.encode("hex")
self.server.responder = MyResponder()
target = self.dbg.CreateTarget("")
process = self.connect(target)
lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, [lldb.eStateConnected])
error = lldb.SBError()
target.AttachToProcessWithID(lldb.SBListener(), 47, error)
self.assertEquals(error_msg, error.GetCString())

View File

@ -126,6 +126,8 @@ class MockGDBServerResponder:
return self.qfThreadInfo()
if packet == "qC":
return self.qC()
if packet == "QEnableErrorStrings":
return self.QEnableErrorStrings()
if packet == "?":
return self.haltReason()
if packet[0] == "H":
@ -137,6 +139,9 @@ class MockGDBServerResponder:
if data is not None:
return self._qXferResponse(data, has_more)
return ""
if packet.startswith("vAttach;"):
pid = packet.partition(';')[2]
return self.vAttach(int(pid, 16))
if packet[0] == "Z":
return self.setBreakpoint(packet)
return self.other(packet)
@ -177,6 +182,9 @@ class MockGDBServerResponder:
def qC(self):
return "QC0"
def QEnableErrorStrings(self):
return "OK"
def haltReason(self):
# SIGINT is 2, return type is 2 digit hex string
return "S02"
@ -187,6 +195,9 @@ class MockGDBServerResponder:
def _qXferResponse(self, data, has_more):
return "%s%s" % ("m" if has_more else "l", escape_binary(data))
def vAttach(self, pid):
raise self.UnexpectedPacketException()
def selectThread(self, op, thread_id):
return "OK"

View File

@ -3804,11 +3804,9 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
response.GetError() == 0x87) {
process->SetExitStatus(-1, "cannot attach to process due to "
"System Integrity Protection");
}
// E01 code from vAttach means that the attach failed
if (::strstr(continue_cstr, "vAttach") != NULL &&
response.GetError() == 0x1) {
process->SetExitStatus(-1, "unable to attach");
} else if (::strstr(continue_cstr, "vAttach") != NULL &&
response.GetStatus().Fail()) {
process->SetExitStatus(-1, response.GetStatus().AsCString());
} else {
process->SetExitStatus(-1, "lost connection");
}