Index: packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/Makefile =================================================================== --- packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/Makefile +++ packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../make + +LDFLAGS=-pthread + +CXX_SOURCES := test_threadinfo.cpp + +include $(LEVEL)/Makefile.rules Index: packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/TestMiThreadInfo.py =================================================================== --- packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/TestMiThreadInfo.py +++ packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/TestMiThreadInfo.py @@ -0,0 +1,39 @@ +""" +Test lldb-mi -thread-info command. +""" + +from __future__ import print_function + +import lldbmi_testcase +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class MiThreadInfoTestCase(lldbmi_testcase.MiTestCaseBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfWindows # pthreads not supported on Windows + @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races + def test_lldbmi_thread_info(self): + """Test that -thread-info prints thread info and the current-thread-id""" + + self.spawnLldbMi(args = None) + + # Load executable + self.runCmd("-file-exec-and-symbols %s" % self.myexe) + self.expect("\^done") + + self.runCmd("-break-insert ThreadProc") + self.expect("\^done") + + # Run to the breakpoint + self.runCmd("-exec-run") + self.expect("\^running") + self.expect("\*stopped,reason=\"breakpoint-hit\"") + + self.runCmd("-thread-info") + self.expect("\^done,threads=\[\{id=\"1\",(.*)\},\{id=\"2\",(.*)\],current-thread-id=\"2\"") + + self.runCmd("-gdb-quit") + Index: packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/test_threadinfo.cpp =================================================================== --- packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/test_threadinfo.cpp +++ packages/Python/lldbsuite/test/tools/lldb-mi/threadinfo/test_threadinfo.cpp @@ -0,0 +1,21 @@ +#include +#include +#include + +using namespace std; + +void +ThreadProc() +{ + int i = 0; + i++; +} + +int +main() +{ + thread t(ThreadProc); + t.join(); + + return 0; +} Index: tools/lldb-mi/MICmdCmdThread.h =================================================================== --- tools/lldb-mi/MICmdCmdThread.h +++ tools/lldb-mi/MICmdCmdThread.h @@ -60,4 +60,8 @@ bool m_bThreadInvalid; // True = invalid, false = ok VecMIValueTuple_t m_vecMIValueTuple; const CMIUtilString m_constStrArgNamedThreadId; + + // mi value of current-thread-id if multiple threads are requested + bool m_bHasCurrentThread; + CMICmnMIValue m_miValueCurrThreadId; }; Index: tools/lldb-mi/MICmdCmdThread.cpp =================================================================== --- tools/lldb-mi/MICmdCmdThread.cpp +++ tools/lldb-mi/MICmdCmdThread.cpp @@ -29,9 +29,10 @@ // Throws: None. //-- CMICmdCmdThreadInfo::CMICmdCmdThreadInfo() - : m_bSingleThread(false) - , m_bThreadInvalid(true) - , m_constStrArgNamedThreadId("thread-id") + : m_bSingleThread(false), + m_bThreadInvalid(true), + m_constStrArgNamedThreadId("thread-id"), + m_bHasCurrentThread(false) { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "thread-info"; @@ -124,6 +125,15 @@ } } + // -thread-info with multiple threads ends with the current thread id if any + if (thread.IsValid()) + { + const CMIUtilString strId(CMIUtilString::Format("%d", thread.GetIndexID())); + CMICmnMIValueConst miValueCurrThreadId(strId); + m_miValueCurrThreadId = miValueCurrThreadId; + m_bHasCurrentThread = true; + } + return MIstatus::success; } @@ -179,7 +189,12 @@ ++it; } - const CMICmnMIValueResult miValueResult("threads", miValueList); + CMICmnMIValueResult miValueResult("threads", miValueList); + if (m_bHasCurrentThread) + { + CMIUtilString strCurrThreadId = "current-thread-id"; + miValueResult.Add(strCurrThreadId, m_miValueCurrThreadId); + } const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); m_miResultRecord = miRecordResult;