Fix tests
http://reviews.llvm.org/D7500
Files:
test/tools/lldb-mi/TestMiNotification.py
test/tools/lldb-mi/main.c
tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: test/tools/lldb-mi/TestMiNotification.py
===================================================================
--- test/tools/lldb-mi/TestMiNotification.py
+++ test/tools/lldb-mi/TestMiNotification.py
@@ -119,5 +119,89 @@
# Clean up
debugserver_child.terminate(force = True)
+ @lldbmi_test
+ @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ def test_lldbmi_stopped_when_segfault_local(self):
+ """Test that 'lldb-mi --interpreter' notifies after it was stopped when segfault occurred (local)."""
+
+ self.spawnLldbMi(args = None)
+
+ # Load executable
+ self.runCmd("-file-exec-and-symbols %s" % self.myexe)
+ self.expect("\^done")
+
+ # Run to main
+ self.runCmd("-break-insert -f main")
+ self.expect("\^done,bkpt={number=\"1\"")
+ self.runCmd("-exec-run")
+ self.expect("\^running")
+ self.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+ # Set dosegfault=1 and run (to cause a segfault error)
+ self.runCmd("-data-evaluate-expression \"dosegfault=1\"")
+ self.expect("\^done,value=\"1\"")
+ self.runCmd("-exec-continue")
+ self.expect("\^running")
+
+ # Test that *stopped is printed
+ self.expect("\*stopped,reason=\"exception-received\",exception=\"EXC_BAD_ACCESS \(code=1, address=0x0\)\",thread-id=\"1\",stopped-threads=\"all\"")
+
+ @lldbmi_test
+ @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ def test_lldbmi_stopped_when_segfault_remote(self):
+ """Test that 'lldb-mi --interpreter' notifies after it was stopped when segfault occurred (remote)."""
+
+ # Prepare debugserver
+ import os, sys
+ lldb_gdbserver_folder = os.path.abspath(os.path.join(os.path.dirname(os.getcwd()), "lldb-gdbserver"))
+ sys.path.append(lldb_gdbserver_folder)
+ import lldbgdbserverutils
+ debugserver_exe = lldbgdbserverutils.get_debugserver_exe()
+ if not debugserver_exe:
+ raise Exception("debugserver not found")
+ hostname = "localhost"
+ import random
+ port = 12000 + random.randint(0,3999) # the same as GdbRemoteTestCaseBase.get_next_port
+ import pexpect
+ debugserver_child = pexpect.spawn("%s %s:%d" % (debugserver_exe, hostname, port))
+
+ self.spawnLldbMi(args = None)
+
+ # Connect to debugserver
+ self.runCmd("-interpreter-exec command \"platform select remote-macosx --sysroot /\"")
+ self.expect("\^done")
+ self.runCmd("-file-exec-and-symbols %s" % self.myexe)
+ self.expect("\^done")
+ self.runCmd("-interpreter-exec command \"process connect connect://%s:%d\"" % (hostname, port))
+ self.expect("\^done")
+
+ try:
+ # Run to main
+ self.runCmd("-break-insert -f main")
+ self.expect("\^done,bkpt={number=\"1\"")
+ #FIXME -exec-run doesn't work
+ self.runCmd("-interpreter-exec command \"process launch\"") #FIXME: self.runCmd("-exec-run")
+ self.expect("\^done") #FIXME: self.expect("\^running")
+ self.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+ # Set dosegfault=1 and run (to cause a segfault error)
+ self.runCmd("-data-evaluate-expression \"dosegfault=1\"")
+ self.expect("\^done,value=\"1\"")
+ self.runCmd("-exec-continue")
+ self.expect("\^running")
+
+ # Test that *stopped is printed
+ self.expect("\*stopped,reason=\"exception-received\",exception=\"EXC_BAD_ACCESS \(code=1, address=0x0\)\",thread-id=\"1\",stopped-threads=\"all\"")
+
+ # Exit
+ self.runCmd("-gdb-exit")
+ self.runCmd("") #FIXME lldb-mi hangs here on Linux; extra return is needed
+ self.expect("\^exit")
+
+ finally:
+ # Clean up
+ debugserver_child.terminate(force = True)
+
if __name__ == '__main__':
unittest2.main()
Index: test/tools/lldb-mi/main.c
===================================================================
--- test/tools/lldb-mi/main.c
+++ test/tools/lldb-mi/main.c
@@ -11,7 +11,7 @@
extern int a_MyFunction();
extern int b_MyFunction();
extern int infloop();
-int doloop;
+int doloop, dosegfault;
int g_MyVar = 3;
static int s_MyVar = 4;
int main (int argc, char const *argv[])
@@ -24,6 +24,8 @@
//BP_localstest -- it must be at line #24 (or fix it in main*.micmds)
if (doloop) // BP_doloop
infloop();
+ if (dosegfault)
+ *(volatile int *)NULL = 1;
if (argc > 1 && *argv[1] == 'l') {
a++;
printf("a=%d, argv[1]=%s\n", a, argv[1]); //BP_argtest
Index: tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
===================================================================
--- tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
+++ tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
@@ -796,6 +796,7 @@
break;
case lldb::eStopReasonException:
pEventType = "eStopReasonException";
+ bOk = HandleProcessEventStopException();
break;
case lldb::eStopReasonExec:
pEventType = "eStopReasonExec";
@@ -931,6 +932,44 @@
}
//++ ------------------------------------------------------------------------------------
+// Details: Asynchronous event handler for LLDB Process stop exception.
+// Type: Method.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopException(void)
+{
+ const lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ lldb::SBThread sbThread = sbProcess.GetSelectedThread();
+ const size_t nStopDescriptionLen = sbThread.GetStopDescription(nullptr, 0);
+ std::shared_ptr<char> spStopDescription(new char[nStopDescriptionLen]);
+ sbThread.GetStopDescription(spStopDescription.get(), nStopDescriptionLen);
+
+ // MI print "*stopped,reason=\"exception-received\",exception=\"%s\",thread-id=\"%d\",stopped-threads=\"all\""
+ const CMICmnMIValueConst miValueConst("exception-received");
+ const CMICmnMIValueResult miValueResult("reason", miValueConst);
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
+ const CMIUtilString strReason(spStopDescription.get());
+ const CMICmnMIValueConst miValueConst2(strReason);
+ const CMICmnMIValueResult miValueResult2("exception", miValueConst2);
+ bool bOk = miOutOfBandRecord.Add(miValueResult2);
+ const CMIUtilString strThreadId(CMIUtilString::Format("%d", sbThread.GetIndexID()));
+ const CMICmnMIValueConst miValueConst3(strThreadId);
+ const CMICmnMIValueResult miValueResult3("thread-id", miValueConst3);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
+ const CMICmnMIValueConst miValueConst4("all");
+ const CMICmnMIValueResult miValueResult4("stopped-threads", miValueConst4);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
+ bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ bOk = bOk && TextToStdout("(gdb)");
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
// Details: Form partial MI response in a MI value tuple object.
// Type: Method.
// Args: vwrMiValueTuple - (W) MI value tuple object.
Index: tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h
===================================================================
--- tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h
+++ tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h
@@ -77,6 +77,7 @@
bool HandleProcessEventStopReasonTrace(void);
bool HandleProcessEventStopReasonBreakpoint(void);
bool HandleProcessEventStopSignal(bool &vwrbShouldBrk);
+ bool HandleProcessEventStopException(void);
bool HandleProcessEventStateSuspended(const lldb::SBEvent &vEvent);
bool MiHelpGetCurrentThreadFrame(CMICmnMIValueTuple &vwrMiValueTuple);
bool MiResultRecordToStdout(const CMICmnMIResultRecord &vrMiResultRecord);
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits