Index: cmake/platforms/Android.cmake =================================================================== --- cmake/platforms/Android.cmake +++ cmake/platforms/Android.cmake @@ -64,20 +64,25 @@ set( ANDROID_TOOLCHAIN_DIR "${ANDROID_TOOLCHAIN_DIR}" CACHE INTERNAL "Android standalone toolchain directory" FORCE ) set( ANDROID_SYSROOT "${ANDROID_TOOLCHAIN_DIR}/sysroot" CACHE INTERNAL "Android Sysroot" FORCE ) +# CMAKE_EXECUTABLE_SUFFIX is undefined in CMAKE_TOOLCHAIN_FILE +if( WIN32 ) + set( EXECUTABLE_SUFFIX ".exe" ) +endif() + # force python exe to be the one in Android toolchian -set( PYTHON_EXECUTABLE "${ANDROID_TOOLCHAIN_DIR}/bin/python" CACHE INTERNAL "Python exec path" FORCE ) +set( PYTHON_EXECUTABLE "${ANDROID_TOOLCHAIN_DIR}/bin/python${EXECUTABLE_SUFFIX}" CACHE INTERNAL "Python exec path" FORCE ) if( NOT CMAKE_C_COMPILER ) - set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-gcc" CACHE PATH "C compiler" ) - set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-g++" CACHE PATH "C++ compiler" ) - set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-gcc" CACHE PATH "assembler" ) - set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-strip" CACHE PATH "strip" ) - set( CMAKE_AR "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ar" CACHE PATH "archive" ) - set( CMAKE_LINKER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ld" CACHE PATH "linker" ) - set( CMAKE_NM "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-nm" CACHE PATH "nm" ) - set( CMAKE_OBJCOPY "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-objcopy" CACHE PATH "objcopy" ) - set( CMAKE_OBJDUMP "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-objdump" CACHE PATH "objdump" ) - set( CMAKE_RANLIB "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ranlib" CACHE PATH "ranlib" ) + set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-gcc${EXECUTABLE_SUFFIX}" CACHE PATH "C compiler" ) + set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-g++${EXECUTABLE_SUFFIX}" CACHE PATH "C++ compiler" ) + set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-gcc${EXECUTABLE_SUFFIX}" CACHE PATH "assembler" ) + set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-strip${EXECUTABLE_SUFFIX}" CACHE PATH "strip" ) + set( CMAKE_AR "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ar${EXECUTABLE_SUFFIX}" CACHE PATH "archive" ) + set( CMAKE_LINKER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ld${EXECUTABLE_SUFFIX}" CACHE PATH "linker" ) + set( CMAKE_NM "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-nm${EXECUTABLE_SUFFIX}" CACHE PATH "nm" ) + set( CMAKE_OBJCOPY "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-objcopy${EXECUTABLE_SUFFIX}" CACHE PATH "objcopy" ) + set( CMAKE_OBJDUMP "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-objdump${EXECUTABLE_SUFFIX}" CACHE PATH "objdump" ) + set( CMAKE_RANLIB "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ranlib${EXECUTABLE_SUFFIX}" CACHE PATH "ranlib" ) endif() set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT} -pie -fPIE -funwind-tables -fsigned-char -no-canonical-prefixes" ) Index: docs/lldb-for-gdb-users.txt =================================================================== --- docs/lldb-for-gdb-users.txt +++ docs/lldb-for-gdb-users.txt @@ -280,7 +280,7 @@ (lldb) thread until 100 -which runs the thread in the current frame till it reaches line 100 in +Which runs the thread in the current frame till it reaches line 100 in this frame or stops if it leaves the current frame. This is a pretty close equivalent to gdb's "until" command. Index: include/lldb/API/SBDefines.h =================================================================== --- include/lldb/API/SBDefines.h +++ include/lldb/API/SBDefines.h @@ -55,6 +55,7 @@ class LLDB_API SBHostOS; class LLDB_API SBInstruction; class LLDB_API SBInstructionList; +class LLDB_API SBLanguageRuntime; class LLDB_API SBLaunchInfo; class LLDB_API SBLineEntry; class LLDB_API SBListener; Index: include/lldb/API/SBLanguageRuntime.h =================================================================== --- /dev/null +++ include/lldb/API/SBLanguageRuntime.h @@ -0,0 +1,29 @@ +//===-- SBLanguageRuntime.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBLanguageRuntime_h_ +#define LLDB_SBLanguageRuntime_h_ + +#include "lldb/API/SBDefines.h" + +namespace lldb { + +class SBLanguageRuntime +{ +public: + static lldb::LanguageType + GetLanguageTypeFromString (const char *string); + + static const char * + GetNameForLanguageType (lldb::LanguageType language); +}; + +} // namespace lldb + +#endif // LLDB_SBLanguageRuntime_h_ Index: scripts/Python/build-swig-Python.sh =================================================================== --- scripts/Python/build-swig-Python.sh +++ scripts/Python/build-swig-Python.sh @@ -100,6 +100,7 @@ " ${SRC_ROOT}/include/lldb/API/SBHostOS.h"\ " ${SRC_ROOT}/include/lldb/API/SBInstruction.h"\ " ${SRC_ROOT}/include/lldb/API/SBInstructionList.h"\ +" ${SRC_ROOT}/include/lldb/API/SBLanguageRuntime.h"\ " ${SRC_ROOT}/include/lldb/API/SBLaunchInfo.h"\ " ${SRC_ROOT}/include/lldb/API/SBLineEntry.h"\ " ${SRC_ROOT}/include/lldb/API/SBListener.h"\ @@ -154,6 +155,7 @@ " ${SRC_ROOT}/scripts/interface/SBHostOS.i"\ " ${SRC_ROOT}/scripts/interface/SBInstruction.i"\ " ${SRC_ROOT}/scripts/interface/SBInstructionList.i"\ +" ${SRC_ROOT}/scripts/interface/SBLanguageRuntime.i"\ " ${SRC_ROOT}/scripts/interface/SBLaunchInfo.i"\ " ${SRC_ROOT}/scripts/interface/SBLineEntry.i"\ " ${SRC_ROOT}/scripts/interface/SBListener.i"\ Index: scripts/Python/buildSwigPython.py =================================================================== --- scripts/Python/buildSwigPython.py +++ scripts/Python/buildSwigPython.py @@ -97,6 +97,7 @@ "/include/lldb/API/SBInputReader.h", "/include/lldb/API/SBInstruction.h", "/include/lldb/API/SBInstructionList.h", + "/include/lldb/API/SBLanguageRuntime.h", "/include/lldb/API/SBLaunchInfo.h", "/include/lldb/API/SBLineEntry.h", "/include/lldb/API/SBListener.h", @@ -175,6 +176,7 @@ "/scripts/interface/SBInputReader.i", "/scripts/interface/SBInstruction.i", "/scripts/interface/SBInstructionList.i", + "/scripts/interface/SBLanguageRuntime.i", "/scripts/interface/SBLaunchInfo.i", "/scripts/interface/SBLineEntry.i", "/scripts/interface/SBListener.i", Index: scripts/interface/SBLanguageRuntime.i =================================================================== --- /dev/null +++ scripts/interface/SBLanguageRuntime.i @@ -0,0 +1,22 @@ +//===-- SWIG Interface for SBLanguageRuntime --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +class SBLanguageRuntime +{ +public: + static lldb::LanguageType + GetLanguageTypeFromString (const char *string); + + static const char * + GetNameForLanguageType (lldb::LanguageType language); +}; + +} // namespace lldb Index: scripts/lldb.swig =================================================================== --- scripts/lldb.swig +++ scripts/lldb.swig @@ -76,6 +76,7 @@ #include "lldb/API/SBHostOS.h" #include "lldb/API/SBInstruction.h" #include "lldb/API/SBInstructionList.h" +#include "lldb/API/SBLanguageRuntime.h" #include "lldb/API/SBLaunchInfo.h" #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBListener.h" @@ -153,6 +154,7 @@ %include "./interface/SBHostOS.i" %include "./interface/SBInstruction.i" %include "./interface/SBInstructionList.i" +%include "./interface/SBLanguageRuntime.i" %include "./interface/SBLaunchInfo.i" %include "./interface/SBLineEntry.i" %include "./interface/SBListener.i" Index: source/API/CMakeLists.txt =================================================================== --- source/API/CMakeLists.txt +++ source/API/CMakeLists.txt @@ -33,6 +33,7 @@ SBHostOS.cpp SBInstruction.cpp SBInstructionList.cpp + SBLanguageRuntime.cpp SBLaunchInfo.cpp SBLineEntry.cpp SBListener.cpp Index: source/API/SBLanguageRuntime.cpp =================================================================== --- /dev/null +++ source/API/SBLanguageRuntime.cpp @@ -0,0 +1,26 @@ +//===-- SBLanguageRuntime.cpp -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBLanguageRuntime.h" +#include "lldb/Target/LanguageRuntime.h" + +using namespace lldb; +using namespace lldb_private; + +lldb::LanguageType +SBLanguageRuntime::GetLanguageTypeFromString (const char *string) +{ + return LanguageRuntime::GetLanguageTypeFromString(string); +} + +const char * +SBLanguageRuntime::GetNameForLanguageType (lldb::LanguageType language) +{ + return LanguageRuntime::GetNameForLanguageType(language); +} Index: source/Core/Address.cpp =================================================================== --- source/Core/Address.cpp +++ source/Core/Address.cpp @@ -745,10 +745,15 @@ if (var && var->LocationIsValidForAddress (*this)) { s->Indent(); - s->Printf (" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\", type= \"%s\", location =", + s->Printf (" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"", var->GetID(), - var->GetName().GetCString(), - var->GetType()->GetName().GetCString()); + var->GetName().GetCString()); + Type *type = var->GetType(); + if (type) + s->Printf(", type = \"%s\"", type->GetName().GetCString()); + else + s->PutCString(", type = "); + s->PutCString(", location = "); var->DumpLocationForAddress(s, *this); s->PutCString(", decl = "); var->GetDeclaration().DumpStopContext(s, false); Index: source/Plugins/Process/Linux/NativeProcessLinux.h =================================================================== --- source/Plugins/Process/Linux/NativeProcessLinux.h +++ source/Plugins/Process/Linux/NativeProcessLinux.h @@ -263,6 +263,9 @@ MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status); void + WaitForNewThread(::pid_t tid); + + void MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid); void Index: source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -2239,6 +2239,75 @@ } void +NativeProcessLinux::WaitForNewThread(::pid_t tid) +{ + Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); + + NativeThreadProtocolSP new_thread_sp = GetThreadByID(tid); + + if (new_thread_sp) + { + // We are already tracking the thread - we got the event on the new thread (see + // MonitorSignal) before this one. We are done. + return; + } + + // The thread is not tracked yet, let's wait for it to appear. + int status = -1; + ::pid_t wait_pid; + do + { + if (log) + log->Printf ("NativeProcessLinux::%s() received thread creation event for tid %" PRIu32 ". tid not tracked yet, waiting for thread to appear...", __FUNCTION__, tid); + wait_pid = waitpid(tid, &status, __WALL); + } + while (wait_pid == -1 && errno == EINTR); + // Since we are waiting on a specific tid, this must be the creation event. But let's do + // some checks just in case. + if (wait_pid != tid) { + if (log) + log->Printf ("NativeProcessLinux::%s() waiting for tid %" PRIu32 " failed. Assuming the thread has disappeared in the meantime", __FUNCTION__, tid); + // The only way I know of this could happen is if the whole process was + // SIGKILLed in the mean time. In any case, we can't do anything about that now. + return; + } + if (WIFEXITED(status)) + { + if (log) + log->Printf ("NativeProcessLinux::%s() waiting for tid %" PRIu32 " returned an 'exited' event. Not tracking the thread.", __FUNCTION__, tid); + // Also a very improbable event. + return; + } + + siginfo_t info; + Error error = GetSignalInfo(tid, &info); + if (error.Fail()) + { + if (log) + log->Printf ("NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32 " failed. Assuming the thread has disappeared in the meantime.", __FUNCTION__, tid); + return; + } + + if (((info.si_pid != 0) || (info.si_code != SI_USER)) && log) + { + // We should be getting a thread creation signal here, but we received something + // else. There isn't much we can do about it now, so we will just log that. Since the + // thread is alive and we are receiving events from it, we shall pretend that it was + // created properly. + log->Printf ("NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32 " received unexpected signal with code %d from pid %d.", __FUNCTION__, tid, info.si_code, info.si_pid); + } + + if (log) + log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 ": tracking new thread tid %" PRIu32, + __FUNCTION__, GetID (), tid); + + new_thread_sp = AddThread(tid); + std::static_pointer_cast (new_thread_sp)->SetRunning (); + Resume (tid, LLDB_INVALID_SIGNAL_NUMBER); + m_coordinator_up->NotifyThreadCreate (tid, false, CoordinatorErrorHandler); +} + +void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid) { Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); @@ -2267,22 +2336,18 @@ case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)): { // This is the notification on the parent thread which informs us of new thread - // creation. We are not interested in these events at this point (an interesting use - // case would be to stop the process upon thread creation), so we just resume the thread. - // We will pickup the new thread when we get its SIGSTOP notification. + // creation. + // We don't want to do anything with the parent thread so we just resume it. In case we + // want to implement "break on thread creation" functionality, we would need to stop + // here. - if (log) + unsigned long event_message = 0; + if (GetEventMessage (pid, &event_message).Fail()) { - unsigned long event_message = 0; - if (GetEventMessage (pid, &event_message).Success()) - { - lldb::tid_t tid = static_cast (event_message); - log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event for tid %" PRIu64, __FUNCTION__, pid, tid); - - } - else + if (log) log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event but GetEventMessage failed so we don't know the new tid", __FUNCTION__, pid); - } + } else + WaitForNewThread(event_message); Resume (pid, LLDB_INVALID_SIGNAL_NUMBER); break; @@ -2603,8 +2668,10 @@ // Check for new thread notification. if ((info->si_pid == 0) && (info->si_code == SI_USER)) { - // A new thread creation is being signaled. This is one of two parts that come in - // a non-deterministic order. pid is the thread id. + // A new thread creation is being signaled. This is one of two parts that come in + // a non-deterministic order. This code handles the case where the new thread event comes + // before the event on the parent thread. For the opposite case see code in + // MonitorSIGTRAP. if (log) log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " tid %" PRIu64 ": new thread notification", __FUNCTION__, GetID (), pid); Index: test/functionalities/process_attach/TestProcessAttach.py =================================================================== --- test/functionalities/process_attach/TestProcessAttach.py +++ test/functionalities/process_attach/TestProcessAttach.py @@ -22,6 +22,7 @@ self.process_attach_by_id() @dwarf_test + @skipIfLinux # llvm.org/pr23360 def test_attach_to_process_by_id_with_dwarf(self): """Test attach by process id""" self.buildDwarf() @@ -35,6 +36,7 @@ self.process_attach_by_name() @dwarf_test + @skipIfLinux # llvm.org/pr23360 def test_attach_to_process_by_name_with_dwarf(self): """Test attach by process name""" self.buildDwarf() Index: test/tools/lldb-mi/TestMiGdbSetShow.py =================================================================== --- test/tools/lldb-mi/TestMiGdbSetShow.py +++ test/tools/lldb-mi/TestMiGdbSetShow.py @@ -98,6 +98,29 @@ @lldbmi_test @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows") + @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races + def test_lldbmi_gdb_show_language(self): + """Test that 'lldb-mi --interpreter' can get current language.""" + + 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\"") + + # Test that -gdb-show language gets current language + self.runCmd("-gdb-show language") + self.expect("\^done,value=\"c\+\+\"") + + @lldbmi_test + @expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows") @unittest2.expectedFailure("-gdb-set ignores unknown properties") def test_lldbmi_gdb_set_unknown(self): """Test that 'lldb-mi --interpreter' fails when setting an unknown property.""" Index: test/tools/lldb-mi/variable/TestMiVar.py =================================================================== --- test/tools/lldb-mi/variable/TestMiVar.py +++ test/tools/lldb-mi/variable/TestMiVar.py @@ -47,7 +47,7 @@ self.runCmd("-var-show-attributes var2") self.expect("\^done,status=\"editable\"") self.runCmd("-var-list-children var2") - self.expect("\^done,numchild=\"0\",children=\"\[\]\"") + self.expect("\^done,numchild=\"0\"") self.runCmd("-data-evaluate-expression \"g_MyVar=30\"") self.expect("\^done,value=\"30\"") self.runCmd("-var-update --all-values var2") @@ -67,7 +67,7 @@ self.runCmd("-var-show-attributes var3") self.expect("\^done,status=\"editable\"") self.runCmd("-var-list-children var3") - self.expect("\^done,numchild=\"0\",children=\"\[\]\"") + self.expect("\^done,numchild=\"0\"") self.runCmd("-data-evaluate-expression \"s_MyVar=3\"") self.expect("\^done,value=\"3\"") self.runCmd("-var-update --all-values var3") @@ -87,7 +87,7 @@ self.runCmd("-var-show-attributes var4") self.expect("\^done,status=\"editable\"") self.runCmd("-var-list-children var4") - self.expect("\^done,numchild=\"0\",children=\"\[\]\"") + self.expect("\^done,numchild=\"0\"") self.runCmd("-data-evaluate-expression \"b=2\"") self.expect("\^done,value=\"2\"") self.runCmd("-var-update --all-values var4") @@ -107,7 +107,7 @@ self.runCmd("-var-show-attributes var5") self.expect("\^done,status=\"editable\"") #FIXME editable or not? self.runCmd("-var-list-children var5") - self.expect("\^done,numchild=\"0\",children=\"\[\]\"") + self.expect("\^done,numchild=\"0\"") # Print argument "argv[0]" self.runCmd("-data-evaluate-expression \"argv[0]\"") Index: tools/lldb-mi/MICmdCmdGdbShow.h =================================================================== --- tools/lldb-mi/MICmdCmdGdbShow.h +++ tools/lldb-mi/MICmdCmdGdbShow.h @@ -68,6 +68,7 @@ bool GetOptionFn(const CMIUtilString &vrGdbOptionName, FnGdbOptionPtr &vrwpFn) const; bool OptionFnTargetAsync(const CMIUtilString::VecString_t &vrWords); bool OptionFnPrint(const CMIUtilString::VecString_t &vrWords); + bool OptionFnLanguage(const CMIUtilString::VecString_t &vrWords); bool OptionFnFallback(const CMIUtilString::VecString_t &vrWords); // Attributes: Index: tools/lldb-mi/MICmdCmdGdbShow.cpp =================================================================== --- tools/lldb-mi/MICmdCmdGdbShow.cpp +++ tools/lldb-mi/MICmdCmdGdbShow.cpp @@ -9,6 +9,12 @@ // Overview: CMICmdCmdGdbShow implementation. +// Third party headers: +#include "lldb/API/SBCompileUnit.h" +#include "lldb/API/SBFrame.h" +#include "lldb/API/SBLanguageRuntime.h" +#include "lldb/API/SBThread.h" + // In-house headers: #include "MICmdCmdGdbShow.h" #include "MICmnMIResultRecord.h" @@ -22,6 +28,7 @@ const CMICmdCmdGdbShow::MapGdbOptionNameToFnGdbOptionPtr_t CMICmdCmdGdbShow::ms_mapGdbOptionNameToFnGdbOptionPtr = { {"target-async", &CMICmdCmdGdbShow::OptionFnTargetAsync}, {"print", &CMICmdCmdGdbShow::OptionFnPrint}, + {"language", &CMICmdCmdGdbShow::OptionFnLanguage}, {"fallback", &CMICmdCmdGdbShow::OptionFnFallback}}; //++ ------------------------------------------------------------------------------------ @@ -287,6 +294,31 @@ } //++ ------------------------------------------------------------------------------------ +// Details: Carry out work to complete the GDB show option 'language' to prepare +// and send back the requested information. +// Type: Method. +// Args: vrWords - (R) List of additional parameters used by this option. +// Return: MIstatus::success - Function succeeded. +// MIstatus::failure - Function failed. +// Throws: None. +//-- +bool +CMICmdCmdGdbShow::OptionFnLanguage(const CMIUtilString::VecString_t &vrWords) +{ + MIunused(vrWords); + + // Get current language + CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); + lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread(); + const lldb::SBFrame sbFrame = sbThread.GetSelectedFrame(); + lldb::SBCompileUnit sbCompileUnit = sbFrame.GetCompileUnit(); + const lldb::LanguageType eLanguageType = sbCompileUnit.GetLanguage(); + + m_strValue = lldb::SBLanguageRuntime::GetNameForLanguageType(eLanguageType); + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ // Details: Carry out work to complete the GDB show option to prepare and send back the // requested information. // Type: Method. Index: tools/lldb-mi/MICmdCmdVar.cpp =================================================================== --- tools/lldb-mi/MICmdCmdVar.cpp +++ tools/lldb-mi/MICmdCmdVar.cpp @@ -1099,12 +1099,7 @@ CMICmnMIValueResult miValueResult("numchild", miValueConst); VecMIValueResult_t::const_iterator it = m_vecMiValueResult.begin(); - if (it == m_vecMiValueResult.end()) - { - const CMICmnMIValueConst miValueConst("[]"); - miValueResult.Add("children", miValueConst); - } - else + if (it != m_vecMiValueResult.end()) { CMICmnMIValueList miValueList(*it); ++it; Index: tools/lldb-mi/MIUtilString.cpp =================================================================== --- tools/lldb-mi/MIUtilString.cpp +++ tools/lldb-mi/MIUtilString.cpp @@ -17,6 +17,7 @@ // In-house headers: #include "MIUtilString.h" +#include "Platform.h" //++ ------------------------------------------------------------------------------------ // Details: CMIUtilString constructor. @@ -844,8 +845,9 @@ strNew.push_back(cUnescapedChar); else { - char strEscapedChar[sizeof("\\xXX")]; - ::sprintf(strEscapedChar, "\\x%02" PRIx8, cUnescapedChar); + const size_t size = sizeof("\\xXX"); + char strEscapedChar[size]; + ::snprintf(strEscapedChar, size, "\\x%02" PRIx8, cUnescapedChar); strNew.append(strEscapedChar); } break;