aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2015-07-03 16:57:06 +0000
committerEd Maste <emaste@FreeBSD.org>2015-07-03 16:57:06 +0000
commit5e95aa85bb660d45e9905ef1d7180b2678280660 (patch)
tree3c2e41c3be19b7fc7666ed45a5f91ec3b6e35f2a /tools
parent12bd4897ff0678fa663e09d78ebc22dd255ceb86 (diff)
downloadsrc-5e95aa85bb660d45e9905ef1d7180b2678280660.tar.gz
src-5e95aa85bb660d45e9905ef1d7180b2678280660.zip
Import LLDB as of upstream SVN 241361 (git 612c075f)vendor/lldb/lldb-r241361
Notes
Notes: svn path=/vendor/lldb/dist/; revision=285101 svn path=/vendor/lldb/lldb-r241361/; revision=285102; tag=vendor/lldb/lldb-r241361
Diffstat (limited to 'tools')
-rw-r--r--tools/argdumper/argdumper.cpp38
-rw-r--r--tools/argdumper/exports (renamed from tools/lldb-platform/exports)0
-rw-r--r--tools/compact-unwind/compact-unwind-dumper.c2
-rw-r--r--tools/driver/Driver.cpp43
-rw-r--r--tools/driver/Platform.h15
-rw-r--r--tools/lldb-mi/Driver.cpp1276
-rw-r--r--tools/lldb-mi/Driver.h144
-rw-r--r--tools/lldb-mi/MICmdArgContext.cpp42
-rw-r--r--tools/lldb-mi/MICmdArgContext.h14
-rw-r--r--tools/lldb-mi/MICmdArgSet.cpp35
-rw-r--r--tools/lldb-mi/MICmdArgSet.h12
-rw-r--r--tools/lldb-mi/MICmdArgValBase.cpp12
-rw-r--r--tools/lldb-mi/MICmdArgValBase.h14
-rw-r--r--tools/lldb-mi/MICmdArgValConsume.cpp24
-rw-r--r--tools/lldb-mi/MICmdArgValConsume.h12
-rw-r--r--tools/lldb-mi/MICmdArgValFile.cpp29
-rw-r--r--tools/lldb-mi/MICmdArgValFile.h12
-rw-r--r--tools/lldb-mi/MICmdArgValListBase.cpp12
-rw-r--r--tools/lldb-mi/MICmdArgValListBase.h12
-rw-r--r--tools/lldb-mi/MICmdArgValListOfN.cpp14
-rw-r--r--tools/lldb-mi/MICmdArgValListOfN.h22
-rw-r--r--tools/lldb-mi/MICmdArgValNumber.cpp41
-rw-r--r--tools/lldb-mi/MICmdArgValNumber.h29
-rw-r--r--tools/lldb-mi/MICmdArgValOptionLong.cpp16
-rw-r--r--tools/lldb-mi/MICmdArgValOptionLong.h12
-rw-r--r--tools/lldb-mi/MICmdArgValOptionShort.cpp12
-rw-r--r--tools/lldb-mi/MICmdArgValOptionShort.h12
-rw-r--r--tools/lldb-mi/MICmdArgValPrintValues.cpp129
-rw-r--r--tools/lldb-mi/MICmdArgValPrintValues.h53
-rw-r--r--tools/lldb-mi/MICmdArgValString.cpp238
-rw-r--r--tools/lldb-mi/MICmdArgValString.h14
-rw-r--r--tools/lldb-mi/MICmdArgValThreadGrp.cpp14
-rw-r--r--tools/lldb-mi/MICmdArgValThreadGrp.h12
-rw-r--r--tools/lldb-mi/MICmdBase.cpp12
-rw-r--r--tools/lldb-mi/MICmdBase.h12
-rw-r--r--tools/lldb-mi/MICmdCmd.cpp10
-rw-r--r--tools/lldb-mi/MICmdCmd.h10
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.cpp49
-rw-r--r--tools/lldb-mi/MICmdCmdBreak.h10
-rw-r--r--tools/lldb-mi/MICmdCmdData.cpp390
-rw-r--r--tools/lldb-mi/MICmdCmdData.h58
-rw-r--r--tools/lldb-mi/MICmdCmdEnviro.cpp10
-rw-r--r--tools/lldb-mi/MICmdCmdEnviro.h10
-rw-r--r--tools/lldb-mi/MICmdCmdExec.cpp245
-rw-r--r--tools/lldb-mi/MICmdCmdExec.h68
-rw-r--r--tools/lldb-mi/MICmdCmdFile.cpp44
-rw-r--r--tools/lldb-mi/MICmdCmdFile.h15
-rw-r--r--tools/lldb-mi/MICmdCmdGdbInfo.cpp15
-rw-r--r--tools/lldb-mi/MICmdCmdGdbInfo.h10
-rw-r--r--tools/lldb-mi/MICmdCmdGdbSet.cpp180
-rw-r--r--tools/lldb-mi/MICmdCmdGdbSet.h17
-rw-r--r--tools/lldb-mi/MICmdCmdGdbShow.cpp340
-rw-r--r--tools/lldb-mi/MICmdCmdGdbShow.h86
-rw-r--r--tools/lldb-mi/MICmdCmdGdbThread.cpp10
-rw-r--r--tools/lldb-mi/MICmdCmdGdbThread.h10
-rw-r--r--tools/lldb-mi/MICmdCmdMiscellanous.cpp27
-rw-r--r--tools/lldb-mi/MICmdCmdMiscellanous.h10
-rw-r--r--tools/lldb-mi/MICmdCmdStack.cpp501
-rw-r--r--tools/lldb-mi/MICmdCmdStack.h113
-rw-r--r--tools/lldb-mi/MICmdCmdSupportInfo.cpp10
-rw-r--r--tools/lldb-mi/MICmdCmdSupportInfo.h10
-rw-r--r--tools/lldb-mi/MICmdCmdSupportList.cpp10
-rw-r--r--tools/lldb-mi/MICmdCmdSupportList.h10
-rw-r--r--tools/lldb-mi/MICmdCmdSymbol.cpp173
-rw-r--r--tools/lldb-mi/MICmdCmdSymbol.h57
-rw-r--r--tools/lldb-mi/MICmdCmdTarget.cpp275
-rw-r--r--tools/lldb-mi/MICmdCmdTarget.h69
-rw-r--r--tools/lldb-mi/MICmdCmdThread.cpp20
-rw-r--r--tools/lldb-mi/MICmdCmdThread.h10
-rw-r--r--tools/lldb-mi/MICmdCmdTrace.cpp10
-rw-r--r--tools/lldb-mi/MICmdCmdTrace.h10
-rw-r--r--tools/lldb-mi/MICmdCmdVar.cpp425
-rw-r--r--tools/lldb-mi/MICmdCmdVar.h45
-rw-r--r--tools/lldb-mi/MICmdCommands.cpp22
-rw-r--r--tools/lldb-mi/MICmdCommands.h12
-rw-r--r--tools/lldb-mi/MICmdData.cpp12
-rw-r--r--tools/lldb-mi/MICmdData.h12
-rw-r--r--tools/lldb-mi/MICmdFactory.cpp16
-rw-r--r--tools/lldb-mi/MICmdFactory.h12
-rw-r--r--tools/lldb-mi/MICmdInterpreter.cpp42
-rw-r--r--tools/lldb-mi/MICmdInterpreter.h14
-rw-r--r--tools/lldb-mi/MICmdInvoker.cpp12
-rw-r--r--tools/lldb-mi/MICmdInvoker.h12
-rw-r--r--tools/lldb-mi/MICmdMgr.cpp12
-rw-r--r--tools/lldb-mi/MICmdMgr.h12
-rw-r--r--tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp12
-rw-r--r--tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h12
-rw-r--r--tools/lldb-mi/MICmnBase.cpp12
-rw-r--r--tools/lldb-mi/MICmnBase.h12
-rw-r--r--tools/lldb-mi/MICmnConfig.h32
-rw-r--r--tools/lldb-mi/MICmnLLDBBroadcaster.cpp12
-rw-r--r--tools/lldb-mi/MICmnLLDBBroadcaster.h12
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp913
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfo.h78
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp92
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h23
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.cpp144
-rw-r--r--tools/lldb-mi/MICmnLLDBDebugger.h21
-rw-r--r--tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp777
-rw-r--r--tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h36
-rw-r--r--tools/lldb-mi/MICmnLLDBProxySBValue.cpp20
-rw-r--r--tools/lldb-mi/MICmnLLDBProxySBValue.h12
-rw-r--r--tools/lldb-mi/MICmnLLDBUtilSBValue.cpp430
-rw-r--r--tools/lldb-mi/MICmnLLDBUtilSBValue.h40
-rw-r--r--tools/lldb-mi/MICmnLog.cpp12
-rw-r--r--tools/lldb-mi/MICmnLog.h12
-rw-r--r--tools/lldb-mi/MICmnLogMediumFile.cpp75
-rw-r--r--tools/lldb-mi/MICmnLogMediumFile.h19
-rw-r--r--tools/lldb-mi/MICmnMIOutOfBandRecord.cpp52
-rw-r--r--tools/lldb-mi/MICmnMIOutOfBandRecord.h21
-rw-r--r--tools/lldb-mi/MICmnMIResultRecord.cpp14
-rw-r--r--tools/lldb-mi/MICmnMIResultRecord.h12
-rw-r--r--tools/lldb-mi/MICmnMIValue.cpp12
-rw-r--r--tools/lldb-mi/MICmnMIValue.h12
-rw-r--r--tools/lldb-mi/MICmnMIValueConst.cpp16
-rw-r--r--tools/lldb-mi/MICmnMIValueConst.h12
-rw-r--r--tools/lldb-mi/MICmnMIValueList.cpp25
-rw-r--r--tools/lldb-mi/MICmnMIValueList.h12
-rw-r--r--tools/lldb-mi/MICmnMIValueResult.cpp18
-rw-r--r--tools/lldb-mi/MICmnMIValueResult.h14
-rw-r--r--tools/lldb-mi/MICmnMIValueTuple.cpp24
-rw-r--r--tools/lldb-mi/MICmnMIValueTuple.h14
-rw-r--r--tools/lldb-mi/MICmnResources.cpp64
-rw-r--r--tools/lldb-mi/MICmnResources.h44
-rw-r--r--tools/lldb-mi/MICmnStreamStderr.cpp12
-rw-r--r--tools/lldb-mi/MICmnStreamStderr.h12
-rw-r--r--tools/lldb-mi/MICmnStreamStdin.cpp302
-rw-r--r--tools/lldb-mi/MICmnStreamStdin.h72
-rw-r--r--tools/lldb-mi/MICmnStreamStdinLinux.cpp225
-rw-r--r--tools/lldb-mi/MICmnStreamStdinLinux.h72
-rw-r--r--tools/lldb-mi/MICmnStreamStdinWindows.cpp285
-rw-r--r--tools/lldb-mi/MICmnStreamStdinWindows.h79
-rw-r--r--tools/lldb-mi/MICmnStreamStdout.cpp40
-rw-r--r--tools/lldb-mi/MICmnStreamStdout.h13
-rw-r--r--tools/lldb-mi/MICmnThreadMgrStd.cpp12
-rw-r--r--tools/lldb-mi/MICmnThreadMgrStd.h12
-rw-r--r--tools/lldb-mi/MIDataTypes.h13
-rw-r--r--tools/lldb-mi/MIDriver.cpp503
-rw-r--r--tools/lldb-mi/MIDriver.h33
-rw-r--r--tools/lldb-mi/MIDriverBase.cpp12
-rw-r--r--tools/lldb-mi/MIDriverBase.h12
-rw-r--r--tools/lldb-mi/MIDriverMain.cpp235
-rw-r--r--tools/lldb-mi/MIDriverMgr.cpp116
-rw-r--r--tools/lldb-mi/MIDriverMgr.h16
-rw-r--r--tools/lldb-mi/MIExtensions.txt103
-rw-r--r--tools/lldb-mi/MIReadMe.txt254
-rw-r--r--tools/lldb-mi/MIUtilDateTimeStd.cpp30
-rw-r--r--tools/lldb-mi/MIUtilDateTimeStd.h15
-rw-r--r--tools/lldb-mi/MIUtilDebug.cpp12
-rw-r--r--tools/lldb-mi/MIUtilDebug.h12
-rw-r--r--tools/lldb-mi/MIUtilFileStd.cpp28
-rw-r--r--tools/lldb-mi/MIUtilFileStd.h18
-rw-r--r--tools/lldb-mi/MIUtilMapIdToVariant.cpp12
-rw-r--r--tools/lldb-mi/MIUtilMapIdToVariant.h12
-rw-r--r--tools/lldb-mi/MIUtilSingletonBase.h12
-rw-r--r--tools/lldb-mi/MIUtilSingletonHelper.h12
-rw-r--r--tools/lldb-mi/MIUtilString.cpp583
-rw-r--r--tools/lldb-mi/MIUtilString.h44
-rw-r--r--tools/lldb-mi/MIUtilSystemLinux.cpp14
-rw-r--r--tools/lldb-mi/MIUtilSystemLinux.h14
-rw-r--r--tools/lldb-mi/MIUtilSystemOsx.cpp12
-rw-r--r--tools/lldb-mi/MIUtilSystemOsx.h12
-rw-r--r--tools/lldb-mi/MIUtilSystemWindows.cpp26
-rw-r--r--tools/lldb-mi/MIUtilSystemWindows.h12
-rw-r--r--tools/lldb-mi/MIUtilTermios.cpp71
-rw-r--r--tools/lldb-mi/MIUtilTermios.h30
-rw-r--r--tools/lldb-mi/MIUtilThreadBaseStd.cpp43
-rw-r--r--tools/lldb-mi/MIUtilThreadBaseStd.h15
-rw-r--r--tools/lldb-mi/MIUtilVariant.cpp12
-rw-r--r--tools/lldb-mi/MIUtilVariant.h12
-rw-r--r--tools/lldb-mi/Platform.cpp61
-rw-r--r--tools/lldb-mi/Platform.h8
-rw-r--r--tools/lldb-server/LLDBServerUtilities.cpp67
-rw-r--r--tools/lldb-server/LLDBServerUtilities.h25
-rw-r--r--tools/lldb-server/exports0
-rw-r--r--tools/lldb-server/lldb-gdbserver.cpp698
-rw-r--r--tools/lldb-server/lldb-platform.cpp (renamed from tools/lldb-platform/lldb-platform.cpp)192
-rw-r--r--tools/lldb-server/lldb-server.cpp76
178 files changed, 6353 insertions, 7396 deletions
diff --git a/tools/argdumper/argdumper.cpp b/tools/argdumper/argdumper.cpp
new file mode 100644
index 000000000000..381a9d2f4b22
--- /dev/null
+++ b/tools/argdumper/argdumper.cpp
@@ -0,0 +1,38 @@
+//===-- argdumper.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/Core/StreamString.h"
+#include "lldb/Utility/JSON.h"
+
+#include <iostream>
+
+using namespace lldb_private;
+
+int
+main (int argc, char *argv[])
+{
+ JSONArray::SP arguments(new JSONArray());
+ for (int i = 1;
+ i < argc;
+ i++)
+ {
+ arguments->AppendObject(JSONString::SP(new JSONString(argv[i])));
+ }
+
+ JSONObject::SP object(new JSONObject());
+ object->SetObject("arguments", arguments);
+
+ StreamString ss;
+
+ object->Write(ss);
+
+ std::cout << ss.GetData() << std::endl;
+
+ return 0;
+}
diff --git a/tools/lldb-platform/exports b/tools/argdumper/exports
index e69de29bb2d1..e69de29bb2d1 100644
--- a/tools/lldb-platform/exports
+++ b/tools/argdumper/exports
diff --git a/tools/compact-unwind/compact-unwind-dumper.c b/tools/compact-unwind/compact-unwind-dumper.c
index 0f898dbc76b4..d6bd72d93027 100644
--- a/tools/compact-unwind/compact-unwind-dumper.c
+++ b/tools/compact-unwind/compact-unwind-dumper.c
@@ -1051,7 +1051,7 @@ print_second_level_index_regular (struct baton baton)
// UNWIND_SECOND_LEVEL_REGULAR entries have a funcOffset which includes the
// functionOffset from the containing index table already. UNWIND_SECOND_LEVEL_COMPRESSED
// entries only have the offset from the containing index table functionOffset.
- // So strip off the contianing index table functionOffset value here so they can
+ // So strip off the containing index table functionOffset value here so they can
// be treated the same at the lower layers.
print_function_encoding (baton, idx, encoding, (uint32_t) -1, func_offset - baton.first_level_index_entry.functionOffset);
diff --git a/tools/driver/Driver.cpp b/tools/driver/Driver.cpp
index f02b081b8f0f..91b92d25f434 100644
--- a/tools/driver/Driver.cpp
+++ b/tools/driver/Driver.cpp
@@ -51,7 +51,6 @@ static void reset_stdin_termios ();
static bool g_old_stdin_termios_is_valid = false;
static struct termios g_old_stdin_termios;
-static char *g_debugger_name = (char *) "";
static Driver *g_driver = NULL;
// In the Driver::MainLoop, we change the terminal settings. This function is
@@ -146,16 +145,12 @@ Driver::Driver () :
// We want to be able to handle CTRL+D in the terminal to have it terminate
// certain input
m_debugger.SetCloseInputOnEOF (false);
- g_debugger_name = (char *) m_debugger.GetInstanceName();
- if (g_debugger_name == NULL)
- g_debugger_name = (char *) "";
g_driver = this;
}
Driver::~Driver ()
{
g_driver = NULL;
- g_debugger_name = NULL;
}
@@ -872,7 +867,6 @@ PrepareCommandsForSourcing (const char *commands_data, size_t commands_size, int
{
enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
- bool success = true;
::FILE *commands_file = NULL;
fds[0] = -1;
fds[1] = -1;
@@ -887,10 +881,9 @@ PrepareCommandsForSourcing (const char *commands_data, size_t commands_size, int
ssize_t nrwr = write(fds[WRITE], commands_data, commands_size);
if (nrwr < 0)
{
- fprintf(stderr, "error: write(%i, %p, %zd) failed (errno = %i) "
+ fprintf(stderr, "error: write(%i, %p, %" PRIu64 ") failed (errno = %i) "
"when trying to open LLDB commands pipe\n",
- fds[WRITE], commands_data, commands_size, errno);
- success = false;
+ fds[WRITE], commands_data, static_cast<uint64_t>(commands_size), errno);
}
else if (static_cast<size_t>(nrwr) == commands_size)
{
@@ -916,14 +909,12 @@ PrepareCommandsForSourcing (const char *commands_data, size_t commands_size, int
"error: fdopen(%i, \"r\") failed (errno = %i) when "
"trying to open LLDB commands pipe\n",
fds[READ], errno);
- success = false;
}
}
}
else
{
fprintf(stderr, "error: can't create pipe file descriptors for LLDB commands\n");
- success = false;
}
return commands_file;
@@ -956,6 +947,18 @@ CleanupAfterCommandSourcing (int fds[2])
}
+std::string
+EscapeString (std::string arg)
+{
+ std::string::size_type pos = 0;
+ while ((pos = arg.find_first_of("\"\\", pos)) != std::string::npos)
+ {
+ arg.insert (pos, 1, '\\');
+ pos += 2;
+ }
+ return '"' + arg + '"';
+}
+
void
Driver::MainLoop ()
{
@@ -1005,13 +1008,13 @@ Driver::MainLoop ()
{
char arch_name[64];
if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
- commands_stream.Printf("target create --arch=%s \"%s\"", arch_name, m_option_data.m_args[0].c_str());
+ commands_stream.Printf("target create --arch=%s %s", arch_name, EscapeString(m_option_data.m_args[0]).c_str());
else
- commands_stream.Printf("target create \"%s\"", m_option_data.m_args[0].c_str());
+ commands_stream.Printf("target create %s", EscapeString(m_option_data.m_args[0]).c_str());
if (!m_option_data.m_core_file.empty())
{
- commands_stream.Printf(" --core \"%s\"", m_option_data.m_core_file.c_str());
+ commands_stream.Printf(" --core %s", EscapeString(m_option_data.m_core_file).c_str());
}
commands_stream.Printf("\n");
@@ -1019,23 +1022,17 @@ Driver::MainLoop ()
{
commands_stream.Printf ("settings set -- target.run-args ");
for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
- {
- const char *arg_cstr = m_option_data.m_args[arg_idx].c_str();
- if (strchr(arg_cstr, '"') == NULL)
- commands_stream.Printf(" \"%s\"", arg_cstr);
- else
- commands_stream.Printf(" '%s'", arg_cstr);
- }
+ commands_stream.Printf(" %s", EscapeString(m_option_data.m_args[arg_idx]).c_str());
commands_stream.Printf("\n");
}
}
else if (!m_option_data.m_core_file.empty())
{
- commands_stream.Printf("target create --core \"%s\"\n", m_option_data.m_core_file.c_str());
+ commands_stream.Printf("target create --core %s\n", EscapeString(m_option_data.m_core_file).c_str());
}
else if (!m_option_data.m_process_name.empty())
{
- commands_stream.Printf ("process attach --name \"%s\"", m_option_data.m_process_name.c_str());
+ commands_stream.Printf ("process attach --name %s", EscapeString(m_option_data.m_process_name).c_str());
if (m_option_data.m_wait_for)
commands_stream.Printf(" --waitfor");
diff --git a/tools/driver/Platform.h b/tools/driver/Platform.h
index 8995512a0f8f..c42d7e3da9d4 100644
--- a/tools/driver/Platform.h
+++ b/tools/driver/Platform.h
@@ -10,12 +10,11 @@
#ifndef lldb_Platform_h_
#define lldb_Platform_h_
-#include "lldb/Host/HostGetOpt.h"
-
#if defined( _WIN32 )
// this will stop signal.h being included
#define _INC_SIGNAL
+ #include "lldb/Host/HostGetOpt.h"
#include <io.h>
#if defined( _MSC_VER )
#include <eh.h>
@@ -93,7 +92,7 @@
extern int tcgetattr( int fildes, struct termios *termios_p );
#else
-
+ #include "lldb/Host/HostGetOpt.h"
#include <inttypes.h>
#include <libgen.h>
@@ -103,16 +102,6 @@
#include <pthread.h>
#include <sys/time.h>
-
-#if !defined(__ANDROID_NDK__)
- #include <histedit.h>
- #if defined(__FreeBSD__) || defined(__NetBSD__)
- #include <readline/readline.h>
- #else
- #include <editline/readline.h>
- #endif
-#endif
-
#endif
#endif // lldb_Platform_h_
diff --git a/tools/lldb-mi/Driver.cpp b/tools/lldb-mi/Driver.cpp
deleted file mode 100644
index 2a907636723b..000000000000
--- a/tools/lldb-mi/Driver.cpp
+++ /dev/null
@@ -1,1276 +0,0 @@
-//===-- Driver.cpp ----------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnConfig.h"
-
-#if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
-
-#ifndef _MSC_VER
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <string>
-#endif // _MSC_VER
-
-#include "Platform.h" // CODETAG_IOR_SIGNALS
-#include "Driver.h"
-
-#ifdef _MSC_VER
-#include <lldb\Host\windows\getopt\GetOptInc.h>
-#endif // _MSC_VER
-#include "lldb/API/SBBreakpoint.h"
-#include "lldb/API/SBCommandInterpreter.h"
-#include "lldb/API/SBCommandReturnObject.h"
-#include "lldb/API/SBCommunication.h"
-#include "lldb/API/SBEvent.h"
-#include "lldb/API/SBHostOS.h"
-#include "lldb/API/SBListener.h"
-#include "lldb/API/SBStream.h"
-#include "lldb/API/SBTarget.h"
-#include "lldb/API/SBThread.h"
-#include "lldb/API/SBProcess.h"
-
-using namespace lldb;
-
-static void reset_stdin_termios();
-static bool g_old_stdin_termios_is_valid = false;
-static struct termios g_old_stdin_termios;
-
-static char *g_debugger_name = (char *)"";
-Driver *g_driver = NULL;
-
-// In the Driver::MainLoop, we change the terminal settings. This function is
-// added as an atexit handler to make sure we clean them up.
-static void
-reset_stdin_termios()
-{
- if (g_old_stdin_termios_is_valid)
- {
- g_old_stdin_termios_is_valid = false;
- ::tcsetattr(STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
- }
-}
-
-typedef struct
-{
- uint32_t usage_mask; // Used to mark options that can be used together. If (1 << n & usage_mask) != 0
- // then this option belongs to option set n.
- bool required; // This option is required (in the current usage level)
- const char *long_option; // Full name for this option.
- int short_option; // Single character for this option.
- int option_has_arg; // no_argument, required_argument or optional_argument
- uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
- lldb::CommandArgumentType argument_type; // Type of argument this option takes
- const char *usage_text; // Full text explaining what this options does and what (if any) argument to
- // pass it.
-} OptionDefinition;
-
-#define LLDB_3_TO_5 LLDB_OPT_SET_3 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5
-#define LLDB_4_TO_5 LLDB_OPT_SET_4 | LLDB_OPT_SET_5
-
-static OptionDefinition g_options[] = {
- {LLDB_OPT_SET_1, true, "help", 'h', no_argument, 0, eArgTypeNone, "Prints out the usage information for the LLDB debugger."},
- {LLDB_OPT_SET_2, true, "version", 'v', no_argument, 0, eArgTypeNone, "Prints out the current version number of the LLDB debugger."},
- {LLDB_OPT_SET_3, true, "arch", 'a', required_argument, 0, eArgTypeArchitecture,
- "Tells the debugger to use the specified architecture when starting and running the program. <architecture> must "
- "be one of the architectures for which the program was compiled."},
- {LLDB_OPT_SET_3, true, "file", 'f', required_argument, 0, eArgTypeFilename,
- "Tells the debugger to use the file <filename> as the program to be debugged."},
- {LLDB_OPT_SET_3, false, "core", 'c', required_argument, 0, eArgTypeFilename,
- "Tells the debugger to use the fullpath to <path> as the core file."},
- {LLDB_OPT_SET_5, true, "attach-pid", 'p', required_argument, 0, eArgTypePid,
- "Tells the debugger to attach to a process with the given pid."},
- {LLDB_OPT_SET_4, true, "attach-name", 'n', required_argument, 0, eArgTypeProcessName,
- "Tells the debugger to attach to a process with the given name."},
- {LLDB_OPT_SET_4, true, "wait-for", 'w', no_argument, 0, eArgTypeNone,
- "Tells the debugger to wait for a process with the given pid or name to launch before attaching."},
- {LLDB_3_TO_5, false, "source", 's', required_argument, 0, eArgTypeFilename, "Tells the debugger to read in and execute the lldb "
- "commands in the given file, after any file provided on "
- "the command line has been loaded."},
- {LLDB_3_TO_5, false, "one-line", 'o', required_argument, 0, eArgTypeNone,
- "Tells the debugger to execute this one-line lldb command after any file provided on the command line has been loaded."},
- {LLDB_3_TO_5, false, "source-before-file", 'S', required_argument, 0, eArgTypeFilename,
- "Tells the debugger to read in and execute the lldb commands in the given file, before any file provided on the command line has been "
- "loaded."},
- {LLDB_3_TO_5, false, "one-line-before-file", 'O', required_argument, 0, eArgTypeNone,
- "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded."},
- {LLDB_3_TO_5, false, "source-quietly", 'Q', no_argument, 0, eArgTypeNone,
- "Tells the debugger suppress output from commands provided in the -s, -S, -O and -o commands."},
- {LLDB_3_TO_5, false, "editor", 'e', no_argument, 0, eArgTypeNone,
- "Tells the debugger to open source files using the host's \"external editor\" mechanism."},
- {LLDB_3_TO_5, false, "no-lldbinit", 'x', no_argument, 0, eArgTypeNone, "Do not automatically parse any '.lldbinit' files."},
- {LLDB_3_TO_5, false, "no-use-colors", 'X', no_argument, 0, eArgTypeNone, "Do not use colors."},
- {LLDB_OPT_SET_6, true, "python-path", 'P', no_argument, 0, eArgTypeNone,
- "Prints out the path to the lldb.py file for this version of lldb."},
- {LLDB_3_TO_5, false, "script-language", 'l', required_argument, 0, eArgTypeScriptLang,
- "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default. "
- "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl. Currently only the Python "
- "extensions have been implemented."},
- {LLDB_3_TO_5, false, "debug", 'd', no_argument, 0, eArgTypeNone,
- "Tells the debugger to print out extra information for debugging itself."},
- {0, false, NULL, 0, 0, 0, eArgTypeNone, NULL}};
-
-static const uint32_t last_option_set_with_args = 2;
-
-Driver::Driver()
- : SBBroadcaster("Driver")
- , m_debugger(SBDebugger::Create(false))
- , m_option_data()
-{
- // We want to be able to handle CTRL+D in the terminal to have it terminate
- // certain input
- m_debugger.SetCloseInputOnEOF(false);
- g_debugger_name = (char *)m_debugger.GetInstanceName();
- if (g_debugger_name == NULL)
- g_debugger_name = (char *)"";
- g_driver = this;
-}
-
-Driver::~Driver()
-{
- g_driver = NULL;
- g_debugger_name = NULL;
-}
-
-// This function takes INDENT, which tells how many spaces to output at the front
-// of each line; TEXT, which is the text that is to be output. It outputs the
-// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
-// front of each line. It breaks lines on spaces, tabs or newlines, shortening
-// the line if necessary to not break in the middle of a word. It assumes that
-// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
-
-void
-OutputFormattedUsageText(FILE *out, int indent, const char *text, int output_max_columns)
-{
- int len = strlen(text);
- std::string text_string(text);
-
- // Force indentation to be reasonable.
- if (indent >= output_max_columns)
- indent = 0;
-
- // Will it all fit on one line?
-
- if (len + indent < output_max_columns)
- // Output as a single line
- fprintf(out, "%*s%s\n", indent, "", text);
- else
- {
- // We need to break it up into multiple lines.
- int text_width = output_max_columns - indent - 1;
- int start = 0;
- int end = start;
- int final_end = len;
- int sub_len;
-
- while (end < final_end)
- {
- // Dont start the 'text' on a space, since we're already outputting the indentation.
- while ((start < final_end) && (text[start] == ' '))
- start++;
-
- end = start + text_width;
- if (end > final_end)
- end = final_end;
- else
- {
- // If we're not at the end of the text, make sure we break the line on white space.
- while (end > start && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
- end--;
- }
- sub_len = end - start;
- std::string substring = text_string.substr(start, sub_len);
- fprintf(out, "%*s%s\n", indent, "", substring.c_str());
- start = end + 1;
- }
- }
-}
-
-void
-ShowUsage(FILE *out, OptionDefinition *option_table, Driver::OptionData data)
-{
- uint32_t screen_width = 80;
- uint32_t indent_level = 0;
- const char *name = "lldb";
-
- fprintf(out, "\nUsage:\n\n");
-
- indent_level += 2;
-
- // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
- // <cmd> [options-for-level-1]
- // etc.
-
- uint32_t num_options;
- uint32_t num_option_sets = 0;
-
- for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
- {
- uint32_t this_usage_mask = option_table[num_options].usage_mask;
- if (this_usage_mask == LLDB_OPT_SET_ALL)
- {
- if (num_option_sets == 0)
- num_option_sets = 1;
- }
- else
- {
- for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
- {
- if (this_usage_mask & 1 << j)
- {
- if (num_option_sets <= j)
- num_option_sets = j + 1;
- }
- }
- }
- }
-
- for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
- {
- uint32_t opt_set_mask;
-
- opt_set_mask = 1 << opt_set;
-
- if (opt_set > 0)
- fprintf(out, "\n");
- fprintf(out, "%*s%s", indent_level, "", name);
- bool is_help_line = false;
-
- for (uint32_t i = 0; i < num_options; ++i)
- {
- if (option_table[i].usage_mask & opt_set_mask)
- {
- CommandArgumentType arg_type = option_table[i].argument_type;
- const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString(arg_type);
- // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
- // so we do it by hand here.
- if (option_table[i].short_option == 'h')
- is_help_line = true;
-
- if (option_table[i].required)
- {
- if (option_table[i].option_has_arg == required_argument)
- fprintf(out, " -%c <%s>", option_table[i].short_option, arg_name);
- else if (option_table[i].option_has_arg == optional_argument)
- fprintf(out, " -%c [<%s>]", option_table[i].short_option, arg_name);
- else
- fprintf(out, " -%c", option_table[i].short_option);
- }
- else
- {
- if (option_table[i].option_has_arg == required_argument)
- fprintf(out, " [-%c <%s>]", option_table[i].short_option, arg_name);
- else if (option_table[i].option_has_arg == optional_argument)
- fprintf(out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
- else
- fprintf(out, " [-%c]", option_table[i].short_option);
- }
- }
- }
- if (!is_help_line && (opt_set <= last_option_set_with_args))
- fprintf(out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
- }
-
- fprintf(out, "\n\n");
-
- // Now print out all the detailed information about the various options: long form, short form and help text:
- // -- long_name <argument>
- // - short <argument>
- // help text
-
- // This variable is used to keep track of which options' info we've printed out, because some options can be in
- // more than one usage level, but we only want to print the long form of its information once.
-
- Driver::OptionData::OptionSet options_seen;
- Driver::OptionData::OptionSet::iterator pos;
-
- indent_level += 5;
-
- for (uint32_t i = 0; i < num_options; ++i)
- {
- // Only print this option if we haven't already seen it.
- pos = options_seen.find(option_table[i].short_option);
- if (pos == options_seen.end())
- {
- CommandArgumentType arg_type = option_table[i].argument_type;
- const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString(arg_type);
-
- options_seen.insert(option_table[i].short_option);
- fprintf(out, "%*s-%c ", indent_level, "", option_table[i].short_option);
- if (arg_type != eArgTypeNone)
- fprintf(out, "<%s>", arg_name);
- fprintf(out, "\n");
- fprintf(out, "%*s--%s ", indent_level, "", option_table[i].long_option);
- if (arg_type != eArgTypeNone)
- fprintf(out, "<%s>", arg_name);
- fprintf(out, "\n");
- indent_level += 5;
- OutputFormattedUsageText(out, indent_level, option_table[i].usage_text, screen_width);
- indent_level -= 5;
- fprintf(out, "\n");
- }
- }
-
- indent_level -= 5;
-
- fprintf(out, "\n%*sNotes:\n", indent_level, "");
- indent_level += 5;
-
- fprintf(out, "\n%*sMultiple \"-s\" and \"-o\" options can be provided. They will be processed from left to right in order, "
- "\n%*swith the source files and commands interleaved. The same is true of the \"-S\" and \"-O\" options."
- "\n%*sThe before file and after file sets can intermixed freely, the command parser will sort them out."
- "\n%*sThe order of the file specifiers (\"-c\", \"-f\", etc.) is not significant in this regard.\n\n",
- indent_level, "", indent_level, "", indent_level, "", indent_level, "");
-
- fprintf(out, "\n%*sIf you don't provide -f then the first argument will be the file to be debugged"
- "\n%*swhich means that '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
- "\n%*sBut remember to end the options with \"--\" if any of your arguments have a \"-\" in them.\n\n",
- indent_level, "", indent_level, "", name, indent_level, "");
-}
-
-void
-BuildGetOptTable(OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table, uint32_t num_options)
-{
- if (num_options == 0)
- return;
-
- uint32_t i;
- uint32_t j;
- std::bitset<256> option_seen;
-
- getopt_table.resize(num_options + 1);
-
- for (i = 0, j = 0; i < num_options; ++i)
- {
- char short_opt = expanded_option_table[i].short_option;
-
- if (option_seen.test(short_opt) == false)
- {
- getopt_table[j].name = expanded_option_table[i].long_option;
- getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
- getopt_table[j].flag = NULL;
- getopt_table[j].val = expanded_option_table[i].short_option;
- option_seen.set(short_opt);
- ++j;
- }
- }
-
- getopt_table[j].name = NULL;
- getopt_table[j].has_arg = 0;
- getopt_table[j].flag = NULL;
- getopt_table[j].val = 0;
-}
-
-Driver::OptionData::OptionData()
- : m_args()
- , m_script_lang(lldb::eScriptLanguageDefault)
- , m_core_file()
- , m_crash_log()
- , m_initial_commands()
- , m_after_file_commands()
- , m_debug_mode(false)
- , m_source_quietly(false)
- , m_print_version(false)
- , m_print_python_path(false)
- , m_print_help(false)
- , m_wait_for(false)
- , m_process_name()
- , m_process_pid(LLDB_INVALID_PROCESS_ID)
- , m_use_external_editor(false)
- , m_seen_options()
-{
-}
-
-Driver::OptionData::~OptionData()
-{
-}
-
-void
-Driver::OptionData::Clear()
-{
- m_args.clear();
- m_script_lang = lldb::eScriptLanguageDefault;
- m_initial_commands.clear();
- m_after_file_commands.clear();
- m_debug_mode = false;
- m_source_quietly = false;
- m_print_help = false;
- m_print_version = false;
- m_print_python_path = false;
- m_use_external_editor = false;
- m_wait_for = false;
- m_process_name.erase();
- m_process_pid = LLDB_INVALID_PROCESS_ID;
-}
-
-void
-Driver::OptionData::AddInitialCommand(const char *command, bool before_file, bool is_file, SBError &error)
-{
- std::vector<std::pair<bool, std::string>> *command_set;
- if (before_file)
- command_set = &(m_initial_commands);
- else
- command_set = &(m_after_file_commands);
-
- if (is_file)
- {
- SBFileSpec file(command);
- if (file.Exists())
- command_set->push_back(std::pair<bool, std::string>(true, optarg));
- else if (file.ResolveExecutableLocation())
- {
- char final_path[PATH_MAX];
- file.GetPath(final_path, sizeof(final_path));
- std::string path_str(final_path);
- command_set->push_back(std::pair<bool, std::string>(true, path_str));
- }
- else
- error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
- }
- else
- command_set->push_back(std::pair<bool, std::string>(false, optarg));
-}
-
-void
-Driver::ResetOptionValues()
-{
- m_option_data.Clear();
-}
-
-const char *
-Driver::GetFilename() const
-{
- if (m_option_data.m_args.empty())
- return NULL;
- return m_option_data.m_args.front().c_str();
-}
-
-const char *
-Driver::GetCrashLogFilename() const
-{
- if (m_option_data.m_crash_log.empty())
- return NULL;
- return m_option_data.m_crash_log.c_str();
-}
-
-lldb::ScriptLanguage
-Driver::GetScriptLanguage() const
-{
- return m_option_data.m_script_lang;
-}
-
-void
-Driver::ExecuteInitialCommands(bool before_file)
-{
- size_t num_commands;
- std::vector<std::pair<bool, std::string>> *command_set;
- if (before_file)
- command_set = &(m_option_data.m_initial_commands);
- else
- command_set = &(m_option_data.m_after_file_commands);
-
- num_commands = command_set->size();
- SBCommandReturnObject result;
- bool old_async = GetDebugger().GetAsync();
- GetDebugger().SetAsync(false);
- for (size_t idx = 0; idx < num_commands; idx++)
- {
- bool is_file = (*command_set)[idx].first;
- const char *command = (*command_set)[idx].second.c_str();
- char command_string[PATH_MAX * 2];
- const bool dump_stream_only_if_no_immediate = true;
- const char *executed_command = command;
- if (is_file)
- {
- ::snprintf(command_string, sizeof(command_string), "command source -s %i '%s'", m_option_data.m_source_quietly, command);
- executed_command = command_string;
- }
-
- m_debugger.GetCommandInterpreter().HandleCommand(executed_command, result, false);
- if (!m_option_data.m_source_quietly || result.Succeeded() == false)
- {
- const size_t output_size = result.GetOutputSize();
- if (output_size > 0)
- {
- const char *cstr = result.GetOutput(dump_stream_only_if_no_immediate);
- if (cstr)
- printf("%s", cstr);
- }
- const size_t error_size = result.GetErrorSize();
- if (error_size > 0)
- {
- const char *cstr = result.GetError(dump_stream_only_if_no_immediate);
- if (cstr)
- printf("%s", cstr);
- }
- }
-
- if (result.Succeeded() == false)
- {
- const char *type = before_file ? "before file" : "after_file";
- if (is_file)
- ::fprintf(stderr, "Aborting %s command execution, command file: '%s' failed.\n", type, command);
- else
- ::fprintf(stderr, "Aborting %s command execution, command: '%s' failed.\n", type, command);
- break;
- }
- result.Clear();
- }
- GetDebugger().SetAsync(old_async);
-}
-
-bool
-Driver::GetDebugMode() const
-{
- return m_option_data.m_debug_mode;
-}
-
-// Check the arguments that were passed to this program to make sure they are valid and to get their
-// argument values (if any). Return a boolean value indicating whether or not to start up the full
-// debugger (i.e. the Command Interpreter) or not. Return FALSE if the arguments were invalid OR
-// if the user only wanted help or version information.
-
-SBError
-Driver::ParseArgs(int argc, const char *argv[], FILE *out_fh, bool &exiting)
-{
- ResetOptionValues();
-
- SBCommandReturnObject result;
-
- SBError error;
- std::string option_string;
- struct option *long_options = NULL;
- std::vector<struct option> long_options_vector;
- uint32_t num_options;
-
- for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
- /* Do Nothing. */;
-
- if (num_options == 0)
- {
- if (argc > 1)
- error.SetErrorStringWithFormat("invalid number of options");
- return error;
- }
-
- BuildGetOptTable(g_options, long_options_vector, num_options);
-
- if (long_options_vector.empty())
- long_options = NULL;
- else
- long_options = &long_options_vector.front();
-
- if (long_options == NULL)
- {
- error.SetErrorStringWithFormat("invalid long options");
- return error;
- }
-
- // Build the option_string argument for call to getopt_long_only.
-
- for (int i = 0; long_options[i].name != NULL; ++i)
- {
- if (long_options[i].flag == NULL)
- {
- option_string.push_back((char)long_options[i].val);
- switch (long_options[i].has_arg)
- {
- default:
- case no_argument:
- break;
- case required_argument:
- option_string.push_back(':');
- break;
- case optional_argument:
- option_string.append("::");
- break;
- }
- }
- }
-
- // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
- // know at that point whether we should read in init files yet. So we don't read them in in the
- // Driver constructor, then set the flags back to "read them in" here, and then if we see the
- // "-n" flag, we'll turn it off again. Finally we have to read them in by hand later in the
- // main loop.
-
- m_debugger.SkipLLDBInitFiles(false);
- m_debugger.SkipAppInitFiles(false);
-
-// Prepare for & make calls to getopt_long_only.
-#if __GLIBC__
- optind = 0;
-#else
- optreset = 1;
- optind = 1;
-#endif
- int val;
- while (1)
- {
- int long_options_index = -1;
- val = ::getopt_long_only(argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
-
- if (val == -1)
- break;
- else if (val == '?')
- {
- m_option_data.m_print_help = true;
- error.SetErrorStringWithFormat("unknown or ambiguous option");
- break;
- }
- else if (val == 0)
- continue;
- else
- {
- m_option_data.m_seen_options.insert((char)val);
- if (long_options_index == -1)
- {
- for (int i = 0; long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val; ++i)
- {
- if (long_options[i].val == val)
- {
- long_options_index = i;
- break;
- }
- }
- }
-
- if (long_options_index >= 0)
- {
- const int short_option = g_options[long_options_index].short_option;
-
- switch (short_option)
- {
- case 'h':
- m_option_data.m_print_help = true;
- break;
-
- case 'v':
- m_option_data.m_print_version = true;
- break;
-
- case 'P':
- m_option_data.m_print_python_path = true;
- break;
-
- case 'c':
- {
- SBFileSpec file(optarg);
- if (file.Exists())
- {
- m_option_data.m_core_file = optarg;
- }
- else
- error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
- }
- break;
-
- case 'e':
- m_option_data.m_use_external_editor = true;
- break;
-
- case 'x':
- m_debugger.SkipLLDBInitFiles(true);
- m_debugger.SkipAppInitFiles(true);
- break;
-
- case 'X':
- m_debugger.SetUseColor(false);
- break;
-
- case 'f':
- {
- SBFileSpec file(optarg);
- if (file.Exists())
- {
- m_option_data.m_args.push_back(optarg);
- }
- else if (file.ResolveExecutableLocation())
- {
- char path[PATH_MAX];
- file.GetPath(path, sizeof(path));
- m_option_data.m_args.push_back(path);
- }
- else
- error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
- }
- break;
-
- case 'a':
- if (!m_debugger.SetDefaultArchitecture(optarg))
- error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
- break;
-
- case 'l':
- m_option_data.m_script_lang = m_debugger.GetScriptingLanguage(optarg);
- break;
-
- case 'd':
- m_option_data.m_debug_mode = true;
- break;
-
- case 'Q':
- m_option_data.m_source_quietly = true;
- break;
-
- case 'n':
- m_option_data.m_process_name = optarg;
- break;
-
- case 'w':
- m_option_data.m_wait_for = true;
- break;
-
- case 'p':
- {
- char *remainder;
- m_option_data.m_process_pid = strtol(optarg, &remainder, 0);
- if (remainder == optarg || *remainder != '\0')
- error.SetErrorStringWithFormat("Could not convert process PID: \"%s\" into a pid.", optarg);
- }
- break;
- case 's':
- m_option_data.AddInitialCommand(optarg, false, true, error);
- break;
- case 'o':
- m_option_data.AddInitialCommand(optarg, false, false, error);
- break;
- case 'S':
- m_option_data.AddInitialCommand(optarg, true, true, error);
- break;
- case 'O':
- m_option_data.AddInitialCommand(optarg, true, false, error);
- break;
- default:
- m_option_data.m_print_help = true;
- error.SetErrorStringWithFormat("unrecognized option %c", short_option);
- break;
- }
- }
- else
- {
- error.SetErrorStringWithFormat("invalid option with value %i", val);
- }
- if (error.Fail())
- {
- return error;
- }
- }
- }
-
- if (error.Fail() || m_option_data.m_print_help)
- {
- ShowUsage(out_fh, g_options, m_option_data);
- exiting = true;
- }
- else if (m_option_data.m_print_version)
- {
- ::fprintf(out_fh, "%s\n", m_debugger.GetVersionString());
- exiting = true;
- }
- else if (m_option_data.m_print_python_path)
- {
- SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
- if (python_file_spec.IsValid())
- {
- char python_path[PATH_MAX];
- size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
- if (num_chars < PATH_MAX)
- {
- ::fprintf(out_fh, "%s\n", python_path);
- }
- else
- ::fprintf(out_fh, "<PATH TOO LONG>\n");
- }
- else
- ::fprintf(out_fh, "<COULD NOT FIND PATH>\n");
- exiting = true;
- }
- else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
- {
- // Any arguments that are left over after option parsing are for
- // the program. If a file was specified with -f then the filename
- // is already in the m_option_data.m_args array, and any remaining args
- // are arguments for the inferior program. If no file was specified with
- // -f, then what is left is the program name followed by any arguments.
-
- // Skip any options we consumed with getopt_long_only
- argc -= optind;
- argv += optind;
-
- if (argc > 0)
- {
- for (int arg_idx = 0; arg_idx < argc; ++arg_idx)
- {
- const char *arg = argv[arg_idx];
- if (arg)
- m_option_data.m_args.push_back(arg);
- }
- }
- }
- else
- {
- // Skip any options we consumed with getopt_long_only
- argc -= optind;
- // argv += optind; // Commented out to keep static analyzer happy
-
- if (argc > 0)
- ::fprintf(out_fh, "Warning: program arguments are ignored when attaching.\n");
- }
-
- return error;
-}
-
-void
-Driver::MainLoop()
-{
- if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
- {
- g_old_stdin_termios_is_valid = true;
- atexit(reset_stdin_termios);
- }
-
- ::setbuf(stdin, NULL);
- ::setbuf(stdout, NULL);
-
- m_debugger.SetErrorFileHandle(stderr, false);
- m_debugger.SetOutputFileHandle(stdout, false);
- m_debugger.SetInputFileHandle(stdin, true);
-
- m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
-
- struct winsize window_size;
- if (isatty(STDIN_FILENO) && ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
- {
- if (window_size.ws_col > 0)
- m_debugger.SetTerminalWidth(window_size.ws_col);
- }
-
- SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
-
- // Before we handle any options from the command line, we parse the
- // .lldbinit file in the user's home directory.
- SBCommandReturnObject result;
- sb_interpreter.SourceInitFileInHomeDirectory(result);
- if (GetDebugMode())
- {
- result.PutError(m_debugger.GetErrorFileHandle());
- result.PutOutput(m_debugger.GetOutputFileHandle());
- }
-
- // Now we handle options we got from the command line
- // First source in the commands specified to be run before the file arguments are processed.
- ExecuteInitialCommands(true);
-
- // Was there a core file specified?
- std::string core_file_spec("");
- if (!m_option_data.m_core_file.empty())
- core_file_spec.append("--core ").append(m_option_data.m_core_file);
-
- char command_string[PATH_MAX * 2];
- const size_t num_args = m_option_data.m_args.size();
- if (num_args > 0)
- {
- char arch_name[64];
- if (m_debugger.GetDefaultArchitecture(arch_name, sizeof(arch_name)))
- ::snprintf(command_string, sizeof(command_string), "target create --arch=%s %s \"%s\"", arch_name, core_file_spec.c_str(),
- m_option_data.m_args[0].c_str());
- else
- ::snprintf(command_string, sizeof(command_string), "target create %s \"%s\"", core_file_spec.c_str(),
- m_option_data.m_args[0].c_str());
-
- m_debugger.HandleCommand(command_string);
-
- if (num_args > 1)
- {
- m_debugger.HandleCommand("settings clear target.run-args");
- char arg_cstr[1024];
- for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
- {
- ::snprintf(arg_cstr, sizeof(arg_cstr), "settings append target.run-args \"%s\"", m_option_data.m_args[arg_idx].c_str());
- m_debugger.HandleCommand(arg_cstr);
- }
- }
- }
- else if (!core_file_spec.empty())
- {
- ::snprintf(command_string, sizeof(command_string), "target create %s", core_file_spec.c_str());
- m_debugger.HandleCommand(command_string);
- ;
- }
- else if (!m_option_data.m_process_name.empty())
- {
- ::snprintf(command_string, sizeof(command_string), "process attach --name '%s'%s", m_option_data.m_process_name.c_str(),
- m_option_data.m_wait_for ? " --waitfor" : "");
- m_debugger.HandleCommand(command_string);
- }
- else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid)
- {
- ::snprintf(command_string, sizeof(command_string), "process attach --pid %" PRIu64, m_option_data.m_process_pid);
- m_debugger.HandleCommand(command_string);
- }
-
- ExecuteInitialCommands(false);
-
- // Now that all option parsing is done, we try and parse the .lldbinit
- // file in the current working directory
- sb_interpreter.SourceInitFileInCurrentWorkingDirectory(result);
- if (GetDebugMode())
- {
- result.PutError(m_debugger.GetErrorFileHandle());
- result.PutOutput(m_debugger.GetOutputFileHandle());
- }
-
- bool handle_events = true;
- bool spawn_thread = false;
- m_debugger.RunCommandInterpreter(handle_events, spawn_thread);
-
- reset_stdin_termios();
- fclose(stdin);
-
- SBDebugger::Destroy(m_debugger);
-}
-
-void
-Driver::ResizeWindow(unsigned short col)
-{
- GetDebugger().SetTerminalWidth(col);
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Setup *this driver so it works as pass through (child) driver for the MI
-// driver. Called by the parent (MI driver) driver.
-// This driver has setup code in two places. The original in MainLoop() and
-// in int main() (when MICONFIG_COMPILE_MIDRIVER_VERSION == 0) so that code can
-// remain as much near to the original code as possible. If MI driver is the main
-// driver (when MICONFIG_COMPILE_MIDRIVER_VERSION == 1) then this function is
-// used to set up the Driver to work with the MI driver.
-// Type: Method.
-// Args: vwErrMsg - (W) On failure current error discription.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-Driver::MISetup(CMIUtilString &vwErrMsg)
-{
- bool bOk = MIstatus::success;
-
- // Is *this driver a pass through driver to the MI driver
- CMIDriverBase *pParent = GetDriversParent();
- if (pParent == nullptr)
- {
- // No it is not.
- // If MI is the main driver (which passes through to *this driver) then
- // *this driver needs to be initialized after MI is initialize to have a valid
- // pointer to the parent driver. *this is the parent's pass thru driver.
- assert(pParent == nullptr);
- return MIstatus::success; // Allow success for if Driver is the main driver
- }
-
- // MI driver may have streams it wants *this driver to use - still to be sorted
- m_debugger.SetErrorFileHandle(pParent->GetStderr(), false); // MI may redirect to its own stream
- m_debugger.SetOutputFileHandle(pParent->GetStdout(), false); // MI likely to NULL this
- m_debugger.SetInputFileHandle(pParent->GetStdin(), false); // MI could use this to feed input
-
- // ToDo: Do I need this?
- m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
-
- // ToDo: Do I need this?
- struct winsize window_size;
- if (isatty(STDIN_FILENO) && ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
- {
- if (window_size.ws_col > 0)
- m_debugger.SetTerminalWidth(window_size.ws_col);
- }
-
- return bOk;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Initialize setup *this driver ready for use.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-Driver::DoInitialize(void)
-{
- // Do nothing
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Unbind detach or release resources used by *this driver.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-Driver::DoShutdown(void)
-{
- SBDebugger::Destroy(m_debugger);
-
- // Is *this driver a pass through driver to the MI driver
- CMIDriverBase *pParent = GetDriversParent();
- if (pParent == nullptr)
- {
- // See DoInitialize().
- assert(pParent == nullptr);
- return MIstatus::success;
- }
-
- // Put stuff here when *this driver is a pass thru driver to the MI driver
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Retrieve the name for *this driver.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - Driver name.
-// Throws: None.
-//--
-const CMIUtilString &
-Driver::GetName(void) const
-{
- static CMIUtilString name("LLDB driver");
- return name;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Retrieve *this driver's last error condition.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString - Text description.
-// Throws: None.
-//--
-CMIUtilString
-Driver::GetError(void) const
-{
- // Do nothing - to implement
- return CMIUtilString();
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Call this function puts *this driver to work.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-Driver::DoMainLoop(void)
-{
- MainLoop();
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Call *this driver to resize the console window.
-// Type: Overridden.
-// Args: vTermWidth - (R) New window column size.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-void
-Driver::DoResizeWindow(const uint32_t vTermWidth)
-{
- ResizeWindow((unsigned short)vTermWidth);
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Call *this driver to return it's debugger.
-// Type: Overridden.
-// Args: None.
-// Return: lldb::SBDebugger & - LLDB debugger object reference.
-// Throws: None.
-//--
-lldb::SBDebugger &
-Driver::GetTheDebugger(void)
-{
- return GetDebugger();
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Proxy function to allow the driver implementation to validate executable
-// command line arguments.
-// Type: Overrideable.
-// Args: argc - (R) An integer that contains the count of arguments that follow in
-// argv. The argc parameter is always greater than or equal to 1.
-// argv - (R) An array of null-terminated strings representing command-line
-// arguments entered by the user of the program. By convention,
-// argv[0] is the command with which the program is invoked.
-// vpStdOut - (R) Pointer to a standard output stream.
-// vwbExiting - (W) True = *this want to exit, Reasons: help, invalid arg(s),
-// version information only.
-// False = Continue to work, start debugger i.e. Command
-// interpreter.
-// Return: lldb::SBError - LLDB current error status.
-// Throws: None.
-//--
-lldb::SBError
-Driver::DoParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting)
-{
- return ParseArgs(argc, argv, vpStdOut, vwbExiting);
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: A client can ask if *this driver is GDB/MI compatible.
-// Type: Overridden.
-// Args: None.
-// Return: True - GBD/MI compatible LLDB front end.
-// False - Not GBD/MI compatible LLDB front end.
-// Throws: None.
-//--
-bool
-Driver::GetDriverIsGDBMICompatibleDriver(void) const
-{
- return false;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: This function allows *this driver to call on another driver to perform work
-// should this driver not be able to handle the client data input.
-// SetDriverToFallThruTo() specifies the fall through to driver.
-// Check the error message if the function returns a failure.
-// Type: Overridden.
-// Args: vCmd - (R) Command instruction to interpret.
-// vwErrMsg - (W) Error description on command failing.
-// Return: MIstatus::success - Command succeeded.
-// MIstatus::failure - Command failed.
-// Throws: None.
-//--
-bool
-Driver::DoFallThruToAnotherDriver(const CMIUtilString &vCmd, CMIUtilString &vwErrMsg)
-{
- bool bOk = MIstatus::success;
- vwErrMsg.empty();
-
- // ToDo: Implement do work on other driver after this driver said "Give up you try"
- // This may nto be required if the feature to 'fall through' is not required
- SBCommandReturnObject returnObj = lldb::SBCommandReturnObject();
- SBCommandInterpreter cmdIntrp = m_debugger.GetCommandInterpreter();
- const lldb::ReturnStatus cmdResult = cmdIntrp.HandleCommand(vCmd.c_str(), returnObj);
- MIunused(cmdResult);
- if (returnObj.Succeeded() == false)
- {
- bOk = MIstatus::failure;
- vwErrMsg = returnObj.GetError();
- }
-
- return bOk;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: This function allows *this driver to call functionality on the parent driver
-// ask for information for example.
-// Type: Overridden.
-// Args: vrOtherDriver - (R) Reference to another driver object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-Driver::SetDriverParent(const CMIDriverBase &vrOtherDriver)
-{
- m_pDriverParent = const_cast<CMIDriverBase *>(&vrOtherDriver);
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Set a unique ID for *this driver. It cannot be empty.
-// Type: Overridden.
-// Args: vId - (R) Text description.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-Driver::SetId(const CMIUtilString &vId)
-{
- if (vId.empty())
- {
- // Invalid to have it empty
- return MIstatus::failure;
- }
-
- m_strDriverId = vId;
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Get the unique ID for *this driver.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - Text description.
-// Throws: None.
-//--
-const CMIUtilString &
-Driver::GetId(void) const
-{
- return m_strDriverId;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Create *this driver. Function contains functionality that needs to be called
-// prior to constructing the *this driver.
-// Type: Static method.
-// Args: None.
-// Return: Driver * - Ptr to the LLDB driver object.
-// Throws: None.
-//--
-Driver *
-Driver::CreateSelf(void)
-{
- lldb::SBDebugger::Initialize();
-
- Driver *pDriver = new Driver;
- return pDriver;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Retrieve the name for *this driver.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString - Driver name.
-// Throws: None.
-//--
-const CMIUtilString &
-Driver::GetDriverName(void) const
-{
- return GetName();
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Get the unique ID for *this driver.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - Text description.
-// Throws: None.
-//--
-const CMIUtilString &
-Driver::GetDriverId(void) const
-{
- return GetId();
-}
-
-#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
diff --git a/tools/lldb-mi/Driver.h b/tools/lldb-mi/Driver.h
deleted file mode 100644
index 5bc97383a0c1..000000000000
--- a/tools/lldb-mi/Driver.h
+++ /dev/null
@@ -1,144 +0,0 @@
-//===-- Driver.h ------------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// In-house headers:
-#include "MICmnConfig.h"
-#if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
-
-#ifndef lldb_Driver_h_
-#define lldb_Driver_h_
-
-//#include "Platform.h" // IOR removed
-#include "lldb/Utility/PseudoTerminal.h"
-
-#include <set>
-#include <bitset>
-#include <string>
-#include <vector>
-
-#include "lldb/API/SBDefines.h"
-#include "lldb/API/SBBroadcaster.h"
-#include "lldb/API/SBDebugger.h"
-#include "lldb/API/SBError.h"
-#include "MIDriverMgr.h"
-#include "MIDriverBase.h"
-
-#define ASYNC true
-#define NO_ASYNC false
-
-class IOChannel;
-
-class Driver : public lldb::SBBroadcaster, public CMIDriverBase, public CMIDriverMgr::IDriver
-{
- // MI required code:
- // Static:
- public:
- static Driver *CreateSelf(void);
-
- // Methods:
- public:
- bool MISetup(CMIUtilString &vwErrMsg);
-
- // Overridden:
- public:
- // From CMIDriverMgr::IDriver
- virtual bool DoInitialize(void);
- virtual bool DoShutdown(void);
- virtual bool DoMainLoop(void);
- virtual void DoResizeWindow(const uint32_t vWindowSizeWsCol);
- virtual lldb::SBError DoParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting);
- virtual CMIUtilString GetError(void) const;
- virtual const CMIUtilString &GetName(void) const;
- virtual lldb::SBDebugger &GetTheDebugger(void);
- virtual bool GetDriverIsGDBMICompatibleDriver(void) const;
- virtual bool SetId(const CMIUtilString &vID);
- virtual const CMIUtilString &GetId(void) const;
- // From CMIDriverBase
- virtual bool DoFallThruToAnotherDriver(const CMIUtilString &vCmd, CMIUtilString &vwErrMsg);
- virtual bool SetDriverParent(const CMIDriverBase &vrOtherDriver);
- virtual const CMIUtilString &GetDriverName(void) const;
- virtual const CMIUtilString &GetDriverId(void) const;
-
- // Original code:
- public:
- Driver();
-
- virtual ~Driver();
-
- void MainLoop();
-
- lldb::SBError ParseArgs(int argc, const char *argv[], FILE *out_fh, bool &do_exit);
-
- const char *GetFilename() const;
-
- const char *GetCrashLogFilename() const;
-
- const char *GetArchName() const;
-
- lldb::ScriptLanguage GetScriptLanguage() const;
-
- void ExecuteInitialCommands(bool before_file);
-
- bool GetDebugMode() const;
-
- class OptionData
- {
- public:
- OptionData();
- ~OptionData();
-
- void Clear();
-
- void AddInitialCommand(const char *command, bool before_file, bool is_file, lldb::SBError &error);
-
- // static OptionDefinition m_cmd_option_table[];
-
- std::vector<std::string> m_args;
- lldb::ScriptLanguage m_script_lang;
- std::string m_core_file;
- std::string m_crash_log;
- std::vector<std::pair<bool, std::string>> m_initial_commands;
- std::vector<std::pair<bool, std::string>> m_after_file_commands;
- bool m_debug_mode;
- bool m_source_quietly;
- bool m_print_version;
- bool m_print_python_path;
- bool m_print_help;
- bool m_wait_for;
- std::string m_process_name;
- lldb::pid_t m_process_pid;
- bool m_use_external_editor; // FIXME: When we have set/show variables we can remove this from here.
- typedef std::set<char> OptionSet;
- OptionSet m_seen_options;
- };
-
- static lldb::SBError SetOptionValue(int option_idx, const char *option_arg, Driver::OptionData &data);
-
- lldb::SBDebugger &
- GetDebugger()
- {
- return m_debugger;
- }
-
- void ResizeWindow(unsigned short col);
-
- private:
- lldb::SBDebugger m_debugger;
- OptionData m_option_data;
-
- void ResetOptionValues();
-
- void ReadyForCommand();
-};
-
-extern Driver *g_driver;
-
-#endif // lldb_Driver_h_
-
-#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
diff --git a/tools/lldb-mi/MICmdArgContext.cpp b/tools/lldb-mi/MICmdArgContext.cpp
index 217913cff175..7a1bbf77d31a 100644
--- a/tools/lldb-mi/MICmdArgContext.cpp
+++ b/tools/lldb-mi/MICmdArgContext.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnArgContext.cpp
-//
-// Overview: CMICmdArgContext implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgContext.h"
@@ -30,8 +18,6 @@
// Throws: None.
//--
CMICmdArgContext::CMICmdArgContext(void)
- : m_constCharSpace(' ')
- , m_constStrSpace(" ")
{
}
@@ -44,8 +30,6 @@ CMICmdArgContext::CMICmdArgContext(void)
//--
CMICmdArgContext::CMICmdArgContext(const CMIUtilString &vrCmdLineArgsRaw)
: m_strCmdArgsAndOptions(vrCmdLineArgsRaw)
- , m_constCharSpace(' ')
- , m_constStrSpace(" ")
{
}
@@ -101,35 +85,35 @@ CMICmdArgContext::RemoveArg(const CMIUtilString &vArg)
if (vArg.empty())
return MIstatus::success;
- const MIuint nLen = vArg.length();
- const MIuint nLenCntxt = m_strCmdArgsAndOptions.length();
+ const size_t nLen = vArg.length();
+ const size_t nLenCntxt = m_strCmdArgsAndOptions.length();
if (nLen > nLenCntxt)
return MIstatus::failure;
- MIuint nExtraSpace = 0;
- MIint nPos = m_strCmdArgsAndOptions.find(vArg);
+ size_t nExtraSpace = 0;
+ size_t nPos = m_strCmdArgsAndOptions.find(vArg);
while (1)
{
- if (nPos == (MIint)std::string::npos)
+ if (nPos == std::string::npos)
return MIstatus::success;
bool bPass1 = false;
if (nPos != 0)
{
- if (m_strCmdArgsAndOptions[nPos - 1] == m_constCharSpace)
+ if (m_strCmdArgsAndOptions[nPos - 1] == ' ')
bPass1 = true;
}
else
bPass1 = true;
- const MIuint nEnd = nPos + nLen;
+ const size_t nEnd = nPos + nLen;
if (bPass1)
{
bool bPass2 = false;
if (nEnd < nLenCntxt)
{
- if (m_strCmdArgsAndOptions[nEnd] == m_constCharSpace)
+ if (m_strCmdArgsAndOptions[nEnd] == ' ')
{
bPass2 = true;
nExtraSpace = 1;
@@ -145,7 +129,7 @@ CMICmdArgContext::RemoveArg(const CMIUtilString &vArg)
nPos = m_strCmdArgsAndOptions.find(vArg, nEnd);
}
- const MIuint nPosEnd = nLen + nExtraSpace;
+ const size_t nPosEnd = nLen + nExtraSpace;
m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.replace(nPos, nPosEnd, "").c_str();
m_strCmdArgsAndOptions = m_strCmdArgsAndOptions.Trim();
@@ -182,7 +166,7 @@ CMICmdArgContext::RemoveArgAtPos(const CMIUtilString &vArg, const MIuint nArgInd
// Single words
strBuildContextUp += rWord;
if (bSpaceRequired)
- strBuildContextUp += m_constStrSpace;
+ strBuildContextUp += " ";
}
else
{
@@ -193,7 +177,7 @@ CMICmdArgContext::RemoveArgAtPos(const CMIUtilString &vArg, const MIuint nArgInd
while (vArg != words)
{
if (bSpaceRequired)
- words += m_constStrSpace;
+ words += " ";
words += *it;
if (++it == itEnd)
break;
@@ -225,7 +209,7 @@ MIuint
CMICmdArgContext::GetNumberArgsPresent(void) const
{
CMIUtilString::VecString_t vecOptions;
- return m_strCmdArgsAndOptions.SplitConsiderQuotes(m_constStrSpace, vecOptions);
+ return m_strCmdArgsAndOptions.SplitConsiderQuotes(" ", vecOptions);
}
//++ ------------------------------------------------------------------------------------
@@ -239,7 +223,7 @@ CMIUtilString::VecString_t
CMICmdArgContext::GetArgs(void) const
{
CMIUtilString::VecString_t vecOptions;
- m_strCmdArgsAndOptions.SplitConsiderQuotes(m_constStrSpace, vecOptions);
+ m_strCmdArgsAndOptions.SplitConsiderQuotes(" ", vecOptions);
return vecOptions;
}
diff --git a/tools/lldb-mi/MICmdArgContext.h b/tools/lldb-mi/MICmdArgContext.h
index 7178373ce380..baeb9232ef50 100644
--- a/tools/lldb-mi/MICmdArgContext.h
+++ b/tools/lldb-mi/MICmdArgContext.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgContext.h
-//
-// Overview: CMICmdArgContext interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
@@ -56,6 +44,4 @@ class CMICmdArgContext
// Attributes:
private:
CMIUtilString m_strCmdArgsAndOptions;
- const MIchar m_constCharSpace;
- const CMIUtilString m_constStrSpace;
};
diff --git a/tools/lldb-mi/MICmdArgSet.cpp b/tools/lldb-mi/MICmdArgSet.cpp
index 290f9eef8a9d..3d63a6138f7f 100644
--- a/tools/lldb-mi/MICmdArgSet.cpp
+++ b/tools/lldb-mi/MICmdArgSet.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgSet.cpp
-//
-// Overview: CMICmdArgSet implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgSet.h"
#include "MICmdArgValBase.h"
@@ -181,28 +169,24 @@ CMICmdArgSet::Validate(const CMIUtilString &vStrMiCmd, CMICmdArgContext &vwCmdAr
m_cmdArgContext = vwCmdArgsText;
// Iterate all the arguments or options required by a command
- const MIuint nArgs = vwCmdArgsText.GetNumberArgsPresent();
- MIuint nArgsMandatoryCnt = 0;
SetCmdArgs_t::const_iterator it = m_setCmdArgs.begin();
while (it != m_setCmdArgs.end())
{
const CMICmdArgValBase *pArg(*it);
- const CMIUtilString &rArgName(pArg->GetName());
- MIunused(rArgName);
- if (pArg->GetIsMandatory())
- nArgsMandatoryCnt++;
+
if (!const_cast<CMICmdArgValBase *>(pArg)->Validate(vwCmdArgsText))
{
- if (pArg->GetIsMandatory() && !pArg->GetFound())
- m_setCmdArgsThatAreMissing.push_back(const_cast<CMICmdArgValBase *>(pArg));
- else if (pArg->GetFound())
+ if (pArg->GetFound())
{
if (pArg->GetIsMissingOptions())
m_setCmdArgsMissingInfo.push_back(const_cast<CMICmdArgValBase *>(pArg));
else if (!pArg->GetValid())
m_setCmdArgsThatNotValid.push_back(const_cast<CMICmdArgValBase *>(pArg));
}
+ else if (pArg->GetIsMandatory())
+ m_setCmdArgsThatAreMissing.push_back(const_cast<CMICmdArgValBase *>(pArg));
}
+
if (pArg->GetFound() && !pArg->GetIsHandledByCmd())
{
m_bIsArgsPresentButNotHandledByCmd = true;
@@ -213,14 +197,7 @@ CMICmdArgSet::Validate(const CMIUtilString &vStrMiCmd, CMICmdArgContext &vwCmdAr
++it;
}
- // Check that one or more argument objects have any issues to report...
-
- if (nArgs < nArgsMandatoryCnt)
- {
- SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_N_OPTIONS_REQUIRED), nArgsMandatoryCnt));
- return MIstatus::failure;
- }
-
+ // report any issues with arguments/options
if (IsArgsPresentButNotHandledByCmd())
WarningArgsNotHandledbyCmdLogFile(vStrMiCmd);
diff --git a/tools/lldb-mi/MICmdArgSet.h b/tools/lldb-mi/MICmdArgSet.h
index eed667071733..00da679d7733 100644
--- a/tools/lldb-mi/MICmdArgSet.h
+++ b/tools/lldb-mi/MICmdArgSet.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgSet.h
-//
-// Overview: CMICmdArgSet interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
diff --git a/tools/lldb-mi/MICmdArgValBase.cpp b/tools/lldb-mi/MICmdArgValBase.cpp
index 1419df3206c8..dfaacbc6e7b2 100644
--- a/tools/lldb-mi/MICmdArgValBase.cpp
+++ b/tools/lldb-mi/MICmdArgValBase.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValBase.cpp
-//
-// Overview: CMICmdArgValBase implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgValBase.h"
#include "MIUtilString.h"
diff --git a/tools/lldb-mi/MICmdArgValBase.h b/tools/lldb-mi/MICmdArgValBase.h
index 0afe8d9bab6a..0d0eedd6e5b7 100644
--- a/tools/lldb-mi/MICmdArgValBase.h
+++ b/tools/lldb-mi/MICmdArgValBase.h
@@ -1,4 +1,4 @@
-//===-- Platform.h ----------------------------------------------*- C++ -*-===//
+//===-- CMICmdArgValBase.h --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValBase.h
-//
-// Overview: CMICmdArgValBase interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmdArgValConsume.cpp b/tools/lldb-mi/MICmdArgValConsume.cpp
index 041005567393..c2fe9940d878 100644
--- a/tools/lldb-mi/MICmdArgValConsume.cpp
+++ b/tools/lldb-mi/MICmdArgValConsume.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValConsume.cpp
-//
-// Overview: CMICmdArgValConsume implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgValConsume.h"
#include "MICmdArgContext.h"
@@ -71,7 +59,7 @@ bool
CMICmdArgValConsume::Validate(CMICmdArgContext &vwArgContext)
{
if (vwArgContext.IsEmpty())
- return MIstatus::success;
+ return m_bMandatory ? MIstatus::failure : MIstatus::success;
// Consume the optional file, line, linenum arguments till the mode '--' argument
const CMIUtilString::VecString_t vecOptions(vwArgContext.GetArgs());
@@ -80,15 +68,15 @@ CMICmdArgValConsume::Validate(CMICmdArgContext &vwArgContext)
{
const CMIUtilString & rTxt( *it );
- if ( rTxt.compare( "--" ) == 0 )
+ if ( rTxt.compare( "--" ) == 0 )
{
m_bFound = true;
m_bValid = true;
- return MIstatus::success;
- }
+ return MIstatus::success;
+ }
- if ( !vwArgContext.RemoveArg( rTxt ) )
- return MIstatus::failure;
+ if ( !vwArgContext.RemoveArg( rTxt ) )
+ return MIstatus::failure;
// Next
++it;
diff --git a/tools/lldb-mi/MICmdArgValConsume.h b/tools/lldb-mi/MICmdArgValConsume.h
index 2b26e33aa8c1..1d37b79eba14 100644
--- a/tools/lldb-mi/MICmdArgValConsume.h
+++ b/tools/lldb-mi/MICmdArgValConsume.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValConsume.h
-//
-// Overview: CMICmdArgValConsume interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmdArgValFile.cpp b/tools/lldb-mi/MICmdArgValFile.cpp
index cee811f24dee..400610ff6ba6 100644
--- a/tools/lldb-mi/MICmdArgValFile.cpp
+++ b/tools/lldb-mi/MICmdArgValFile.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValFile.cpp
-//
-// Overview: CMICmdArgValFile implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgValFile.h"
#include "MICmdArgContext.h"
@@ -72,7 +60,7 @@ bool
CMICmdArgValFile::Validate(CMICmdArgContext &vwArgContext)
{
if (vwArgContext.IsEmpty())
- return MIstatus::success;
+ return m_bMandatory ? MIstatus::failure : MIstatus::success;
// The GDB/MI spec suggests there is only parameter
@@ -133,9 +121,9 @@ CMICmdArgValFile::GetFileNamePath(const CMIUtilString &vrTxt) const
CMIUtilString fileNamePath(vrTxt);
// Look for a space in the path
- const MIchar cSpace = ' ';
- const MIint nPos = fileNamePath.find(cSpace);
- if (nPos != (MIint)std::string::npos)
+ const char cSpace = ' ';
+ const size_t nPos = fileNamePath.find(cSpace);
+ if (nPos != std::string::npos)
fileNamePath = CMIUtilString::Format("\"%s\"", fileNamePath.c_str());
return fileNamePath;
@@ -158,7 +146,7 @@ CMICmdArgValFile::IsFilePath(const CMIUtilString &vrFileNamePath) const
const bool bHaveBckSlash = (vrFileNamePath.find_first_of("\\") != std::string::npos);
// Look for --someLongOption
- MIint nPos = vrFileNamePath.find_first_of("--");
+ size_t nPos = vrFileNamePath.find_first_of("--");
const bool bLong = (nPos == 0);
if (bLong)
return false;
@@ -193,13 +181,14 @@ CMICmdArgValFile::IsFilePath(const CMIUtilString &vrFileNamePath) const
bool
CMICmdArgValFile::IsValidChars(const CMIUtilString &vrText) const
{
- const MIchar *pPtr = const_cast<MIchar *>(vrText.c_str());
+ static CMIUtilString s_strSpecialCharacters(".'\"`@#$%^&*()_+-={}[]| ");
+ const char *pPtr = vrText.c_str();
for (MIuint i = 0; i < vrText.length(); i++, pPtr++)
{
- const MIchar c = *pPtr;
+ const char c = *pPtr;
if (::isalnum((int)c) == 0)
{
- if ((c != '.') && (c != '-') && (c != '_'))
+ if (s_strSpecialCharacters.find(c) == CMIUtilString::npos)
return false;
}
}
diff --git a/tools/lldb-mi/MICmdArgValFile.h b/tools/lldb-mi/MICmdArgValFile.h
index db5380885783..196f21fb3b34 100644
--- a/tools/lldb-mi/MICmdArgValFile.h
+++ b/tools/lldb-mi/MICmdArgValFile.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValFile.h
-//
-// Overview: CMICmdArgValFile interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmdArgValListBase.cpp b/tools/lldb-mi/MICmdArgValListBase.cpp
index b992b307e346..61d72fb823c7 100644
--- a/tools/lldb-mi/MICmdArgValListBase.cpp
+++ b/tools/lldb-mi/MICmdArgValListBase.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValListBase.cpp
-//
-// Overview: CMICmdArgValListBase implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgValListBase.h"
#include "MICmdArgContext.h"
diff --git a/tools/lldb-mi/MICmdArgValListBase.h b/tools/lldb-mi/MICmdArgValListBase.h
index 0e56f6dac021..153af814dcfc 100644
--- a/tools/lldb-mi/MICmdArgValListBase.h
+++ b/tools/lldb-mi/MICmdArgValListBase.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValListBase.h
-//
-// Overview: CMICmdArgValListBase interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
diff --git a/tools/lldb-mi/MICmdArgValListOfN.cpp b/tools/lldb-mi/MICmdArgValListOfN.cpp
index 9a4711485f0b..8e479d52e79a 100644
--- a/tools/lldb-mi/MICmdArgValListOfN.cpp
+++ b/tools/lldb-mi/MICmdArgValListOfN.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValListOfN.cpp
-//
-// Overview: CMICmdArgValListOfN implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgValListOfN.h"
#include "MICmdArgContext.h"
@@ -86,7 +74,7 @@ CMICmdArgValListOfN::Validate(CMICmdArgContext &vwArgContext)
}
if (vwArgContext.IsEmpty())
- return MIstatus::success;
+ return m_bMandatory ? MIstatus::failure : MIstatus::success;
const CMIUtilString &rArg(vwArgContext.GetArgsLeftToParse());
if (IsListOfN(rArg) && CreateList(rArg))
diff --git a/tools/lldb-mi/MICmdArgValListOfN.h b/tools/lldb-mi/MICmdArgValListOfN.h
index 48ee77f79e72..356b494c0898 100644
--- a/tools/lldb-mi/MICmdArgValListOfN.h
+++ b/tools/lldb-mi/MICmdArgValListOfN.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValListOfN.h
-//
-// Overview: CMICmdArgValListOfN interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
@@ -56,7 +44,7 @@ class CMICmdArgValListOfN : public CMICmdArgValListBase
const ArgValType_e veType);
//
const VecArgObjPtr_t &GetExpectedOptions(void) const;
- template <class T1, typename T2> bool GetExpectedOption(T2 &vrwValue) const;
+ template <class T1, typename T2> bool GetExpectedOption(T2 &vrwValue, const VecArgObjPtr_t::size_type vnAt = 0) const;
// Overridden:
public:
@@ -76,6 +64,7 @@ class CMICmdArgValListOfN : public CMICmdArgValListBase
// parsed from the command's options string.
// Type: Template method.
// Args: vrwValue - (W) Templated type return value.
+// vnAt - (R) Value at the specific position.
// T1 - The argument value's class type of the data hold in the list of options.
// T2 - The type pf the variable which holds the value wanted.
// Return: MIstatus::success - Functional succeeded.
@@ -84,10 +73,13 @@ class CMICmdArgValListOfN : public CMICmdArgValListBase
//--
template <class T1, typename T2>
bool
-CMICmdArgValListOfN::GetExpectedOption(T2 &vrwValue) const
+CMICmdArgValListOfN::GetExpectedOption(T2 &vrwValue, const VecArgObjPtr_t::size_type vnAt) const
{
const VecArgObjPtr_t &rVecOptions(GetExpectedOptions());
- VecArgObjPtr_t::const_iterator it2 = rVecOptions.begin();
+ if (rVecOptions.size() <= vnAt)
+ return MIstatus::failure;
+
+ VecArgObjPtr_t::const_iterator it2 = rVecOptions.begin() + vnAt;
if (it2 != rVecOptions.end())
{
const T1 *pOption = static_cast<T1 *>(*it2);
diff --git a/tools/lldb-mi/MICmdArgValNumber.cpp b/tools/lldb-mi/MICmdArgValNumber.cpp
index 8b1878df028b..75e9700c874d 100644
--- a/tools/lldb-mi/MICmdArgValNumber.cpp
+++ b/tools/lldb-mi/MICmdArgValNumber.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValNumber.cpp
-//
-// Overview: CMICmdArgValNumber implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgValNumber.h"
#include "MICmdArgContext.h"
@@ -31,21 +19,25 @@
// Throws: None.
//--
CMICmdArgValNumber::CMICmdArgValNumber(void)
- : m_nNumber(0)
+ : m_nNumberFormatMask(CMICmdArgValNumber::eArgValNumberFormat_Decimal)
+ , m_nNumber(0)
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmdArgValNumber constructor.
// Type: Method.
-// Args: vrArgName - (R) Argument's name to search by.
-// vbMandatory - (R) True = Yes must be present, false = optional argument.
-// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// vnNumberFormatMask - (R) Mask of the number formats. (Dflt = CMICmdArgValNumber::eArgValNumberFormat_Decimal)
// Return: None.
// Throws: None.
//--
-CMICmdArgValNumber::CMICmdArgValNumber(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd)
+CMICmdArgValNumber::CMICmdArgValNumber(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd,
+ const MIuint vnNumberFormatMask /* = CMICmdArgValNumber::eArgValNumberFormat_Decimal*/)
: CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd)
+ , m_nNumberFormatMask(vnNumberFormatMask)
, m_nNumber(0)
{
}
@@ -74,7 +66,7 @@ bool
CMICmdArgValNumber::Validate(CMICmdArgContext &vwArgContext)
{
if (vwArgContext.IsEmpty())
- return MIstatus::success;
+ return m_bMandatory ? MIstatus::failure : MIstatus::success;
if (vwArgContext.GetNumberArgsPresent() == 1)
{
@@ -128,11 +120,20 @@ CMICmdArgValNumber::Validate(CMICmdArgContext &vwArgContext)
bool
CMICmdArgValNumber::IsArgNumber(const CMIUtilString &vrTxt) const
{
+ const bool bFormatDecimal(m_nNumberFormatMask & CMICmdArgValNumber::eArgValNumberFormat_Decimal);
+ const bool bFormatHexadecimal(m_nNumberFormatMask & CMICmdArgValNumber::eArgValNumberFormat_Hexadecimal);
+
// Look for --someLongOption
if (std::string::npos != vrTxt.find("--"))
return false;
- return vrTxt.IsNumber();
+ if (bFormatDecimal && vrTxt.IsNumber())
+ return true;
+
+ if (bFormatHexadecimal && vrTxt.IsHexadecimalNumber())
+ return true;
+
+ return false;
}
//++ ------------------------------------------------------------------------------------
@@ -150,7 +151,7 @@ CMICmdArgValNumber::ExtractNumber(const CMIUtilString &vrTxt)
bool bOk = vrTxt.ExtractNumber(nNumber);
if (bOk)
{
- m_nNumber = static_cast<MIint>(nNumber);
+ m_nNumber = static_cast<MIint64>(nNumber);
}
return bOk;
diff --git a/tools/lldb-mi/MICmdArgValNumber.h b/tools/lldb-mi/MICmdArgValNumber.h
index 1a782e1af388..fea94b698f74 100644
--- a/tools/lldb-mi/MICmdArgValNumber.h
+++ b/tools/lldb-mi/MICmdArgValNumber.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValNumber.h
-//
-// Overview: CMICmdArgValNumber interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
@@ -40,10 +28,24 @@ class CMICmdArgContext;
//--
class CMICmdArgValNumber : public CMICmdArgValBaseTemplate<MIint64>
{
+ // Enums:
+ public:
+ //++ ---------------------------------------------------------------------------------
+ // Details: CMICmdArgValNumber needs to know what format of argument to look for in
+ // the command options text.
+ //--
+ enum ArgValNumberFormat_e
+ {
+ eArgValNumberFormat_Decimal = (1u << 0),
+ eArgValNumberFormat_Hexadecimal = (1u << 1),
+ eArgValNumberFormat_Auto = ((eArgValNumberFormat_Hexadecimal << 1) - 1u) ///< Indicates to try and lookup everything up during a query.
+ };
+
// Methods:
public:
/* ctor */ CMICmdArgValNumber(void);
- /* ctor */ CMICmdArgValNumber(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd);
+ /* ctor */ CMICmdArgValNumber(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd,
+ const MIuint vnNumberFormatMask = eArgValNumberFormat_Decimal);
//
bool IsArgNumber(const CMIUtilString &vrTxt) const;
@@ -61,5 +63,6 @@ class CMICmdArgValNumber : public CMICmdArgValBaseTemplate<MIint64>
// Attributes:
private:
+ MIuint m_nNumberFormatMask;
MIint64 m_nNumber;
};
diff --git a/tools/lldb-mi/MICmdArgValOptionLong.cpp b/tools/lldb-mi/MICmdArgValOptionLong.cpp
index 0c29982e2634..0eaf6e0d055f 100644
--- a/tools/lldb-mi/MICmdArgValOptionLong.cpp
+++ b/tools/lldb-mi/MICmdArgValOptionLong.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValOptionLong.cpp
-//
-// Overview: CMICmdArgValOptionLong implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgValOptionLong.h"
#include "MICmdArgContext.h"
@@ -120,7 +108,7 @@ bool
CMICmdArgValOptionLong::Validate(CMICmdArgContext &vwArgContext)
{
if (vwArgContext.IsEmpty())
- return MIstatus::success;
+ return m_bMandatory ? MIstatus::failure : MIstatus::success;
if (vwArgContext.GetNumberArgsPresent() == 1)
{
@@ -266,7 +254,7 @@ CMICmdArgValOptionLong::IsArgLongOption(const CMIUtilString &vrTxt) const
if (bHavePosSlash || bHaveBckSlash)
return false;
- const MIint nPos = vrTxt.find_first_of("--");
+ const size_t nPos = vrTxt.find_first_of("--");
if (nPos != 0)
return false;
diff --git a/tools/lldb-mi/MICmdArgValOptionLong.h b/tools/lldb-mi/MICmdArgValOptionLong.h
index 8ff92bf84369..ace939b64f83 100644
--- a/tools/lldb-mi/MICmdArgValOptionLong.h
+++ b/tools/lldb-mi/MICmdArgValOptionLong.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValOptionLong.h
-//
-// Overview: CMICmdArgValOptionLong interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmdArgValOptionShort.cpp b/tools/lldb-mi/MICmdArgValOptionShort.cpp
index 5a2b491d3c72..25eac676f5f9 100644
--- a/tools/lldb-mi/MICmdArgValOptionShort.cpp
+++ b/tools/lldb-mi/MICmdArgValOptionShort.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValOptionShort.cpp
-//
-// Overview: CMICmdArgValOptionShort implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgValOptionShort.h"
#include "MICmdArgContext.h"
diff --git a/tools/lldb-mi/MICmdArgValOptionShort.h b/tools/lldb-mi/MICmdArgValOptionShort.h
index 3bd38ac72d20..971a0d3a148c 100644
--- a/tools/lldb-mi/MICmdArgValOptionShort.h
+++ b/tools/lldb-mi/MICmdArgValOptionShort.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValOptionShort.h
-//
-// Overview: CMICmdArgValOptionShort interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmdArgValPrintValues.cpp b/tools/lldb-mi/MICmdArgValPrintValues.cpp
new file mode 100644
index 000000000000..3030782a3a29
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValPrintValues.cpp
@@ -0,0 +1,129 @@
+//===-- MICmdArgValPrintValues.cpp ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// In-house headers:
+#include "MICmdArgValPrintValues.h"
+#include "MICmdArgContext.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValPrintValues constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValPrintValues::CMICmdArgValPrintValues(void)
+ : m_nPrintValues(0)
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValPrintValues constructor.
+// Type: Method.
+// Args: vrArgName - (R) Argument's name to search by.
+// vbMandatory - (R) True = Yes must be present, false = optional argument.
+// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValPrintValues::CMICmdArgValPrintValues(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd)
+ : CMICmdArgValBaseTemplate(vrArgName, vbMandatory, vbHandleByCmd)
+ , m_nPrintValues(0)
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdArgValPrintValues destructor.
+// Type: Overridden.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdArgValPrintValues::~CMICmdArgValPrintValues(void)
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Parse the command's argument options string and try to extract the value *this
+// argument is looking for.
+// Type: Overridden.
+// Args: vwArgContext - (RW) The command's argument options string.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmdArgValPrintValues::Validate(CMICmdArgContext &vwArgContext)
+{
+ if (vwArgContext.IsEmpty())
+ return m_bMandatory ? MIstatus::failure : MIstatus::success;
+
+ const CMIUtilString strArg(vwArgContext.GetArgs()[0]);
+ if (IsArgPrintValues(strArg) && ExtractPrintValues(strArg))
+ {
+ m_bFound = true;
+ m_bValid = true;
+ m_argValue = GetPrintValues();
+ vwArgContext.RemoveArg(strArg);
+ return MIstatus::success;
+ }
+
+ return MIstatus::failure;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Examine the string and determine if it is a valid string type argument.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: bool - True = yes valid arg, false = no.
+// Throws: None.
+//--
+bool
+CMICmdArgValPrintValues::IsArgPrintValues(const CMIUtilString &vrTxt) const
+{
+ return (CMIUtilString::Compare(vrTxt, "0") || CMIUtilString::Compare(vrTxt, "--no-values") ||
+ CMIUtilString::Compare(vrTxt, "1") || CMIUtilString::Compare(vrTxt, "--all-values") ||
+ CMIUtilString::Compare(vrTxt, "2") || CMIUtilString::Compare(vrTxt, "--simple-values"));
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Extract the print-values from the print-values argument.
+// Type: Method.
+// Args: vrTxt - (R) Some text.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmdArgValPrintValues::ExtractPrintValues(const CMIUtilString &vrTxt)
+{
+ if (CMIUtilString::Compare(vrTxt, "0") || CMIUtilString::Compare(vrTxt, "--no-values"))
+ m_nPrintValues = 0;
+ else if (CMIUtilString::Compare(vrTxt, "1") || CMIUtilString::Compare(vrTxt, "--all-values"))
+ m_nPrintValues = 1;
+ else if (CMIUtilString::Compare(vrTxt, "2") || CMIUtilString::Compare(vrTxt, "--simple-values"))
+ m_nPrintValues = 2;
+ else
+ return MIstatus::failure;
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the print-values found in the argument.
+// Type: Method.
+// Args: None.
+// Return: MIuint - The print-values.
+// Throws: None.
+//--
+MIuint
+CMICmdArgValPrintValues::GetPrintValues(void) const
+{
+ return m_nPrintValues;
+}
diff --git a/tools/lldb-mi/MICmdArgValPrintValues.h b/tools/lldb-mi/MICmdArgValPrintValues.h
new file mode 100644
index 000000000000..37de923e9e52
--- /dev/null
+++ b/tools/lldb-mi/MICmdArgValPrintValues.h
@@ -0,0 +1,53 @@
+//===-- MICmdArgValPrintValues.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#pragma once
+
+// In-house headers:
+#include "MICmdArgValBase.h"
+
+// Declarations:
+class CMICmdArgContext;
+
+//++ ============================================================================
+// Details: MI common code class. Command argument class. Arguments object
+// needing specialization derived from the CMICmdArgValBase class.
+// An argument knows what type of argument it is and how it is to
+// interpret the options (context) string to find and validate a matching
+// argument and so extract a value from it. The print-values looks like:
+// 0 or --no-values
+// 1 or --all-values
+// 2 or --simple-values
+// Based on the Interpreter pattern.
+//--
+class CMICmdArgValPrintValues : public CMICmdArgValBaseTemplate<MIuint>
+{
+ // Methods:
+ public:
+ /* ctor */ CMICmdArgValPrintValues(void);
+ /* ctor */ CMICmdArgValPrintValues(const CMIUtilString &vrArgName, const bool vbMandatory, const bool vbHandleByCmd);
+ //
+ bool IsArgPrintValues(const CMIUtilString &vrTxt) const;
+
+ // Overridden:
+ public:
+ // From CMICmdArgValBase
+ /* dtor */ virtual ~CMICmdArgValPrintValues(void);
+ // From CMICmdArgSet::IArg
+ virtual bool Validate(CMICmdArgContext &vArgContext);
+
+ // Methods:
+ private:
+ bool ExtractPrintValues(const CMIUtilString &vrTxt);
+ MIuint GetPrintValues(void) const;
+
+ // Attributes:
+ private:
+ MIuint m_nPrintValues;
+};
diff --git a/tools/lldb-mi/MICmdArgValString.cpp b/tools/lldb-mi/MICmdArgValString.cpp
index c09eead072d1..c8d32901a4e5 100644
--- a/tools/lldb-mi/MICmdArgValString.cpp
+++ b/tools/lldb-mi/MICmdArgValString.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValString.cpp
-//
-// Overview: CMICmdArgValString implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgValString.h"
#include "MICmdArgContext.h"
@@ -46,7 +34,7 @@ CMICmdArgValString::CMICmdArgValString(void)
// Throws: None.
//--
CMICmdArgValString::CMICmdArgValString(const bool vbAnything)
- : m_bHandleQuotedString(false)
+ : m_bHandleQuotedString(vbAnything ? true : false)
, m_bAcceptNumbers(false)
, m_bHandleDirPaths(false)
, m_bHandleAnything(vbAnything)
@@ -56,7 +44,7 @@ CMICmdArgValString::CMICmdArgValString(const bool vbAnything)
//++ ------------------------------------------------------------------------------------
// Details: CMICmdArgValString constructor.
// Type: Method.
-// Args: vbHandleQuotes - (R) True = Parse a string surrounded by quotes spaces are not delimitors, false = only text up to
+// Args: vbHandleQuotes - (R) True = Parse a string surrounded by quotes spaces are not delimiters, false = only text up to
// next delimiting space character.
// vbAcceptNumbers - (R) True = Parse a string and accept as a number if number, false = numbers not recognised
// as string types.
@@ -79,7 +67,7 @@ CMICmdArgValString::CMICmdArgValString(const bool vbHandleQuotes, const bool vbA
// Args: vrArgName - (R) Argument's name to search by.
// vbMandatory - (R) True = Yes must be present, false = optional argument.
// vbHandleByCmd - (R) True = Command processes *this option, false = not handled.
-// vbHandleQuotes - (R) True = Parse a string surrounded by quotes spaces are not delimitors, false = only text up to
+// vbHandleQuotes - (R) True = Parse a string surrounded by quotes spaces are not delimiters, false = only text up to
// next delimiting space character. (Dflt = false)
// vbAcceptNumbers - (R) True = Parse a string and accept as a number if number, false = numbers not recognised as
// string types. (Dflt = false)
@@ -120,10 +108,10 @@ bool
CMICmdArgValString::Validate(CMICmdArgContext &vrwArgContext)
{
if (vrwArgContext.IsEmpty())
- return MIstatus::success;
+ return m_bMandatory ? MIstatus::failure : MIstatus::success;
if (m_bHandleQuotedString)
- return (ValidateQuotedText(vrwArgContext) || ValidateQuotedTextEmbedded(vrwArgContext));
+ return ValidateQuotedText(vrwArgContext);
return ValidateSingleText(vrwArgContext);
}
@@ -140,22 +128,6 @@ CMICmdArgValString::Validate(CMICmdArgContext &vrwArgContext)
bool
CMICmdArgValString::ValidateSingleText(CMICmdArgContext &vrwArgContext)
{
- if (vrwArgContext.GetNumberArgsPresent() == 1)
- {
- const CMIUtilString &rArg(vrwArgContext.GetArgsLeftToParse());
- if (IsStringArg(rArg))
- {
- m_bFound = true;
- m_bValid = true;
- m_argValue = rArg;
- vrwArgContext.RemoveArg(rArg);
- return MIstatus::success;
- }
- else
- return MIstatus::failure;
- }
-
- // More than one option...
const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
CMIUtilString::VecString_t::const_iterator it = vecOptions.begin();
while (it != vecOptions.end())
@@ -168,7 +140,7 @@ CMICmdArgValString::ValidateSingleText(CMICmdArgContext &vrwArgContext)
if (vrwArgContext.RemoveArg(rArg))
{
m_bValid = true;
- m_argValue = rArg;
+ m_argValue = rArg.StripSlashes();
return MIstatus::success;
}
else
@@ -184,8 +156,7 @@ CMICmdArgValString::ValidateSingleText(CMICmdArgContext &vrwArgContext)
//++ ------------------------------------------------------------------------------------
// Details: Parse the command's argument options string and try to extract all the words
-// between quotes then delimited by the next space. Can fall through to
-// ValidateSingleText() or ValidateQuotedQuotedTextEmbedded().
+// between quotes then delimited by the next space.
// Type: Method.
// Args: vrwArgContext - (RW) The command's argument options string.
// Return: MIstatus::success - Functional succeeded.
@@ -195,148 +166,21 @@ CMICmdArgValString::ValidateSingleText(CMICmdArgContext &vrwArgContext)
bool
CMICmdArgValString::ValidateQuotedText(CMICmdArgContext &vrwArgContext)
{
- // CODETAG_QUOTEDTEXT_SIMILAR_CODE
- CMIUtilString strOptions = vrwArgContext.GetArgsLeftToParse();
- const MIchar cQuote = '"';
-
- // Look for first quote of two
- MIint nPos = strOptions.find(cQuote);
- if (nPos == (MIint)std::string::npos)
- return ValidateSingleText(vrwArgContext);
-
- // Is one and only quote at end of the string
- const MIint nLen = strOptions.length();
- if (nPos == (MIint)(nLen - 1))
- return MIstatus::failure;
-
- // Quote must be the first character in the string or be preceeded by a space
- if ((nPos > 0) && (strOptions[nPos - 1] != ' '))
- return MIstatus::failure;
-
- // Need to find the other quote
- const MIint nPos2 = strOptions.rfind(cQuote);
- if (nPos2 == (MIint)std::string::npos)
- return MIstatus::failure;
-
- // Is there quotes surrounding string formatting embedded quotes
- if (IsStringArgQuotedQuotedTextEmbedded(strOptions))
- return ValidateQuotedQuotedTextEmbedded(vrwArgContext);
-
- // Make sure not same back quote, need two quotes
- if (nPos == nPos2)
- return MIstatus::failure;
-
- // Extract quoted text
- const CMIUtilString strQuotedTxt = strOptions.substr(nPos, nPos2 - nPos + 1).c_str();
- if (vrwArgContext.RemoveArg(strQuotedTxt))
- {
- m_bFound = true;
- m_bValid = true;
- m_argValue = strOptions.substr(nPos + 1, nPos2 - nPos - 1).c_str();
- return MIstatus::success;
- }
-
- return MIstatus::failure;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Parse the command's argument options string and try to extract all the words
-// between quotes then delimited by the next space. If there any string format
-// characters '\\' used to embed quotes these are ignored i.e. "\\\"%5d\\\""
-// becomes "%5d". Can fall through to ValidateQuotedText().
-// Type: Method.
-// Args: vrwArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmdArgValString::ValidateQuotedTextEmbedded(CMICmdArgContext &vrwArgContext)
-{
- // CODETAG_QUOTEDTEXT_SIMILAR_CODE
- CMIUtilString strOptions = vrwArgContext.GetArgsLeftToParse();
- const MIchar cBckSlash = '\\';
- const MIint nPos = strOptions.find(cBckSlash);
- if (nPos == (MIint)std::string::npos)
- return ValidateQuotedText(vrwArgContext);
-
- // Back slash must be the first character in the string or be preceeded by a space
- // or '\\'
- const MIchar cSpace = ' ';
- if ((nPos > 0) && (strOptions[nPos - 1] != cSpace))
- return MIstatus::failure;
-
- // Need to find the other back slash
- const MIint nPos2 = strOptions.rfind(cBckSlash);
- if (nPos2 == (MIint)std::string::npos)
- return MIstatus::failure;
-
- // Make sure not same back slash, need two slashs
- if (nPos == nPos2)
- return MIstatus::failure;
-
- // Look for the two quotes
- const MIint nLen = strOptions.length();
- const MIchar cQuote = '"';
- const MIint nPosQuote1 = nPos + 1;
- const MIint nPosQuote2 = (nPos2 < nLen) ? nPos2 + 1 : nPos2;
- if ((nPosQuote1 != nPosQuote2) && (strOptions[nPosQuote1] != cQuote) && (strOptions[nPosQuote2] != cQuote))
- return MIstatus::failure;
-
- // Extract quoted text
- const CMIUtilString strQuotedTxt = strOptions.substr(nPos, nPosQuote2 - nPos + 1).c_str();
- if (vrwArgContext.RemoveArg(strQuotedTxt))
- {
- m_bFound = true;
- m_bValid = true;
- m_argValue = strQuotedTxt;
- return MIstatus::success;
- }
-
- return MIstatus::failure;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Parse the command's argument options string and try to extract all the words
-// between quotes then delimited by the next space. If there any string format
-// characters '\\' used to embed quotes these are ignored i.e. "\\\"%5d\\\""
-// becomes "%5d".
-// Type: Method.
-// Args: vrwArgContext - (RW) The command's argument options string.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmdArgValString::ValidateQuotedQuotedTextEmbedded(CMICmdArgContext &vrwArgContext)
-{
- // CODETAG_QUOTEDTEXT_SIMILAR_CODE
- CMIUtilString strOptions = vrwArgContext.GetArgsLeftToParse();
- const MIint nPos = strOptions.find("\"\\\"");
- if (nPos == (MIint)std::string::npos)
- return MIstatus::failure;
-
- const MIint nPos2 = strOptions.rfind("\\\"\"");
- if (nPos2 == (MIint)std::string::npos)
+ const CMIUtilString::VecString_t vecOptions(vrwArgContext.GetArgs());
+ if (vecOptions.size() == 0)
return MIstatus::failure;
- const MIint nLen = strOptions.length();
- if ((nLen > 5) && ((nPos + 2) == (nPos2 - 2)))
+ const CMIUtilString &rArg(vecOptions[0]);
+ if (!IsStringArg(rArg))
return MIstatus::failure;
- // Quote must be the first character in the string or be preceeded by a space
- // or '\\'
- const MIchar cSpace = ' ';
- if ((nPos > 0) && (strOptions[nPos - 1] != cSpace))
- return MIstatus::failure;
+ m_bFound = true;
- // Extract quoted text
- const CMIUtilString strQuotedTxt = strOptions.substr(nPos, nPos2 - nPos + 3).c_str();
- if (vrwArgContext.RemoveArg(strQuotedTxt))
+ if (vrwArgContext.RemoveArg(rArg))
{
- m_bFound = true;
m_bValid = true;
- m_argValue = strQuotedTxt;
+ const char cQuote = '"';
+ m_argValue = rArg.Trim(cQuote).StripSlashes();
return MIstatus::success;
}
@@ -373,10 +217,6 @@ CMICmdArgValString::IsStringArg(const CMIUtilString &vrTxt) const
bool
CMICmdArgValString::IsStringArgSingleText(const CMIUtilString &vrTxt) const
{
- // Accept anything as string word
- if (m_bHandleAnything)
- return true;
-
if (!m_bHandleDirPaths)
{
// Look for directory file paths, if found reject
@@ -417,20 +257,24 @@ CMICmdArgValString::IsStringArgSingleText(const CMIUtilString &vrTxt) const
bool
CMICmdArgValString::IsStringArgQuotedText(const CMIUtilString &vrTxt) const
{
+ // Accept anything as string word
+ if (m_bHandleAnything)
+ return true;
+
// CODETAG_QUOTEDTEXT_SIMILAR_CODE
- const MIchar cQuote = '"';
- const MIint nPos = vrTxt.find(cQuote);
- if (nPos == (MIint)std::string::npos)
+ const char cQuote = '"';
+ const size_t nPos = vrTxt.find(cQuote);
+ if (nPos == std::string::npos)
return false;
// Is one and only quote at end of the string
- if (nPos == (MIint)(vrTxt.length() - 1))
+ if (nPos == (vrTxt.length() - 1))
return false;
- // Quote must be the first character in the string or be preceeded by a space
+ // Quote must be the first character in the string or be preceded by a space
// Also check for embedded string formating quote
- const MIchar cBckSlash = '\\';
- const MIchar cSpace = ' ';
+ const char cBckSlash = '\\';
+ const char cSpace = ' ';
if ((nPos > 1) && (vrTxt[nPos - 1] == cBckSlash) && (vrTxt[nPos - 2] != cSpace))
{
return false;
@@ -439,8 +283,8 @@ CMICmdArgValString::IsStringArgQuotedText(const CMIUtilString &vrTxt) const
return false;
// Need to find the other quote
- const MIint nPos2 = vrTxt.rfind(cQuote);
- if (nPos2 == (MIint)std::string::npos)
+ const size_t nPos2 = vrTxt.rfind(cQuote);
+ if (nPos2 == std::string::npos)
return false;
// Make sure not same quote, need two quotes
@@ -464,22 +308,22 @@ bool
CMICmdArgValString::IsStringArgQuotedTextEmbedded(const CMIUtilString &vrTxt) const
{
// CODETAG_QUOTEDTEXT_SIMILAR_CODE
- const MIchar cBckSlash = '\\';
- const MIint nPos = vrTxt.find(cBckSlash);
- if (nPos == (MIint)std::string::npos)
+ const char cBckSlash = '\\';
+ const size_t nPos = vrTxt.find(cBckSlash);
+ if (nPos == std::string::npos)
return false;
- // Slash must be the first character in the string or be preceeded by a space
- const MIchar cSpace = ' ';
+ // Slash must be the first character in the string or be preceded by a space
+ const char cSpace = ' ';
if ((nPos > 0) && (vrTxt[nPos - 1] != cSpace))
return false;
// Need to find the other matching slash
- const MIint nPos2 = vrTxt.rfind(cBckSlash);
- if (nPos2 == (MIint)std::string::npos)
+ const size_t nPos2 = vrTxt.rfind(cBckSlash);
+ if (nPos2 == std::string::npos)
return false;
- // Make sure not same back slash, need two slashs
+ // Make sure not same back slash, need two slashes
if (nPos == nPos2)
return MIstatus::failure;
@@ -499,15 +343,15 @@ CMICmdArgValString::IsStringArgQuotedTextEmbedded(const CMIUtilString &vrTxt) co
bool
CMICmdArgValString::IsStringArgQuotedQuotedTextEmbedded(const CMIUtilString &vrTxt) const
{
- const MIint nPos = vrTxt.find("\"\\\"");
- if (nPos == (MIint)std::string::npos)
+ const size_t nPos = vrTxt.find("\"\\\"");
+ if (nPos == std::string::npos)
return false;
- const MIint nPos2 = vrTxt.rfind("\\\"\"");
- if (nPos2 == (MIint)std::string::npos)
+ const size_t nPos2 = vrTxt.rfind("\\\"\"");
+ if (nPos2 == std::string::npos)
return false;
- const MIint nLen = vrTxt.length();
+ const size_t nLen = vrTxt.length();
if ((nLen > 5) && ((nPos + 2) == (nPos2 - 2)))
return false;
diff --git a/tools/lldb-mi/MICmdArgValString.h b/tools/lldb-mi/MICmdArgValString.h
index 58f9ee4f32c3..54051d615919 100644
--- a/tools/lldb-mi/MICmdArgValString.h
+++ b/tools/lldb-mi/MICmdArgValString.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValString.h
-//
-// Overview: CMICmdArgValString interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
@@ -70,7 +58,7 @@ class CMICmdArgValString : public CMICmdArgValBaseTemplate<CMIUtilString>
// Attribute:
private:
- bool m_bHandleQuotedString; // True = Parse a string surrounded by quotes spaces are not delimitors, false = only text up to next
+ bool m_bHandleQuotedString; // True = Parse a string surrounded by quotes spaces are not delimiters, false = only text up to next
// delimiting space character
bool m_bAcceptNumbers; // True = Parse a string and accept as a number if number, false = numbers not recognised as string types
bool m_bHandleDirPaths; // True = Parse a string and accept directory file style string if present, false = directory file path not
diff --git a/tools/lldb-mi/MICmdArgValThreadGrp.cpp b/tools/lldb-mi/MICmdArgValThreadGrp.cpp
index 606c615dfca2..c7e663c4721b 100644
--- a/tools/lldb-mi/MICmdArgValThreadGrp.cpp
+++ b/tools/lldb-mi/MICmdArgValThreadGrp.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValThreadGrp.cpp
-//
-// Overview: CMICmdArgValThreadGrp implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdArgValThreadGrp.h"
#include "MICmdArgContext.h"
@@ -74,7 +62,7 @@ bool
CMICmdArgValThreadGrp::Validate(CMICmdArgContext &vwArgContext)
{
if (vwArgContext.IsEmpty())
- return MIstatus::success;
+ return m_bMandatory ? MIstatus::failure : MIstatus::success;
if (vwArgContext.GetNumberArgsPresent() == 1)
{
diff --git a/tools/lldb-mi/MICmdArgValThreadGrp.h b/tools/lldb-mi/MICmdArgValThreadGrp.h
index d82b89ff5017..d361f3a87477 100644
--- a/tools/lldb-mi/MICmdArgValThreadGrp.h
+++ b/tools/lldb-mi/MICmdArgValThreadGrp.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdArgValThreadGrp.h
-//
-// Overview: CMICmdArgValThreadGrp interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmdBase.cpp b/tools/lldb-mi/MICmdBase.cpp
index d08dcb90f65f..de4fec2ff2ff 100644
--- a/tools/lldb-mi/MICmdBase.cpp
+++ b/tools/lldb-mi/MICmdBase.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdBase.cpp
-//
-// Overview: CMICmdBase implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdBase.h"
#include "MICmnMIValueConst.h"
diff --git a/tools/lldb-mi/MICmdBase.h b/tools/lldb-mi/MICmdBase.h
index c2a8fe030310..7209f4fe5d12 100644
--- a/tools/lldb-mi/MICmdBase.h
+++ b/tools/lldb-mi/MICmdBase.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdBase.h
-//
-// Overview: CMICmdBase interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmdCmd.cpp b/tools/lldb-mi/MICmdCmd.cpp
index 50f651f634f6..fbfc60995c5a 100644
--- a/tools/lldb-mi/MICmdCmd.cpp
+++ b/tools/lldb-mi/MICmdCmd.cpp
@@ -7,18 +7,10 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmd.cpp
-//
// Overview: CMICmdCmdEnablePrettyPrinting implementation.
// CMICmdCmdSource implementation.
//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
+
// In-house headers:
#include "MICmdCmd.h"
diff --git a/tools/lldb-mi/MICmdCmd.h b/tools/lldb-mi/MICmdCmd.h
index 1fd363084b4a..a360ad6a56af 100644
--- a/tools/lldb-mi/MICmdCmd.h
+++ b/tools/lldb-mi/MICmdCmd.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmd.h
-//
// Overview: CMICmdCmdEnablePrettyPrinting interface.
// CMICmdCmdSource interface.
//
@@ -21,13 +18,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
/*
MI commands implemented are:
diff --git a/tools/lldb-mi/MICmdCmdBreak.cpp b/tools/lldb-mi/MICmdCmdBreak.cpp
index 9ad7ea3540fd..1b3480984bb5 100644
--- a/tools/lldb-mi/MICmdCmdBreak.cpp
+++ b/tools/lldb-mi/MICmdCmdBreak.cpp
@@ -7,22 +7,12 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdBreak.cpp
-//
// Overview: CMICmdCmdBreakInsert implementation.
// CMICmdCmdBreakDelete implementation.
// CMICmdCmdBreakDisable implementation.
// CMICmdCmdBreakEnable implementation.
// CMICmdCmdBreakAfter implementation.
// CMICmdCmdBreakCondition implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// Third Party Headers:
#include "lldb/API/SBBreakpointLocation.h"
@@ -242,7 +232,7 @@ CMICmdCmdBreakInsert::Execute(void)
m_brkPt = sbTarget.BreakpointCreateByLocation(fileName.c_str(), nFileLine);
break;
case eBreakPoint_ByName:
- m_brkPt = sbTarget.BreakpointCreateByName(m_brkName.c_str(), sbTarget.GetExecutable().GetFilename());
+ m_brkPt = sbTarget.BreakpointCreateByName(m_brkName.c_str(), nullptr);
break;
case eBreakPoint_count:
case eBreakPoint_NotDefineYet:
@@ -253,25 +243,33 @@ CMICmdCmdBreakInsert::Execute(void)
if (bOk)
{
+ if (!m_bBrkPtIsPending && (m_brkPt.GetNumLocations() == 0))
+ {
+ sbTarget.BreakpointDelete(m_brkPt.GetID());
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_LOCATION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
+ return MIstatus::failure;
+ }
+
m_brkPt.SetEnabled(m_bBrkPtEnabled);
m_brkPt.SetIgnoreCount(m_nBrkPtIgnoreCount);
if (m_bBrkPtCondition)
m_brkPt.SetCondition(m_brkPtCondition.c_str());
if (m_bBrkPtThreadId)
m_brkPt.SetThreadID(m_nBrkPtThreadId);
- if (!m_brkPt.IsValid())
- m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
}
// CODETAG_LLDB_BREAKPOINT_CREATION
// This is in the main thread
// Record break point information to be by LLDB event handler function
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
+ if (!rSessionInfo.GetBrkPtInfo(m_brkPt, sBrkPtInfo))
+ return MIstatus::failure;
sBrkPtInfo.m_id = m_brkPt.GetID();
sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
+ sBrkPtInfo.m_nTimes = m_brkPt.GetHitCount();
sBrkPtInfo.m_strOrigLoc = m_brkName;
sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
@@ -279,8 +277,8 @@ CMICmdCmdBreakInsert::Execute(void)
sBrkPtInfo.m_strCondition = m_brkPtCondition;
sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
- bOk = bOk && rSessionInfo.RecordBrkPtInfo(m_brkPt.GetID(), sBrkPtInfo);
+ bOk = bOk && rSessionInfo.RecordBrkPtInfo(m_brkPt.GetID(), sBrkPtInfo);
if (!bOk)
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
@@ -313,33 +311,14 @@ CMICmdCmdBreakInsert::Acknowledge(void)
// Get breakpoint information
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
- if (!rSessionInfo.GetBrkPtInfo(m_brkPt, sBrkPtInfo))
- {
+ if (!rSessionInfo.RecordBrkPtInfoGet(m_brkPt.GetID(), sBrkPtInfo))
return MIstatus::failure;
- }
-
- // CODETAG_LLDB_BREAKPOINT_CREATION
- // Add more breakpoint information or overwrite existing information
- sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
- sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
- sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
- sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
- sBrkPtInfo.m_nTimes = m_brkPt.GetHitCount();
- sBrkPtInfo.m_strOrigLoc = m_brkName;
- sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
- sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
- sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
- sBrkPtInfo.m_strCondition = m_brkPtCondition;
- sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
- sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
// MI print
- // "^done,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",thread-groups=[\"%s\"],times=\"%d\",original-location=\"%s\"}"
+ // "^done,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",thread-groups=[\"%s\"],times=\"%d\",original-location=\"%s\"}"
CMICmnMIValueTuple miValueTuple;
if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple))
- {
return MIstatus::failure;
- }
const CMICmnMIValueResult miValueResultD("bkpt", miValueTuple);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultD);
diff --git a/tools/lldb-mi/MICmdCmdBreak.h b/tools/lldb-mi/MICmdCmdBreak.h
index 371afa15b639..06a3434ca5bb 100644
--- a/tools/lldb-mi/MICmdCmdBreak.h
+++ b/tools/lldb-mi/MICmdCmdBreak.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdBreak.h
-//
// Overview: CMICmdCmdBreakInsert interface.
// CMICmdCmdBreakDelete interface.
// CMICmdCmdBreakDisable interface.
@@ -25,13 +22,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
diff --git a/tools/lldb-mi/MICmdCmdData.cpp b/tools/lldb-mi/MICmdCmdData.cpp
index 92e419073335..bd0209337cd4 100644
--- a/tools/lldb-mi/MICmdCmdData.cpp
+++ b/tools/lldb-mi/MICmdCmdData.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdData.cpp
-//
// Overview: CMICmdCmdDataEvaluateExpression implementation.
// CMICmdCmdDataDisassemble implementation.
// CMICmdCmdDataReadMemoryBytes implementation.
@@ -19,15 +16,11 @@
// CMICmdCmdDataListRegisterChanged implementation.
// CMICmdCmdDataWriteMemoryBytes implementation.
// CMICmdCmdDataWriteMemory implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
+// CMICmdCmdDataInfoLine implementation.
// Third Party Headers:
+#include <inttypes.h> // For PRIx64
+#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBInstructionList.h"
@@ -132,7 +125,7 @@ CMICmdCmdDataEvaluateExpression::Execute(void)
lldb::SBValue value = frame.EvaluateExpression(rExpression.c_str());
if (!value.IsValid() || value.GetError().Fail())
value = frame.FindVariable(rExpression.c_str());
- const CMICmnLLDBUtilSBValue utilValue(value);
+ const CMICmnLLDBUtilSBValue utilValue(value, true);
if (!utilValue.IsValid() || utilValue.IsValueUnknown())
{
m_bEvaluatedExpression = false;
@@ -160,12 +153,7 @@ CMICmdCmdDataEvaluateExpression::Execute(void)
{
const lldb::ValueType eValueType = value.GetValueType();
MIunused(eValueType);
- m_strValue = utilValue.GetValue();
- CMIUtilString strCString;
- if (CMICmnLLDBProxySBValue::GetCString(value, strCString))
- {
- m_strValue += CMIUtilString::Format(" '%s'", strCString.c_str());
- }
+ m_strValue = utilValue.GetValue().Escape().AddSlashes();
return MIstatus::success;
}
@@ -277,7 +265,7 @@ CMICmdCmdDataEvaluateExpression::CreateSelf(void)
// Throws: None.
//--
bool
-CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression(const CMIUtilString &vrExpr, MIchar &vrwInvalidChar)
+CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression(const CMIUtilString &vrExpr, char &vrwInvalidChar)
{
static const std::string strInvalidCharacters(";#\\");
const size_t nInvalidCharacterOffset = vrExpr.find_first_of(strInvalidCharacters);
@@ -408,35 +396,44 @@ CMICmdCmdDataDisassemble::Execute(void)
lldb::addr_t lldbStartAddr = static_cast<lldb::addr_t>(nAddrStart);
lldb::SBInstructionList instructions = sbTarget.ReadInstructions(lldb::SBAddress(lldbStartAddr, sbTarget), nAddrEnd - nAddrStart);
const MIuint nInstructions = instructions.GetSize();
+ // Calculate the offset of first instruction so that we can generate offset starting at 0
+ lldb::addr_t start_offset = 0;
+ if(nInstructions > 0)
+ start_offset = instructions.GetInstructionAtIndex(0).GetAddress().GetOffset();
+
for (size_t i = 0; i < nInstructions; i++)
{
- const MIchar *pUnknown = "??";
+ const char *pUnknown = "??";
lldb::SBInstruction instrt = instructions.GetInstructionAtIndex(i);
- const MIchar *pStrMnemonic = instrt.GetMnemonic(sbTarget);
+ const char *pStrMnemonic = instrt.GetMnemonic(sbTarget);
pStrMnemonic = (pStrMnemonic != nullptr) ? pStrMnemonic : pUnknown;
+ const char *pStrComment = instrt.GetComment(sbTarget);
+ CMIUtilString strComment;
+ if (pStrComment != nullptr && *pStrComment != '\0')
+ strComment = CMIUtilString::Format("; %s", pStrComment);
lldb::SBAddress address = instrt.GetAddress();
lldb::addr_t addr = address.GetLoadAddress(sbTarget);
- const MIchar *pFnName = address.GetFunction().GetName();
+ const char *pFnName = address.GetFunction().GetName();
pFnName = (pFnName != nullptr) ? pFnName : pUnknown;
- lldb::addr_t addrOffSet = address.GetOffset();
- const MIchar *pStrOperands = instrt.GetOperands(sbTarget);
+ lldb::addr_t addrOffSet = address.GetOffset() - start_offset;
+ const char *pStrOperands = instrt.GetOperands(sbTarget);
pStrOperands = (pStrOperands != nullptr) ? pStrOperands : pUnknown;
const size_t instrtSize = instrt.GetByteSize();
- // MI "{address=\"0x%08llx\",func-name=\"%s\",offset=\"%lld\",inst=\"%s %s\"}"
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%08llx", addr));
+ // MI "{address=\"0x%016" PRIx64 "\",func-name=\"%s\",offset=\"%lld\",inst=\"%s %s\"}"
+ const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%016" PRIx64, addr));
const CMICmnMIValueResult miValueResult("address", miValueConst);
CMICmnMIValueTuple miValueTuple(miValueResult);
const CMICmnMIValueConst miValueConst2(pFnName);
const CMICmnMIValueResult miValueResult2("func-name", miValueConst2);
miValueTuple.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("0x%lld", addrOffSet));
+ const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("%lld", addrOffSet));
const CMICmnMIValueResult miValueResult3("offset", miValueConst3);
miValueTuple.Add(miValueResult3);
const CMICmnMIValueConst miValueConst4(CMIUtilString::Format("%d", instrtSize));
const CMICmnMIValueResult miValueResult4("size", miValueConst4);
miValueTuple.Add(miValueResult4);
- const CMICmnMIValueConst miValueConst5(CMIUtilString::Format("%s %s", pStrMnemonic, pStrOperands));
+ const CMICmnMIValueConst miValueConst5(CMIUtilString::Format("%s %s%s", pStrMnemonic, pStrOperands, strComment.Escape(true).c_str()));
const CMICmnMIValueResult miValueResult5("inst", miValueConst5);
miValueTuple.Add(miValueResult5);
@@ -444,7 +441,7 @@ CMICmdCmdDataDisassemble::Execute(void)
{
lldb::SBLineEntry lineEntry = address.GetLineEntry();
const MIuint nLine = lineEntry.GetLine();
- const MIchar *pFileName = lineEntry.GetFileSpec().GetFilename();
+ const char *pFileName = lineEntry.GetFileSpec().GetFilename();
pFileName = (pFileName != nullptr) ? pFileName : pUnknown;
// MI "src_and_asm_line={line=\"%u\",file=\"%s\",line_asm_insn=[ ]}"
@@ -515,13 +512,13 @@ CMICmdCmdDataDisassemble::CreateSelf(void)
//--
CMICmdCmdDataReadMemoryBytes::CMICmdCmdDataReadMemoryBytes(void)
: m_constStrArgThread("thread")
+ , m_constStrArgFrame("frame")
, m_constStrArgByteOffset("o")
- , m_constStrArgAddrStart("address")
+ , m_constStrArgAddrExpr("address")
, m_constStrArgNumBytes("count")
, m_pBufferMemory(nullptr)
, m_nAddrStart(0)
, m_nAddrNumBytesToRead(0)
- , m_nAddrOffset(0)
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "data-read-memory-bytes";
@@ -559,11 +556,13 @@ bool
CMICmdCmdDataReadMemoryBytes::ParseArgs(void)
{
bool bOk =
- m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ bOk = bOk &&
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgFrame, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk =
bOk &&
m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgByteOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgAddrStart, true, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgAddrExpr, true, true, true, true)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumBytes, true, true)));
return (bOk && ParseValidateCmdOptions());
}
@@ -573,32 +572,101 @@ CMICmdCmdDataReadMemoryBytes::ParseArgs(void)
// The command is likely to communicate with the LLDB SBDebugger in here.
// Type: Overridden.
// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
// Throws: None.
//--
bool
CMICmdCmdDataReadMemoryBytes::Execute(void)
{
- CMICMDBASE_GETOPTION(pArgAddrStart, Number, m_constStrArgAddrStart);
- CMICMDBASE_GETOPTION(pArgAddrOffset, Number, m_constStrArgByteOffset);
+ CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
+ CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
+ CMICMDBASE_GETOPTION(pArgAddrOffset, OptionShort, m_constStrArgByteOffset);
+ CMICMDBASE_GETOPTION(pArgAddrExpr, String, m_constStrArgAddrExpr);
CMICMDBASE_GETOPTION(pArgNumBytes, Number, m_constStrArgNumBytes);
- const MIuint64 nAddrStart = pArgAddrStart->GetValue();
+ // get the --thread option value
+ MIuint64 nThreadId = UINT64_MAX;
+ if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
+ m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
+ return MIstatus::failure;
+ }
+
+ // get the --frame option value
+ MIuint64 nFrame = UINT64_MAX;
+ if (pArgFrame->GetFound() && !pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame))
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
+ m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str()));
+ return MIstatus::failure;
+ }
+
+ // get the -o option value
+ MIuint64 nAddrOffset = 0;
+ if (pArgAddrOffset->GetFound() && !pArgAddrOffset->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nAddrOffset))
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
+ m_cmdData.strMiCmd.c_str(), m_constStrArgByteOffset.c_str()));
+ return MIstatus::failure;
+ }
+
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ if (!sbProcess.IsValid())
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ?
+ sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
+ if (!thread.IsValid())
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
+ lldb::SBFrame frame = (nFrame != UINT64_MAX) ?
+ thread.GetFrameAtIndex(nFrame) : thread.GetSelectedFrame();
+ if (!frame.IsValid())
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FRAME_INVALID), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
+ const CMIUtilString &rAddrExpr = pArgAddrExpr->GetValue();
+ lldb::SBValue addrExprValue = frame.EvaluateExpression(rAddrExpr.c_str());
+ lldb::SBError error = addrExprValue.GetError();
+ if (error.Fail())
+ {
+ SetError(error.GetCString());
+ return MIstatus::failure;
+ }
+ else if (!addrExprValue.IsValid())
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_EXPR_INVALID), rAddrExpr.c_str()));
+ return MIstatus::failure;
+ }
+
+ MIuint64 nAddrStart = 0;
+ if (!CMICmnLLDBProxySBValue::GetValueAsUnsigned(addrExprValue, nAddrStart))
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_EXPR_INVALID), rAddrExpr.c_str()));
+ return MIstatus::failure;
+ }
+
+ nAddrStart += nAddrOffset;
const MIuint64 nAddrNumBytes = pArgNumBytes->GetValue();
- if (pArgAddrOffset->GetFound())
- m_nAddrOffset = pArgAddrOffset->GetValue();
- m_pBufferMemory = new MIuchar[nAddrNumBytes];
+ m_pBufferMemory = new unsigned char[nAddrNumBytes];
if (m_pBufferMemory == nullptr)
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_MEMORY_ALLOC_FAILURE), m_cmdData.strMiCmd.c_str(), nAddrNumBytes));
return MIstatus::failure;
}
- CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBError error;
const MIuint64 nReadBytes = sbProcess.ReadMemory(static_cast<lldb::addr_t>(nAddrStart), (void *)m_pBufferMemory, nAddrNumBytes, error);
if (nReadBytes != nAddrNumBytes)
{
@@ -634,14 +702,15 @@ CMICmdCmdDataReadMemoryBytes::Execute(void)
bool
CMICmdCmdDataReadMemoryBytes::Acknowledge(void)
{
- // MI: memory=[{begin=\"0x%08x\",offset=\"0x%08x\",end=\"0x%08x\",contents=\" \" }]"
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%08x", m_nAddrStart));
+ // MI: memory=[{begin=\"0x%016" PRIx64 "\",offset=\"0x%016" PRIx64" \",end=\"0x%016" PRIx64 "\",contents=\" \" }]"
+ const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%016" PRIx64, m_nAddrStart));
const CMICmnMIValueResult miValueResult("begin", miValueConst);
CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("0x%08x", m_nAddrOffset));
+ const MIuint64 nAddrOffset = 0;
+ const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("0x%016" PRIx64, nAddrOffset));
const CMICmnMIValueResult miValueResult2("offset", miValueConst2);
miValueTuple.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("0x%08x", m_nAddrStart + m_nAddrNumBytesToRead));
+ const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("0x%016" PRIx64, m_nAddrStart + m_nAddrNumBytesToRead));
const CMICmnMIValueResult miValueResult3("end", miValueConst3);
miValueTuple.Add(miValueResult3);
@@ -650,7 +719,7 @@ CMICmdCmdDataReadMemoryBytes::Acknowledge(void)
strContent.reserve((m_nAddrNumBytesToRead << 1) + 1);
for (MIuint64 i = 0; i < m_nAddrNumBytesToRead; i++)
{
- strContent += CMIUtilString::Format("%02x", m_pBufferMemory[i]);
+ strContent += CMIUtilString::Format("%02hhx", m_pBufferMemory[i]);
}
const CMICmnMIValueConst miValueConst4(strContent);
const CMICmnMIValueResult miValueResult4("contents", miValueConst4);
@@ -1475,13 +1544,13 @@ CMICmdCmdDataWriteMemory::Execute(void)
m_nCount = pArgNumber->GetValue();
const MIuint64 nValue = pArgContents->GetValue();
- m_pBufferMemory = new MIuchar[m_nCount];
+ m_pBufferMemory = new unsigned char[m_nCount];
if (m_pBufferMemory == nullptr)
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_MEMORY_ALLOC_FAILURE), m_cmdData.strMiCmd.c_str(), m_nCount));
return MIstatus::failure;
}
- *m_pBufferMemory = static_cast<MIchar>(nValue);
+ *m_pBufferMemory = static_cast<char>(nValue);
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
@@ -1537,3 +1606,224 @@ CMICmdCmdDataWriteMemory::CreateSelf(void)
{
return new CMICmdCmdDataWriteMemory();
}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataInfoLine constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataInfoLine::CMICmdCmdDataInfoLine(void)
+ : m_constStrArgLocation("location")
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "data-info-line";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdDataInfoLine::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdDataInfoLine destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdDataInfoLine::~CMICmdCmdDataInfoLine(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
+CMICmdCmdDataInfoLine::ParseArgs(void)
+{
+ bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgLocation, true, 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.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdDataInfoLine::Execute(void)
+{
+ CMICMDBASE_GETOPTION(pArgLocation, String, m_constStrArgLocation);
+
+ const CMIUtilString &strLocation(pArgLocation->GetValue());
+ CMIUtilString strCmdOptionsLocation;
+ if (strLocation.at(0) == '*')
+ {
+ // Parse argument:
+ // *0x12345
+ // ^^^^^^^ -- address
+ const CMIUtilString strAddress(strLocation.c_str() + 1);
+ strCmdOptionsLocation = CMIUtilString::Format("--address %s", strAddress.c_str());
+ }
+ else
+ {
+ const size_t nLineStartPos = strLocation.rfind(':');
+ if ((nLineStartPos == std::string::npos) || (nLineStartPos == 0) || (nLineStartPos == strLocation.length() - 1))
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_LOCATION_FORMAT), m_cmdData.strMiCmd.c_str(), strLocation.c_str())
+ .c_str());
+ return MIstatus::failure;
+ }
+ // Parse argument:
+ // hello.cpp:5
+ // ^^^^^^^^^ -- file
+ // ^ -- line
+ const CMIUtilString strFile(strLocation.substr(0, nLineStartPos).c_str());
+ const CMIUtilString strLine(strLocation.substr(nLineStartPos + 1).c_str());
+ strCmdOptionsLocation = CMIUtilString::Format("--file \"%s\" --line %s", strFile.AddSlashes().c_str(), strLine.c_str());
+ }
+ const CMIUtilString strCmd(CMIUtilString::Format("target modules lookup -v %s", strCmdOptionsLocation.c_str()));
+
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ const lldb::ReturnStatus rtn = rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(strCmd.c_str(), m_lldbResult);
+ MIunused(rtn);
+
+ 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
+CMICmdCmdDataInfoLine::Acknowledge(void)
+{
+ if (m_lldbResult.GetErrorSize() > 0)
+ {
+ const CMICmnMIValueConst miValueConst(m_lldbResult.GetError());
+ const CMICmnMIValueResult miValueResult("msg", miValueConst);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+ else if (m_lldbResult.GetOutputSize() > 0)
+ {
+ CMIUtilString::VecString_t vecLines;
+ const CMIUtilString strLldbMsg(m_lldbResult.GetOutput());
+ const MIuint nLines(strLldbMsg.SplitLines(vecLines));
+
+ for (MIuint i = 0; i < nLines; ++i)
+ {
+ // String looks like:
+ // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
+ const CMIUtilString &rLine(vecLines[i]);
+
+ // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
+ // ^^^^^^^^^ -- property
+ const size_t nPropertyStartPos = rLine.find_first_not_of(' ');
+ const size_t nPropertyEndPos = rLine.find(':');
+ const size_t nPropertyLen = nPropertyEndPos - nPropertyStartPos;
+ const CMIUtilString strProperty(rLine.substr(nPropertyStartPos, nPropertyLen).c_str());
+
+ // Skip all except LineEntry
+ if (!CMIUtilString::Compare(strProperty, "LineEntry"))
+ continue;
+
+ // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
+ // ^^^^^^^^^^^^^^^^^^ -- start address
+ const size_t nStartAddressStartPos = rLine.find("[");
+ const size_t nStartAddressEndPos = rLine.find("-");
+ const size_t nStartAddressLen = nStartAddressEndPos - nStartAddressStartPos - 1;
+ const CMIUtilString strStartAddress(rLine.substr(nStartAddressStartPos + 1, nStartAddressLen).c_str());
+ const CMICmnMIValueConst miValueConst(strStartAddress);
+ const CMICmnMIValueResult miValueResult("start", miValueConst);
+ CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
+
+ // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
+ // ^^^^^^^^^^^^^^^^^^ -- end address
+ const size_t nEndAddressEndPos = rLine.find(")");
+ const size_t nEndAddressLen = nEndAddressEndPos - nStartAddressEndPos - 1;
+ const CMIUtilString strEndAddress(rLine.substr(nStartAddressEndPos + 1, nEndAddressLen).c_str());
+ const CMICmnMIValueConst miValueConst2(strEndAddress);
+ const CMICmnMIValueResult miValueResult2("end", miValueConst2);
+ bool bOk = miRecordResult.Add(miValueResult2);
+ if (!bOk)
+ return MIstatus::failure;
+
+ // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
+ // ^^^^^^^^^^^^^ -- file
+ // ^ -- line
+ // ^ -- column (optional)
+ const size_t nFileStartPos = rLine.find_first_not_of(' ', nEndAddressEndPos + 2);
+ const size_t nFileOrLineEndPos = rLine.rfind(':');
+ const size_t nFileOrLineStartPos = rLine.rfind(':', nFileOrLineEndPos - 1);
+ const size_t nFileEndPos = nFileStartPos < nFileOrLineStartPos ? nFileOrLineStartPos : nFileOrLineEndPos;
+ const size_t nFileLen = nFileEndPos - nFileStartPos;
+ const CMIUtilString strFile(rLine.substr(nFileStartPos, nFileLen).c_str());
+ const CMICmnMIValueConst miValueConst3(strFile);
+ const CMICmnMIValueResult miValueResult3("file", miValueConst3);
+ bOk = miRecordResult.Add(miValueResult3);
+ if (!bOk)
+ return MIstatus::failure;
+
+ // LineEntry: \[0x0000000100000f37-0x0000000100000f45\): /path/to/file:3[:1]
+ // ^ -- line
+ const size_t nLineStartPos = nFileEndPos + 1;
+ const size_t nLineEndPos = rLine.find(':', nLineStartPos);
+ const size_t nLineLen = nLineEndPos != std::string::npos ? nLineEndPos - nLineStartPos - 1
+ : std::string::npos;
+ const CMIUtilString strLine(rLine.substr(nLineStartPos, nLineLen).c_str());
+ const CMICmnMIValueConst miValueConst4(strLine);
+ const CMICmnMIValueResult miValueResult4("line", miValueConst4);
+ bOk = miRecordResult.Add(miValueResult4);
+ if (!bOk)
+ return MIstatus::failure;
+
+ // MI print "%s^done,start=\"%d\",end=\"%d\"",file=\"%s\",line=\"%d\"
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+ }
+ }
+
+ // MI print "%s^error,msg=\"Command '-data-info-line'. Error: The LineEntry is absent or has an unknown format.\""
+ const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SOME_ERROR), m_cmdData.strMiCmd.c_str(), "The LineEntry is absent or has an unknown format."));
+ const CMICmnMIValueResult miValueResult("msg", miValueConst);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
+ 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 *
+CMICmdCmdDataInfoLine::CreateSelf(void)
+{
+ return new CMICmdCmdDataInfoLine();
+}
diff --git a/tools/lldb-mi/MICmdCmdData.h b/tools/lldb-mi/MICmdCmdData.h
index 5084beea6d8f..11873e9cbe4f 100644
--- a/tools/lldb-mi/MICmdCmdData.h
+++ b/tools/lldb-mi/MICmdCmdData.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdData.h
-//
// Overview: CMICmdCmdDataEvaluateExpression interface.
// CMICmdCmdDataDisassemble interface.
// CMICmdCmdDataReadMemoryBytes interface.
@@ -19,6 +16,7 @@
// CMICmdCmdDataListRegisterChanged interface.
// CMICmdCmdDataWriteMemoryBytes interface.
// CMICmdCmdDataWriteMemory interface.
+// CMICmdCmdDataInfoLine interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
@@ -29,15 +27,12 @@
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
+// Third party headers:
+#include "lldb/API/SBCommandReturnObject.h"
+
// In-house headers:
#include "MICmdBase.h"
#include "MICmnMIValueTuple.h"
@@ -73,7 +68,7 @@ class CMICmdCmdDataEvaluateExpression : public CMICmdBase
// Methods:
private:
- bool HaveInvalidCharacterInExpression(const CMIUtilString &vrExpr, MIchar &vrwInvalidChar);
+ bool HaveInvalidCharacterInExpression(const CMIUtilString &vrExpr, char &vrwInvalidChar);
// Attributes:
private:
@@ -83,7 +78,7 @@ class CMICmdCmdDataEvaluateExpression : public CMICmdBase
CMICmnMIValueTuple m_miValueTuple;
bool m_bCompositeVarType; // True = yes composite type, false = internal type
bool m_bFoundInvalidChar; // True = yes found unexpected character in the expression, false = all ok
- MIchar m_cExpressionInvalidChar;
+ char m_cExpressionInvalidChar;
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
const CMIUtilString m_constStrArgFrame; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
const CMIUtilString m_constStrArgExpr;
@@ -155,14 +150,14 @@ class CMICmdCmdDataReadMemoryBytes : public CMICmdBase
// Attributes:
private:
- const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option. Not handled by command.
+ const CMIUtilString m_constStrArgThread; // Not in the MI spec but implemented by GDB.
+ const CMIUtilString m_constStrArgFrame; // Not in the MI spec but implemented by GDB.
const CMIUtilString m_constStrArgByteOffset;
- const CMIUtilString m_constStrArgAddrStart;
+ const CMIUtilString m_constStrArgAddrExpr;
const CMIUtilString m_constStrArgNumBytes;
- MIuchar *m_pBufferMemory;
+ unsigned char *m_pBufferMemory;
MIuint64 m_nAddrStart;
MIuint64 m_nAddrNumBytesToRead;
- MIuint64 m_nAddrOffset;
};
//++ ============================================================================
@@ -373,5 +368,36 @@ class CMICmdCmdDataWriteMemory : public CMICmdBase
MIuint64 m_nAddr;
CMIUtilString m_strContents;
MIuint64 m_nCount;
- MIuchar *m_pBufferMemory;
+ unsigned char *m_pBufferMemory;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "data-info-line".
+// See MIExtensions.txt for details.
+//--
+class CMICmdCmdDataInfoLine : public CMICmdBase
+{
+ // Statics:
+ public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase *CreateSelf(void);
+
+ // Methods:
+ public:
+ /* ctor */ CMICmdCmdDataInfoLine(void);
+
+ // Overridden:
+ public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute(void);
+ virtual bool Acknowledge(void);
+ virtual bool ParseArgs(void);
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdDataInfoLine(void);
+
+ // Attributes:
+ private:
+ lldb::SBCommandReturnObject m_lldbResult;
+ const CMIUtilString m_constStrArgLocation;
};
diff --git a/tools/lldb-mi/MICmdCmdEnviro.cpp b/tools/lldb-mi/MICmdCmdEnviro.cpp
index a4369ab3a990..dd167841032a 100644
--- a/tools/lldb-mi/MICmdCmdEnviro.cpp
+++ b/tools/lldb-mi/MICmdCmdEnviro.cpp
@@ -7,17 +7,7 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdEnviro.cpp
-//
// Overview: CMICmdCmdEnvironmentCd implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// In-house headers:
#include "MICmdCmdEnviro.h"
diff --git a/tools/lldb-mi/MICmdCmdEnviro.h b/tools/lldb-mi/MICmdCmdEnviro.h
index 9a223beb91b0..1fb699e989b6 100644
--- a/tools/lldb-mi/MICmdCmdEnviro.h
+++ b/tools/lldb-mi/MICmdCmdEnviro.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdEnviro.h
-//
// Overview: CMICmdCmdEnvironmentCd interface.
//
// To implement new MI commands derive a new command class from the command base
@@ -20,13 +17,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
diff --git a/tools/lldb-mi/MICmdCmdExec.cpp b/tools/lldb-mi/MICmdCmdExec.cpp
index eec62c8d37e8..f0208c83d58d 100644
--- a/tools/lldb-mi/MICmdCmdExec.cpp
+++ b/tools/lldb-mi/MICmdCmdExec.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdExec.cpp
-//
// Overview: CMICmdCmdExecRun implementation.
// CMICmdCmdExecContinue implementation.
// CMICmdCmdExecNext implementation.
@@ -18,13 +15,8 @@
// CMICmdCmdExecStepInstruction implementation.
// CMICmdCmdExecFinish implementation.
// CMICmdCmdExecInterrupt implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
+// CMICmdCmdExecArguments implementation.
+// CMICmdCmdExecAbort implementation.
// Third Party Headers:
#include "lldb/API/SBCommandInterpreter.h"
@@ -90,10 +82,9 @@ CMICmdCmdExecRun::Execute(void)
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
lldb::SBError error;
lldb::SBStream errMsg;
- uint32_t launch_flags = lldb::LaunchFlags::eLaunchFlagDebug;
- lldb::SBProcess process = rSessionInfo.GetTarget().Launch(rSessionInfo.GetListener(), nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, launch_flags, false, error);
-
+ lldb::SBLaunchInfo launchInfo = rSessionInfo.GetTarget().GetLaunchInfo();
+ launchInfo.SetListener(rSessionInfo.GetListener());
+ lldb::SBProcess process = rSessionInfo.GetTarget().Launch(launchInfo, error);
if ((!process.IsValid()) || (error.Fail()))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str(), errMsg.GetData()));
@@ -207,7 +198,7 @@ CMICmdCmdExecContinue::~CMICmdCmdExecContinue(void)
bool
CMICmdCmdExecContinue::Execute(void)
{
- const MIchar *pCmd = "continue";
+ const char *pCmd = "continue";
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
const lldb::ReturnStatus rtn = rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(pCmd, m_lldbResult);
MIunused(rtn);
@@ -226,7 +217,7 @@ CMICmdCmdExecContinue::Execute(void)
{
// ToDo: Re-evaluate if this is required when application near finished as this is parsing LLDB error message
// which seems a hack and is code brittle
- const MIchar *pLldbErr = m_lldbResult.GetError();
+ const char *pLldbErr = m_lldbResult.GetError();
const CMIUtilString strLldbMsg(CMIUtilString(pLldbErr).StripCREndOfLine());
if (strLldbMsg == "error: Process must be launched.")
{
@@ -376,7 +367,7 @@ CMICmdCmdExecNext::Acknowledge(void)
{
if (m_lldbResult.GetErrorSize() > 0)
{
- const MIchar *pLldbErr = m_lldbResult.GetError();
+ const char *pLldbErr = m_lldbResult.GetError();
MIunused(pLldbErr);
const CMICmnMIValueConst miValueConst(m_lldbResult.GetError());
const CMICmnMIValueResult miValueResult("message", miValueConst);
@@ -503,7 +494,7 @@ CMICmdCmdExecStep::Acknowledge(void)
{
if (m_lldbResult.GetErrorSize() > 0)
{
- const MIchar *pLldbErr = m_lldbResult.GetError();
+ const char *pLldbErr = m_lldbResult.GetError();
MIunused(pLldbErr);
const CMICmnMIValueConst miValueConst(m_lldbResult.GetError());
const CMICmnMIValueResult miValueResult("message", miValueConst);
@@ -630,7 +621,7 @@ CMICmdCmdExecNextInstruction::Acknowledge(void)
{
if (m_lldbResult.GetErrorSize() > 0)
{
- const MIchar *pLldbErr = m_lldbResult.GetError();
+ const char *pLldbErr = m_lldbResult.GetError();
MIunused(pLldbErr);
const CMICmnMIValueConst miValueConst(m_lldbResult.GetError());
const CMICmnMIValueResult miValueResult("message", miValueConst);
@@ -757,7 +748,7 @@ CMICmdCmdExecStepInstruction::Acknowledge(void)
{
if (m_lldbResult.GetErrorSize() > 0)
{
- const MIchar *pLldbErr = m_lldbResult.GetError();
+ const char *pLldbErr = m_lldbResult.GetError();
MIunused(pLldbErr);
const CMICmnMIValueConst miValueConst(m_lldbResult.GetError());
const CMICmnMIValueResult miValueResult("message", miValueConst);
@@ -885,7 +876,7 @@ CMICmdCmdExecFinish::Acknowledge(void)
{
if (m_lldbResult.GetErrorSize() > 0)
{
- const MIchar *pLldbErr = m_lldbResult.GetError();
+ const char *pLldbErr = m_lldbResult.GetError();
MIunused(pLldbErr);
const CMICmnMIValueConst miValueConst(m_lldbResult.GetError());
const CMICmnMIValueResult miValueResult("message", miValueConst);
@@ -1016,3 +1007,215 @@ CMICmdCmdExecInterrupt::CreateSelf(void)
{
return new CMICmdCmdExecInterrupt();
}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecArguments constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecArguments::CMICmdCmdExecArguments(void)
+ : m_constStrArgArguments("arguments")
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "exec-arguments";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdExecArguments::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecArguments destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecArguments::~CMICmdCmdExecArguments(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 - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdExecArguments::ParseArgs(void)
+{
+ bool bOk = m_setCmdArgs.Add(
+ *(new CMICmdArgValListOfN(m_constStrArgArguments, false, true, CMICmdArgValListBase::eArgValType_StringAnything)));
+ 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.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdExecArguments::Execute(void)
+{
+ CMICMDBASE_GETOPTION(pArgArguments, ListOfN, m_constStrArgArguments);
+
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
+ if (!sbTarget.IsValid())
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
+ lldb::SBLaunchInfo sbLaunchInfo = sbTarget.GetLaunchInfo();
+ sbLaunchInfo.SetArguments(NULL, false);
+
+ CMIUtilString strArg;
+ size_t nArgIndex = 0;
+ while (pArgArguments->GetExpectedOption<CMICmdArgValString, CMIUtilString>(strArg, nArgIndex))
+ {
+ const char *argv[2] = { strArg.c_str(), NULL };
+ sbLaunchInfo.SetArguments(argv, true);
+ ++nArgIndex;
+ }
+
+ sbTarget.SetLaunchInfo(sbLaunchInfo);
+
+ 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 - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdExecArguments::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 *
+CMICmdCmdExecArguments::CreateSelf(void)
+{
+ return new CMICmdCmdExecArguments();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecAbort constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecAbort::CMICmdCmdExecAbort(void)
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "exec-abort";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdExecAbort::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdExecAbort destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdExecAbort::~CMICmdCmdExecAbort(void)
+{
+}
+
+//++ ------------------------------------------------------------------------------------
+// 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.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdExecAbort::Execute(void)
+{
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ if (!sbProcess.IsValid())
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
+ lldb::SBError sbError = sbProcess.Destroy();
+ if (sbError.Fail())
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDBPROCESS_DESTROY), m_cmdData.strMiCmd.c_str(), sbError.GetCString()));
+ 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 - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdExecAbort::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 *
+CMICmdCmdExecAbort::CreateSelf(void)
+{
+ return new CMICmdCmdExecAbort();
+}
diff --git a/tools/lldb-mi/MICmdCmdExec.h b/tools/lldb-mi/MICmdCmdExec.h
index be03d6b93566..8889fb96402e 100644
--- a/tools/lldb-mi/MICmdCmdExec.h
+++ b/tools/lldb-mi/MICmdCmdExec.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdExec.h
-//
// Overview: CMICmdCmdExecRun interface.
// CMICmdCmdExecContinue interface.
// CMICmdCmdExecNext interface.
@@ -18,6 +15,8 @@
// CMICmdCmdExecStepInstruction interface.
// CMICmdCmdExecFinish interface.
// CMICmdCmdExecInterrupt interface.
+// CMICmdCmdExecArguments interface.
+// CMICmdCmdExecAbort interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
@@ -27,13 +26,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
@@ -307,3 +299,59 @@ class CMICmdCmdExecInterrupt : public CMICmdBase
private:
lldb::SBCommandReturnObject m_lldbResult;
};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "exec-arguments".
+// Gotchas: None.
+// Authors: Ilia Kirianovskii 25/11/2014.
+// Changes: None.
+//--
+class CMICmdCmdExecArguments : public CMICmdBase
+{
+ // Statics:
+ public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase *CreateSelf(void);
+
+ // Methods:
+ public:
+ /* ctor */ CMICmdCmdExecArguments(void);
+
+ // Overridden:
+ public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute(void);
+ virtual bool Acknowledge(void);
+ virtual bool ParseArgs(void);
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdExecArguments(void);
+
+ // Attributes:
+ private:
+ const CMIUtilString m_constStrArgArguments;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "exec-abort".
+//--
+class CMICmdCmdExecAbort : public CMICmdBase
+{
+ // Statics:
+ public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase *CreateSelf(void);
+
+ // Methods:
+ public:
+ /* ctor */ CMICmdCmdExecAbort(void);
+
+ // Overridden:
+ public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute(void);
+ virtual bool Acknowledge(void);
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdExecAbort(void);
+};
diff --git a/tools/lldb-mi/MICmdCmdFile.cpp b/tools/lldb-mi/MICmdCmdFile.cpp
index 83862f24f1f1..b28060e29f25 100644
--- a/tools/lldb-mi/MICmdCmdFile.cpp
+++ b/tools/lldb-mi/MICmdCmdFile.cpp
@@ -7,17 +7,7 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdFile.cpp
-//
// Overview: CMICmdCmdFileExecAndSymbols implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// Third Party Headers:
#include "lldb/API/SBStream.h"
@@ -29,7 +19,9 @@
#include "MICmnLLDBDebugSessionInfo.h"
#include "MIUtilFileStd.h"
#include "MICmdArgValFile.h"
+#include "MICmdArgValString.h"
#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdFileExecAndSymbols constructor.
@@ -41,6 +33,8 @@
CMICmdCmdFileExecAndSymbols::CMICmdCmdFileExecAndSymbols(void)
: m_constStrArgNameFile("file")
, m_constStrArgThreadGrp("thread-group")
+ , m_constStrArgNamedPlatformName("p")
+ , m_constStrArgNamedRemotePath("r")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "file-exec-and-symbols";
@@ -75,6 +69,12 @@ CMICmdCmdFileExecAndSymbols::ParseArgs(void)
bool bOk = m_setCmdArgs.Add(
*(new CMICmdArgValOptionLong(m_constStrArgThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValFile(m_constStrArgNameFile, true, true)));
+ bOk = bOk &&
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgNamedPlatformName, false, true,
+ CMICmdArgValListBase::eArgValType_String, 1)));
+ bOk = bOk &&
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgNamedRemotePath, false, true,
+ CMICmdArgValListBase::eArgValType_StringQuotedNumberPath, 1)));
return (bOk && ParseValidateCmdOptions());
}
@@ -93,20 +93,28 @@ bool
CMICmdCmdFileExecAndSymbols::Execute(void)
{
CMICMDBASE_GETOPTION(pArgNamedFile, File, m_constStrArgNameFile);
+ CMICMDBASE_GETOPTION(pArgPlatformName, OptionShort, m_constStrArgNamedPlatformName);
+ CMICMDBASE_GETOPTION(pArgRemotePath, OptionShort, m_constStrArgNamedRemotePath);
CMICmdArgValFile *pArgFile = static_cast<CMICmdArgValFile *>(pArgNamedFile);
const CMIUtilString &strExeFilePath(pArgFile->GetValue());
+ bool bPlatformName = pArgPlatformName->GetFound();
+ CMIUtilString platformName;
+ if (bPlatformName)
+ {
+ pArgPlatformName->GetExpectedOption<CMICmdArgValString, CMIUtilString>(platformName);
+ }
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger();
lldb::SBError error;
- const MIchar *pTargetTriple = nullptr; // Let LLDB discover the triple required
- const MIchar *pTargetPlatformName = "";
+ const char *pTargetTriple = nullptr; // Let LLDB discover the triple required
+ const char *pTargetPlatformName = platformName.c_str();
const bool bAddDepModules = false;
lldb::SBTarget target = rDbgr.CreateTarget(strExeFilePath.c_str(), pTargetTriple, pTargetPlatformName, bAddDepModules, error);
CMIUtilString strWkDir;
const CMIUtilString &rStrKeyWkDir(rSessionInfo.m_constStrSharedDataKeyWkDir);
if (!rSessionInfo.SharedDataRetrieve<CMIUtilString>(rStrKeyWkDir, strWkDir))
{
- strWkDir = CMIUtilFileStd().StripOffFileName(strExeFilePath);
+ strWkDir = CMIUtilFileStd::StripOffFileName(strExeFilePath);
if (!rSessionInfo.SharedDataAdd<CMIUtilString>(rStrKeyWkDir, strWkDir))
{
SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), m_cmdData.strMiCmd.c_str(), rStrKeyWkDir.c_str()));
@@ -119,6 +127,16 @@ CMICmdCmdFileExecAndSymbols::Execute(void)
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED), m_cmdData.strMiCmd.c_str(), "SetCurrentPlatformSDKRoot()"));
return MIstatus::failure;
}
+ if (pArgRemotePath->GetFound())
+ {
+ CMIUtilString remotePath;
+ pArgRemotePath->GetExpectedOption<CMICmdArgValString, CMIUtilString>(remotePath);
+ lldb::SBModule module = target.FindModule(target.GetExecutable());
+ if (module.IsValid())
+ {
+ module.SetPlatformFileSpec(lldb::SBFileSpec(remotePath.c_str()));
+ }
+ }
lldb::SBStream err;
if (error.Fail())
{
diff --git a/tools/lldb-mi/MICmdCmdFile.h b/tools/lldb-mi/MICmdCmdFile.h
index 5e23c85daeff..307f4f887aa5 100644
--- a/tools/lldb-mi/MICmdCmdFile.h
+++ b/tools/lldb-mi/MICmdCmdFile.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdFile.h
-//
// Overview: CMICmdCmdFileExecAndSymbols interface.
//
// To implement new MI commands derive a new command class from the command base
@@ -20,13 +17,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
@@ -39,7 +29,8 @@
// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "file-exec-and-symbols".
// This command does not follow the MI documentation exactly.
-// Gotchas: None.
+// Gotchas: This command has additonal flags that were not available in GDB MI.
+// See MIextensions.txt for details.
// Authors: Illya Rudkin 25/02/2014.
// Changes: None.
//--
@@ -69,4 +60,6 @@ class CMICmdCmdFileExecAndSymbols : public CMICmdBase
const CMIUtilString m_constStrArgNameFile;
const CMIUtilString
m_constStrArgThreadGrp; // Not handled by *this command. Not specified in MI spec but Eclipse gives this option sometimes
+ const CMIUtilString m_constStrArgNamedPlatformName; // Added to support iOS platform selection
+ const CMIUtilString m_constStrArgNamedRemotePath; // Added to support iOS device remote file location
};
diff --git a/tools/lldb-mi/MICmdCmdGdbInfo.cpp b/tools/lldb-mi/MICmdCmdGdbInfo.cpp
index be70962b63ae..25e0ff4ffbe8 100644
--- a/tools/lldb-mi/MICmdCmdGdbInfo.cpp
+++ b/tools/lldb-mi/MICmdCmdGdbInfo.cpp
@@ -7,19 +7,10 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdGdbInfo.cpp
-//
// Overview: CMICmdCmdGdbInfo implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// Third party headers:
+#include <inttypes.h> // For PRIx64
#include "lldb/API/SBCommandReturnObject.h"
// In-house headers:
@@ -209,7 +200,7 @@ CMICmdCmdGdbInfo::PrintFnSharedLibrary(void)
const CMIUtilString strModuleFileName(module.GetFileSpec().GetFilename());
const CMIUtilString strModuleFullPath(CMIUtilString::Format("%s/%s", strModuleFilePath.c_str(), strModuleFileName.c_str()));
const CMIUtilString strHasSymbols = (module.GetNumSymbols() > 0) ? "Yes" : "No";
- lldb::addr_t addrLoadS = 0xffffffff;
+ lldb::addr_t addrLoadS = 0xffffffffffffffff;
lldb::addr_t addrLoadSize = 0;
bool bHaveAddrLoad = false;
const MIuint nSections = module.GetNumSections();
@@ -229,7 +220,7 @@ CMICmdCmdGdbInfo::PrintFnSharedLibrary(void)
}
}
bOk = bOk &&
- rStdout.TextToStdout(CMIUtilString::Format("~\"0x%08x\t0x%08x\t%s\t\t%s\"", addrLoadS, addrLoadS + addrLoadSize,
+ rStdout.TextToStdout(CMIUtilString::Format("~\"0x%016" PRIx64 "\t0x%016" PRIx64 "\t%s\t\t%s\"", addrLoadS, addrLoadS + addrLoadSize,
strHasSymbols.c_str(), strModuleFullPath.c_str()));
}
}
diff --git a/tools/lldb-mi/MICmdCmdGdbInfo.h b/tools/lldb-mi/MICmdCmdGdbInfo.h
index 0d45e6c39335..eb60f8277c01 100644
--- a/tools/lldb-mi/MICmdCmdGdbInfo.h
+++ b/tools/lldb-mi/MICmdCmdGdbInfo.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdGdbInfo.h
-//
// Overview: CMICmdCmdGdbInfo interface.
//
// To implement new MI commands derive a new command class from the command base
@@ -20,13 +17,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
diff --git a/tools/lldb-mi/MICmdCmdGdbSet.cpp b/tools/lldb-mi/MICmdCmdGdbSet.cpp
index c1c1bb599fdd..452ac516f2e4 100644
--- a/tools/lldb-mi/MICmdCmdGdbSet.cpp
+++ b/tools/lldb-mi/MICmdCmdGdbSet.cpp
@@ -1,4 +1,4 @@
-//===-- MICmdCmdGdbSet.cpp ------- -------------------------*- C++ -*-===//
+//===-- MICmdCmdGdbSet.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,17 +7,7 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdGdbSet.cpp
-//
// Overview: CMICmdCmdGdbSet implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// In-house headers:
#include "MICmdCmdGdbSet.h"
@@ -30,8 +20,10 @@
// Instantiations:
const CMICmdCmdGdbSet::MapGdbOptionNameToFnGdbOptionPtr_t CMICmdCmdGdbSet::ms_mapGdbOptionNameToFnGdbOptionPtr = {
- // { "target-async", &CMICmdCmdGdbSet::OptionFnTargetAsync }, // Example code if need to implement GDB set other options
+ {"target-async", &CMICmdCmdGdbSet::OptionFnTargetAsync},
+ {"print", &CMICmdCmdGdbSet::OptionFnPrint},
// { "auto-solib-add", &CMICmdCmdGdbSet::OptionFnAutoSolibAdd }, // Example code if need to implement GDB set other options
+ {"output-radix", &CMICmdCmdGdbSet::OptionFnOutputRadix},
{"solib-search-path", &CMICmdCmdGdbSet::OptionFnSolibSearchPath},
{"fallback", &CMICmdCmdGdbSet::OptionFnFallback}};
@@ -89,7 +81,7 @@ CMICmdCmdGdbSet::ParseArgs(void)
}
//++ ------------------------------------------------------------------------------------
-// Details: The invoker requires this function. The command does work in this function.
+// Details: The invoker requires this function. The command is executed in this function.
// The command is likely to communicate with the LLDB SBDebugger in here.
// Type: Overridden.
// Args: None.
@@ -103,7 +95,8 @@ CMICmdCmdGdbSet::Execute(void)
CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(pArgGdbOption->GetExpectedOptions());
- // Get the gdb-set option to carry out
+ // Get the gdb-set option to carry out. This option will be used as an action
+ // which should be done. Further arguments will be used as parameters for it.
CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
const CMICmdArgValString *pOption = static_cast<const CMICmdArgValString *>(*it);
const CMIUtilString strOption(pOption->GetValue());
@@ -142,7 +135,7 @@ CMICmdCmdGdbSet::Execute(void)
//++ ------------------------------------------------------------------------------------
// Details: The invoker requires this function. The command prepares a MI Record Result
-// for the work carried out in the Execute().
+// for the work carried out in the Execute() method.
// Type: Overridden.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
@@ -152,6 +145,8 @@ CMICmdCmdGdbSet::Execute(void)
bool
CMICmdCmdGdbSet::Acknowledge(void)
{
+ // Print error if option isn't recognized:
+ // ^error,msg="The request '%s' was not recognized, not implemented"
if (!m_bGdbOptionRecognised)
{
const CMICmnMIValueConst miValueConst(
@@ -162,6 +157,7 @@ CMICmdCmdGdbSet::Acknowledge(void)
return MIstatus::success;
}
+ // ^done,value="%s"
if (m_bGdbOptionFnSuccessful)
{
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
@@ -169,6 +165,8 @@ CMICmdCmdGdbSet::Acknowledge(void)
return MIstatus::success;
}
+ // Print error if request failed:
+ // ^error,msg="The request '%s' failed.
const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str()));
const CMICmnMIValueResult miValueResult("msg", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
@@ -215,6 +213,98 @@ CMICmdCmdGdbSet::GetOptionFn(const CMIUtilString &vrPrintFnName, FnGdbOptionPtr
}
//++ ------------------------------------------------------------------------------------
+// Details: Carry out work to complete the GDB set option 'target-async' to prepare
+// and send back information asked for.
+// 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
+CMICmdCmdGdbSet::OptionFnTargetAsync(const CMIUtilString::VecString_t &vrWords)
+{
+ bool bAsyncMode = false;
+ bool bOk = true;
+
+ if (vrWords.size() > 1)
+ // Too many arguments.
+ bOk = false;
+ else if (vrWords.size() == 0)
+ // If no arguments, default is "on".
+ bAsyncMode = true;
+ else if (CMIUtilString::Compare(vrWords[0], "on"))
+ bAsyncMode = true;
+ else if (CMIUtilString::Compare(vrWords[0], "off"))
+ bAsyncMode = false;
+ else
+ // Unrecognized argument.
+ bOk = false;
+
+ if (!bOk)
+ {
+ // Report error.
+ m_bGbbOptionFnHasError = true;
+ m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC);
+ return MIstatus::failure;
+ }
+
+ // Turn async mode on/off.
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ rSessionInfo.GetDebugger().SetAsync(bAsyncMode);
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Carry out work to complete the GDB set option 'print-char-array-as-string' to
+// prepare and send back information asked for.
+// 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
+CMICmdCmdGdbSet::OptionFnPrint(const CMIUtilString::VecString_t &vrWords)
+{
+ const bool bAllArgs(vrWords.size() == 2);
+ const bool bArgOn(bAllArgs && (CMIUtilString::Compare(vrWords[1], "on") || CMIUtilString::Compare(vrWords[1], "1")));
+ const bool bArgOff(bAllArgs && (CMIUtilString::Compare(vrWords[1], "off") || CMIUtilString::Compare(vrWords[1], "0")));
+ if (!bAllArgs || (!bArgOn && !bArgOff))
+ {
+ m_bGbbOptionFnHasError = true;
+ m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS);
+ return MIstatus::failure;
+ }
+
+ const CMIUtilString strOption(vrWords[0]);
+ CMIUtilString strOptionKey;
+ if (CMIUtilString::Compare(strOption, "char-array-as-string"))
+ strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
+ else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
+ strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
+ else if (CMIUtilString::Compare(strOption, "aggregate-field-names"))
+ strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
+ else
+ {
+ m_bGbbOptionFnHasError = true;
+ m_strGdbOptionFnError = CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION), strOption.c_str());
+ return MIstatus::failure;
+ }
+
+ const bool bOptionValue(bArgOn);
+ if (!m_rLLDBDebugSessionInfo.SharedDataAdd<bool>(strOptionKey, bOptionValue))
+ {
+ m_bGbbOptionFnHasError = false;
+ SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), m_cmdData.strMiCmd.c_str(), strOptionKey.c_str()));
+ return MIstatus::failure;
+ }
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
// Details: Carry out work to complete the GDB set option 'solib-search-path' to prepare
// and send back information asked for.
// Type: Method.
@@ -248,8 +338,60 @@ CMICmdCmdGdbSet::OptionFnSolibSearchPath(const CMIUtilString::VecString_t &vrWor
}
//++ ------------------------------------------------------------------------------------
-// Details: Carry out work to complete the GDB set option to prepare and send back information
-// asked for.
+// Details: Carry out work to complete the GDB set option 'output-radix' to prepare
+// and send back information asked for.
+// Type: Method.
+// Args: vrWords - (R) List of additional parameters used by this option.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdGdbSet::OptionFnOutputRadix(const CMIUtilString::VecString_t &vrWords)
+{
+ // Check we have at least one argument
+ if (vrWords.size() < 1)
+ {
+ m_bGbbOptionFnHasError = true;
+ m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
+ return MIstatus::failure;
+ }
+ const CMIUtilString &rStrValOutputRadix(vrWords[0]);
+
+ CMICmnLLDBDebugSessionInfoVarObj::varFormat_e format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid;
+ MIint64 radix;
+ if (rStrValOutputRadix.ExtractNumber(radix))
+ {
+ switch (radix)
+ {
+ case 8:
+ format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Octal;
+ break;
+ case 10:
+ format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural;
+ break;
+ case 16:
+ format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Hex;
+ break;
+ default:
+ format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid;
+ break;
+ }
+ }
+ if (format == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid)
+ {
+ m_bGbbOptionFnHasError = false;
+ SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), m_cmdData.strMiCmd.c_str(), "Output Radix"));
+ return MIstatus::failure;
+ }
+ CMICmnLLDBDebugSessionInfoVarObj::VarObjSetFormat(format);
+
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Carry out work to complete the GDB set option to prepare and send back the
+// requested information.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functional succeeded.
@@ -261,8 +403,8 @@ CMICmdCmdGdbSet::OptionFnFallback(const CMIUtilString::VecString_t &vrWords)
{
MIunused(vrWords);
- // Do nothing - intentional. This is a fallback temporary action function to do nothing.
- // This allows the search for gdb-set options to always suceed when the option is not
+ // Do nothing - intentional. This is a fallback function to do nothing.
+ // This allows the search for gdb-set options to always succeed when the option is not
// found (implemented).
return MIstatus::success;
diff --git a/tools/lldb-mi/MICmdCmdGdbSet.h b/tools/lldb-mi/MICmdCmdGdbSet.h
index 59ddc57e1a2d..0095f81838d1 100644
--- a/tools/lldb-mi/MICmdCmdGdbSet.h
+++ b/tools/lldb-mi/MICmdCmdGdbSet.h
@@ -1,4 +1,4 @@
-//===-- MICmdCmdGdbSet.h ------------- ---------------------*- C++ -*-===//
+//===-- MICmdCmdGdbSet.h ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,12 +7,9 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdGdbSet.h
-//
// Overview: CMICmdCmdGdbSet interface.
//
-// To implement new MI commands derive a new command class from the command base
+// To implement new MI commands, derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
// to the command factory. The files of relevance are:
// MICmdCommands.cpp
@@ -20,13 +17,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
@@ -79,7 +69,10 @@ class CMICmdCmdGdbSet : public CMICmdBase
// Methods:
private:
bool GetOptionFn(const CMIUtilString &vrGdbOptionName, FnGdbOptionPtr &vrwpFn) const;
+ bool OptionFnTargetAsync(const CMIUtilString::VecString_t &vrWords);
+ bool OptionFnPrint(const CMIUtilString::VecString_t &vrWords);
bool OptionFnSolibSearchPath(const CMIUtilString::VecString_t &vrWords);
+ bool OptionFnOutputRadix(const CMIUtilString::VecString_t &vrWords);
bool OptionFnFallback(const CMIUtilString::VecString_t &vrWords);
// Attributes:
diff --git a/tools/lldb-mi/MICmdCmdGdbShow.cpp b/tools/lldb-mi/MICmdCmdGdbShow.cpp
new file mode 100644
index 000000000000..f1f40ccbed1a
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdGdbShow.cpp
@@ -0,0 +1,340 @@
+//===-- MICmdCmdGdbShow.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// 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"
+#include "MICmnMIValueConst.h"
+#include "MICmdArgValString.h"
+#include "MICmdArgValListOfN.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+
+// Instantiations:
+const CMICmdCmdGdbShow::MapGdbOptionNameToFnGdbOptionPtr_t CMICmdCmdGdbShow::ms_mapGdbOptionNameToFnGdbOptionPtr = {
+ {"target-async", &CMICmdCmdGdbShow::OptionFnTargetAsync},
+ {"print", &CMICmdCmdGdbShow::OptionFnPrint},
+ {"language", &CMICmdCmdGdbShow::OptionFnLanguage},
+ {"fallback", &CMICmdCmdGdbShow::OptionFnFallback}};
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdGdbShow constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdGdbShow::CMICmdCmdGdbShow(void)
+ : m_constStrArgNamedThreadGrp("thread-group")
+ , m_constStrArgNamedGdbOption("option")
+ , m_bGdbOptionRecognised(true)
+ , m_bGdbOptionFnSuccessful(false)
+ , m_bGbbOptionFnHasError(false)
+ , m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS))
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "gdb-show";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdGdbShow::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdGdbShow destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdGdbShow::~CMICmdCmdGdbShow(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 - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdGdbShow::ParseArgs(void)
+{
+ bool bOk = m_setCmdArgs.Add(
+ *(new CMICmdArgValOptionLong(m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1)));
+ bOk = bOk &&
+ m_setCmdArgs.Add(
+ *(new CMICmdArgValListOfN(m_constStrArgNamedGdbOption, true, true, CMICmdArgValListBase::eArgValType_StringAnything)));
+ return (bOk && ParseValidateCmdOptions());
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: The invoker requires this function. The command is executed in this function.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdGdbShow::Execute(void)
+{
+ CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
+ const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(pArgGdbOption->GetExpectedOptions());
+
+ // Get the gdb-show option to carry out. This option will be used as an action
+ // which should be done. Further arguments will be used as parameters for it.
+ CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
+ const CMICmdArgValString *pOption = static_cast<const CMICmdArgValString *>(*it);
+ const CMIUtilString strOption(pOption->GetValue());
+ ++it;
+
+ // Retrieve the parameter(s) for the option
+ CMIUtilString::VecString_t vecWords;
+ while (it != rVecWords.end())
+ {
+ const CMICmdArgValString *pWord = static_cast<const CMICmdArgValString *>(*it);
+ vecWords.push_back(pWord->GetValue());
+
+ // Next
+ ++it;
+ }
+
+ FnGdbOptionPtr pPrintRequestFn = nullptr;
+ if (!GetOptionFn(strOption, pPrintRequestFn))
+ {
+ // For unimplemented option handlers, fallback to a generic handler
+ // ToDo: Remove this when ALL options have been implemented
+ if (!GetOptionFn("fallback", pPrintRequestFn))
+ {
+ m_bGdbOptionRecognised = false;
+ m_strGdbOptionName = "fallback"; // This would be the strOption name
+ return MIstatus::success;
+ }
+ }
+
+ m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords);
+ if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError)
+ 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() method.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdGdbShow::Acknowledge(void)
+{
+ // Print error if option isn't recognized:
+ // ^error,msg="The request '%s' was not recognized, not implemented"
+ if (!m_bGdbOptionRecognised)
+ {
+ const CMICmnMIValueConst miValueConst(
+ CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND), m_strGdbOptionName.c_str()));
+ const CMICmnMIValueResult miValueResult("msg", miValueConst);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ // ^done,value="%s"
+ if (m_bGdbOptionFnSuccessful && !m_strValue.empty())
+ {
+ const CMICmnMIValueConst miValueConst(m_strValue);
+ const CMICmnMIValueResult miValueResult("value", miValueConst);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+ else if (m_bGdbOptionFnSuccessful)
+ {
+ // Ignore empty value (for fallback)
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ // Print error if request failed:
+ // ^error,msg="The request '%s' failed.
+ const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str()));
+ const CMICmnMIValueResult miValueResult("msg", miValueConst);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
+ 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 *
+CMICmdCmdGdbShow::CreateSelf(void)
+{
+ return new CMICmdCmdGdbShow();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the print function's pointer for the matching print request.
+// Type: Method.
+// Args: vrPrintFnName - (R) The info requested.
+// vrwpFn - (W) The print function's pointer of the function to carry out
+// Return: bool - True = Print request is implemented, false = not found.
+// Throws: None.
+//--
+bool
+CMICmdCmdGdbShow::GetOptionFn(const CMIUtilString &vrPrintFnName, FnGdbOptionPtr &vrwpFn) const
+{
+ vrwpFn = nullptr;
+
+ const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it = ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName);
+ if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end())
+ {
+ vrwpFn = (*it).second;
+ return true;
+ }
+
+ return false;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Carry out work to complete the GDB show option 'target-async' 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::OptionFnTargetAsync(const CMIUtilString::VecString_t &vrWords)
+{
+ MIunused(vrWords);
+
+ // Get async mode
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ const bool bAsyncMode = rSessionInfo.GetDebugger().GetAsync();
+
+ m_strValue = bAsyncMode ? "on" : "off";
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Carry out work to complete the GDB show option 'print' 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::OptionFnPrint(const CMIUtilString::VecString_t &vrWords)
+{
+ const bool bAllArgs(vrWords.size() == 1);
+ if (!bAllArgs)
+ {
+ m_bGbbOptionFnHasError = true;
+ m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS);
+ return MIstatus::failure;
+ }
+
+ const CMIUtilString strOption(vrWords[0]);
+ CMIUtilString strOptionKey;
+ bool bOptionValueDefault = false;
+ if (CMIUtilString::Compare(strOption, "char-array-as-string"))
+ strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
+ else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
+ strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
+ else if (CMIUtilString::Compare(strOption, "aggregate-field-names"))
+ {
+ strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
+ bOptionValueDefault = true;
+ }
+ else
+ {
+ m_bGbbOptionFnHasError = true;
+ m_strGdbOptionFnError = CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION), strOption.c_str());
+ return MIstatus::failure;
+ }
+
+ bool bOptionValue = false;
+ bOptionValue = bOptionValueDefault ? !m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(strOptionKey, bOptionValue) || bOptionValue
+ : m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(strOptionKey, bOptionValue) && bOptionValue;
+
+ m_strValue = bOptionValue ? "on" : "off";
+ return MIstatus::success;
+}
+
+//++ ------------------------------------------------------------------------------------
+// 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.
+// Args: None.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdGdbShow::OptionFnFallback(const CMIUtilString::VecString_t &vrWords)
+{
+ MIunused(vrWords);
+
+ // Do nothing - intentional. This is a fallback function to do nothing.
+ // This allows the search for gdb-show options to always succeed when the option is not
+ // found (implemented).
+
+ return MIstatus::success;
+}
diff --git a/tools/lldb-mi/MICmdCmdGdbShow.h b/tools/lldb-mi/MICmdCmdGdbShow.h
new file mode 100644
index 000000000000..5cb4cb58f809
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdGdbShow.h
@@ -0,0 +1,86 @@
+//===-- MICmdCmdGdbShow.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Overview: CMICmdCmdGdbShow interface.
+//
+// To implement new MI commands, derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+
+#pragma once
+
+// In-house headers:
+#include "MICmdBase.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "gdb-show".
+// This command does not follow the MI documentation exactly. While *this
+// command is implemented it does not do anything with the gdb-set
+// variable past in.
+// The design of matching the info request to a request action (or
+// command) is very simple. The request function which carries out
+// the task of information gathering and printing to stdout is part of
+// *this class. Should the request function become more complicated then
+// that request should really reside in a command type class. Then this
+// class instantiates a request info command for a matching request. The
+// design/code of *this class then does not then become bloated. Use a
+// lightweight version of the current MI command system.
+//--
+class CMICmdCmdGdbShow : public CMICmdBase
+{
+ // Statics:
+ public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase *CreateSelf(void);
+
+ // Methods:
+ public:
+ /* ctor */ CMICmdCmdGdbShow(void);
+
+ // Overridden:
+ public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute(void);
+ virtual bool Acknowledge(void);
+ virtual bool ParseArgs(void);
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdGdbShow(void);
+
+ // Typedefs:
+ private:
+ typedef bool (CMICmdCmdGdbShow::*FnGdbOptionPtr)(const CMIUtilString::VecString_t &vrWords);
+ typedef std::map<CMIUtilString, FnGdbOptionPtr> MapGdbOptionNameToFnGdbOptionPtr_t;
+
+ // Methods:
+ private:
+ 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:
+ private:
+ const static MapGdbOptionNameToFnGdbOptionPtr_t ms_mapGdbOptionNameToFnGdbOptionPtr;
+ //
+ const CMIUtilString m_constStrArgNamedThreadGrp;
+ const CMIUtilString m_constStrArgNamedGdbOption;
+ bool m_bGdbOptionRecognised; // True = This command has a function with a name that matches the Print argument, false = not found
+ bool m_bGdbOptionFnSuccessful; // True = The print function completed its task ok, false = function failed for some reason
+ bool m_bGbbOptionFnHasError; // True = The option function has an error condition (not the command!), false = option function ok.
+ CMIUtilString m_strGdbOptionName;
+ CMIUtilString m_strGdbOptionFnError;
+ CMIUtilString m_strValue;
+};
diff --git a/tools/lldb-mi/MICmdCmdGdbThread.cpp b/tools/lldb-mi/MICmdCmdGdbThread.cpp
index e840338a2e41..40f2eeccb6b4 100644
--- a/tools/lldb-mi/MICmdCmdGdbThread.cpp
+++ b/tools/lldb-mi/MICmdCmdGdbThread.cpp
@@ -7,17 +7,7 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdGdbThread.cpp
-//
// Overview: CMICmdCmdGdbThread implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// In-house headers:
#include "MICmdCmdGdbThread.h"
diff --git a/tools/lldb-mi/MICmdCmdGdbThread.h b/tools/lldb-mi/MICmdCmdGdbThread.h
index 5fac70b8b39a..a4b8596a47c1 100644
--- a/tools/lldb-mi/MICmdCmdGdbThread.h
+++ b/tools/lldb-mi/MICmdCmdGdbThread.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdGdbThread.h
-//
// Overview: CMICmdCmdGdbThread interface.
//
// To implement new MI commands derive a new command class from the command base
@@ -20,13 +17,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
diff --git a/tools/lldb-mi/MICmdCmdMiscellanous.cpp b/tools/lldb-mi/MICmdCmdMiscellanous.cpp
index 4e4e1b986e8a..37cae404ad7d 100644
--- a/tools/lldb-mi/MICmdCmdMiscellanous.cpp
+++ b/tools/lldb-mi/MICmdCmdMiscellanous.cpp
@@ -7,20 +7,10 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdMiscellanous.cpp
-//
// Overview: CMICmdCmdGdbExit implementation.
// CMICmdCmdListThreadGroups implementation.
// CMICmdCmdInterpreterExec implementation.
// CMICmdCmdInferiorTtySet implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// Third Party Headers:
#include "lldb/API/SBCommandInterpreter.h"
@@ -84,7 +74,7 @@ bool
CMICmdCmdGdbExit::Execute(void)
{
CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag(true);
- const lldb::SBError sbErr = m_rLLDBDebugSessionInfo.GetProcess().Detach();
+ const lldb::SBError sbErr = m_rLLDBDebugSessionInfo.GetProcess().Destroy();
// Do not check for sbErr.Fail() here, m_lldbProcess is likely !IsValid()
return MIstatus::success;
@@ -249,7 +239,7 @@ CMICmdCmdListThreadGroups::Execute(void)
if (thread.IsValid())
{
CMICmnMIValueTuple miTuple;
- if (!rSessionInfo.MIResponseFormThreadInfo2(m_cmdData, thread, miTuple))
+ if (!rSessionInfo.MIResponseFormThreadInfo(m_cmdData, thread, CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_NoFrames, miTuple))
return MIstatus::failure;
m_vecMIValueTuple.push_back(miTuple);
@@ -340,8 +330,8 @@ CMICmdCmdListThreadGroups::Acknowledge(void)
if (rSessionInfo.GetTarget().IsValid())
{
lldb::SBTarget sbTrgt = rSessionInfo.GetTarget();
- const MIchar *pDir = sbTrgt.GetExecutable().GetDirectory();
- const MIchar *pFileName = sbTrgt.GetExecutable().GetFilename();
+ const char *pDir = sbTrgt.GetExecutable().GetDirectory();
+ const char *pFileName = sbTrgt.GetExecutable().GetFilename();
const CMIUtilString strFile(CMIUtilString::Format("%s/%s", pDir, pFileName));
const CMICmnMIValueConst miValueConst4(strFile);
const CMICmnMIValueResult miValueResult4("executable", miValueConst4);
@@ -409,7 +399,7 @@ CMICmdCmdListThreadGroups::CreateSelf(void)
// Throws: None.
//--
CMICmdCmdInterpreterExec::CMICmdCmdInterpreterExec(void)
- : m_constStrArgNamedInterpreter("intepreter")
+ : m_constStrArgNamedInterpreter("interpreter")
, m_constStrArgNamedCommand("command")
{
// Command factory matches this name with that received from the stdin stream
@@ -493,19 +483,12 @@ CMICmdCmdInterpreterExec::Acknowledge(void)
CMIUtilString strMsg(m_lldbResult.GetOutput());
strMsg = strMsg.StripCREndOfLine();
CMICmnStreamStdout::TextToStdout(strMsg);
-
- // Send the LLDB result message to console so the user can see the result of the
- // command they typed. It is not necessary an error message.
- CMICmnStreamStderr::LLDBMsgToConsole(strMsg);
}
if (m_lldbResult.GetErrorSize() > 0)
{
CMIUtilString strMsg(m_lldbResult.GetError());
strMsg = strMsg.StripCREndOfLine();
CMICmnStreamStderr::LLDBMsgToConsole(strMsg);
-
- // Send LLDB's error message to the MI Driver's Log file
- CMICmnStreamStdout::TextToStdout(strMsg);
}
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
diff --git a/tools/lldb-mi/MICmdCmdMiscellanous.h b/tools/lldb-mi/MICmdCmdMiscellanous.h
index fd990940e44d..ffc691cdc927 100644
--- a/tools/lldb-mi/MICmdCmdMiscellanous.h
+++ b/tools/lldb-mi/MICmdCmdMiscellanous.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdMiscellanous.h
-//
// Overview: CMICmdCmdGdbExit interface.
// CMICmdCmdListThreadGroups interface.
// CMICmdCmdInterpreterExec interface.
@@ -23,13 +20,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
diff --git a/tools/lldb-mi/MICmdCmdStack.cpp b/tools/lldb-mi/MICmdCmdStack.cpp
index 4ab7164a30b7..7f767e727f97 100644
--- a/tools/lldb-mi/MICmdCmdStack.cpp
+++ b/tools/lldb-mi/MICmdCmdStack.cpp
@@ -7,20 +7,12 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdStack.cpp
-//
// Overview: CMICmdCmdStackInfoDepth implementation.
+// CMICmdCmdStackInfoFrame implementation.
// CMICmdCmdStackListFrames implementation.
// CMICmdCmdStackListArguments implementation.
// CMICmdCmdStackListLocals implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
+// CMICmdCmdStackSelectFrame implementation.
// Third Party Headers:
#include "lldb/API/SBThread.h"
@@ -37,6 +29,7 @@
#include "MICmdArgValThreadGrp.h"
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValPrintValues.h"
#include "MICmdArgValListOfN.h"
//++ ------------------------------------------------------------------------------------
@@ -158,6 +151,113 @@ CMICmdCmdStackInfoDepth::CreateSelf(void)
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackInfoFrame constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackInfoFrame::CMICmdCmdStackInfoFrame(void)
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-info-frame";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackInfoFrame::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackInfoFrame destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackInfoFrame::~CMICmdCmdStackInfoFrame(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 - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdStackInfoFrame::ParseArgs(void)
+{
+ return 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.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdStackInfoFrame::Execute(void)
+{
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ if (!sbProcess.IsValid())
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
+ lldb::SBThread sbThread = sbProcess.GetSelectedThread();
+ MIuint nFrameId = sbThread.GetSelectedFrame().GetFrameID();
+ if (!rSessionInfo.MIResponseFormFrameInfo(sbThread, nFrameId, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments, m_miValueTuple))
+ 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 - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdStackInfoFrame::Acknowledge(void)
+{
+ const CMICmnMIValueResult miValueResult("frame", m_miValueTuple);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
+ 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 *
+CMICmdCmdStackInfoFrame::CreateSelf(void)
+{
+ return new CMICmdCmdStackInfoFrame();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdStackListFrames constructor.
// Type: Method.
// Args: None.
@@ -257,7 +357,7 @@ CMICmdCmdStackListFrames::Execute(void)
for (MIuint nLevel = nFrameLow; nLevel < nThreadFrames; nLevel++)
{
CMICmnMIValueTuple miValueTuple;
- if (!rSessionInfo.MIResponseFormFrameInfo(thread, nLevel, miValueTuple))
+ if (!rSessionInfo.MIResponseFormFrameInfo(thread, nLevel, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments, miValueTuple))
return MIstatus::failure;
const CMICmnMIValueResult miValueResult8("frame", miValueTuple);
@@ -350,9 +450,8 @@ CMICmdCmdStackListArguments::CMICmdCmdStackListArguments(void)
, m_miValueList(true)
, m_constStrArgThread("thread")
, m_constStrArgPrintValues("print-values")
- , m_constStrArgNoValues("no-values")
- , m_constStrArgAllValues("all-values")
- , m_constStrArgSimpleValues("simple-values")
+ , m_constStrArgFrameLow("low-frame")
+ , m_constStrArgFrameHigh("high-frame")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "stack-list-arguments";
@@ -386,10 +485,9 @@ CMICmdCmdStackListArguments::ParseArgs(void)
{
bool bOk =
m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, true)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgNoValues, false, true)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgAllValues, false, true)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgSimpleValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgFrameLow, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgFrameHigh, false, true)));
return (bOk && ParseValidateCmdOptions());
}
@@ -406,10 +504,9 @@ bool
CMICmdCmdStackListArguments::Execute(void)
{
CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
- CMICMDBASE_GETOPTION(pArgPrintValues, Number, m_constStrArgPrintValues);
- CMICMDBASE_GETOPTION(pArgNoValues, OptionLong, m_constStrArgNoValues);
- CMICMDBASE_GETOPTION(pArgAllValues, OptionLong, m_constStrArgAllValues);
- CMICMDBASE_GETOPTION(pArgSimpleValues, OptionLong, m_constStrArgSimpleValues);
+ CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
+ CMICMDBASE_GETOPTION(pArgFrameLow, Number, m_constStrArgFrameLow);
+ CMICMDBASE_GETOPTION(pArgFrameHigh, Number, m_constStrArgFrameHigh);
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
@@ -422,26 +519,19 @@ CMICmdCmdStackListArguments::Execute(void)
}
}
- CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat;
- if (pArgPrintValues->GetFound())
+ const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(pArgPrintValues->GetValue());
+
+ MIuint nFrameLow = 0;
+ MIuint nFrameHigh = UINT32_MAX;
+ if (pArgFrameLow->GetFound() && pArgFrameHigh->GetFound())
{
- const MIuint nPrintValues = pArgPrintValues->GetValue();
- if (nPrintValues >= CMICmnLLDBDebugSessionInfo::kNumVariableInfoFormats)
- {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
- eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(nPrintValues);
+ nFrameLow = pArgFrameLow->GetValue();
+ nFrameHigh = pArgFrameHigh->GetValue() + 1;
}
- else if (pArgNoValues->GetFound())
- eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
- else if (pArgAllValues->GetFound())
- eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues;
- else if (pArgSimpleValues->GetFound())
- eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues;
- else
+ else if (pArgFrameLow->GetFound() || pArgFrameHigh->GetFound())
{
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
+ // Only low-frame or high-frame was specified but both are required
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID), m_cmdData.strMiCmd.c_str()));
return MIstatus::failure;
}
@@ -460,12 +550,20 @@ CMICmdCmdStackListArguments::Execute(void)
}
const MIuint nFrames = thread.GetNumFrames();
- for (MIuint i = 0; i < nFrames; i++)
+ if (nFrameLow >= nFrames)
+ {
+ // The low-frame is larger than the actual number of frames
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_FRAME_RANGE_INVALID), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
+ nFrameHigh = std::min(nFrameHigh, nFrames);
+ for (MIuint i = nFrameLow; i < nFrameHigh; i++)
{
lldb::SBFrame frame = thread.GetFrameAtIndex(i);
CMICmnMIValueList miValueList(true);
const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
- if (!rSessionInfo.MIResponseFormVariableInfo3(frame, maskVarTypes, eVarInfoFormat, miValueList))
+ if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes, eVarInfoFormat, miValueList))
return MIstatus::failure;
const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", i));
const CMICmnMIValueResult miValueResult("level", miValueConst);
@@ -540,9 +638,6 @@ CMICmdCmdStackListLocals::CMICmdCmdStackListLocals(void)
, m_constStrArgThread("thread")
, m_constStrArgFrame("frame")
, m_constStrArgPrintValues("print-values")
- , m_constStrArgNoValues("no-values")
- , m_constStrArgAllValues("all-values")
- , m_constStrArgSimpleValues("simple-values")
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "stack-list-locals";
@@ -578,10 +673,7 @@ CMICmdCmdStackListLocals::ParseArgs(void)
m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
bOk = bOk &&
m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgFrame, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, true)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgNoValues, false, true)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgAllValues, false, true)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgSimpleValues, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, true)));
return (bOk && ParseValidateCmdOptions());
}
@@ -599,10 +691,7 @@ CMICmdCmdStackListLocals::Execute(void)
{
CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
- CMICMDBASE_GETOPTION(pArgPrintValues, Number, m_constStrArgPrintValues);
- CMICMDBASE_GETOPTION(pArgNoValues, OptionLong, m_constStrArgNoValues);
- CMICMDBASE_GETOPTION(pArgAllValues, OptionLong, m_constStrArgAllValues);
- CMICMDBASE_GETOPTION(pArgSimpleValues, OptionLong, m_constStrArgSimpleValues);
+ CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
// Retrieve the --thread option's thread ID (only 1)
MIuint64 nThreadId = UINT64_MAX;
@@ -625,28 +714,7 @@ CMICmdCmdStackListLocals::Execute(void)
}
}
- CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat;
- if (pArgPrintValues->GetFound())
- {
- const MIuint nPrintValues = pArgPrintValues->GetValue();
- if (nPrintValues >= CMICmnLLDBDebugSessionInfo::kNumVariableInfoFormats)
- {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
- eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(nPrintValues);
- }
- else if (pArgNoValues->GetFound())
- eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
- else if (pArgAllValues->GetFound())
- eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues;
- else if (pArgSimpleValues->GetFound())
- eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues;
- else
- {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
- return MIstatus::failure;
- }
+ const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(pArgPrintValues->GetValue());
CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
@@ -717,3 +785,288 @@ CMICmdCmdStackListLocals::CreateSelf(void)
{
return new CMICmdCmdStackListLocals();
}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackListVariables constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListVariables::CMICmdCmdStackListVariables(void)
+ : m_bThreadInvalid(false)
+ , m_miValueList(true)
+ , m_constStrArgThread("thread")
+ , m_constStrArgFrame("frame")
+ , m_constStrArgPrintValues("print-values")
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-list-variables";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackListVariables::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackListVariables destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackListVariables::~CMICmdCmdStackListVariables(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
+CMICmdCmdStackListVariables::ParseArgs(void)
+{
+ bool bOk =
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ bOk = bOk &&
+ m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgFrame, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValPrintValues(m_constStrArgPrintValues, true, 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.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdStackListVariables::Execute(void)
+{
+ CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
+ CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
+ CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
+
+ // Retrieve the --thread option's thread ID (only 1)
+ MIuint64 nThreadId = UINT64_MAX;
+ if (pArgThread->GetFound())
+ {
+ if (!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
+ return MIstatus::failure;
+ }
+ }
+
+ MIuint64 nFrame = UINT64_MAX;
+ if (pArgFrame->GetFound())
+ {
+ if (!pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame))
+ {
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgFrame.c_str()));
+ return MIstatus::failure;
+ }
+ }
+
+ const CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(pArgPrintValues->GetValue());
+
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
+ lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
+ m_bThreadInvalid = !thread.IsValid();
+ if (m_bThreadInvalid)
+ return MIstatus::success;
+
+ const lldb::StopReason eStopReason = thread.GetStopReason();
+ if ((eStopReason == lldb::eStopReasonNone) || (eStopReason == lldb::eStopReasonInvalid))
+ {
+ m_bThreadInvalid = true;
+ return MIstatus::success;
+ }
+
+ lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame) : thread.GetSelectedFrame();
+
+ CMICmnMIValueList miValueList(true);
+ const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments | CMICmnLLDBDebugSessionInfo::eVariableType_Locals;
+ if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes, eVarInfoFormat, miValueList, 10, true))
+ return MIstatus::failure;
+ m_miValueList = miValueList;
+
+ 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
+CMICmdCmdStackListVariables::Acknowledge(void)
+{
+ if (m_bThreadInvalid)
+ {
+ // MI print "%s^done,variables=[]"
+ const CMICmnMIValueList miValueList(true);
+ const CMICmnMIValueResult miValueResult("variables", miValueList);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
+ m_miResultRecord = miRecordResult;
+ return MIstatus::success;
+ }
+
+ // MI print "%s^done,variables=[%s]"
+ const CMICmnMIValueResult miValueResult("variables", m_miValueList);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
+ 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 *
+CMICmdCmdStackListVariables::CreateSelf(void)
+{
+ return new CMICmdCmdStackListVariables();
+}
+
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackSelectFrame constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackSelectFrame::CMICmdCmdStackSelectFrame(void)
+ : m_bFrameInvalid(false)
+ , m_constStrArgFrame("frame")
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "stack-select-frame";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdStackSelectFrame::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdStackSelectFrame destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdStackSelectFrame::~CMICmdCmdStackSelectFrame(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 - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdStackSelectFrame::ParseArgs(void)
+{
+ bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgFrame, true, false)));
+ 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.
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdStackSelectFrame::Execute(void)
+{
+ CMICMDBASE_GETOPTION(pArgFrame, Number, m_constStrArgFrame);
+
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();
+
+ const MIuint nFrameId = pArgFrame->GetValue();
+ m_bFrameInvalid = (nFrameId >= sbThread.GetNumFrames());
+ if (m_bFrameInvalid)
+ return MIstatus::success;
+
+ lldb::SBFrame sbFrame = sbThread.SetSelectedFrame(nFrameId);
+ m_bFrameInvalid = !sbFrame.IsValid();
+
+ 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 - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdStackSelectFrame::Acknowledge(void)
+{
+ if (m_bFrameInvalid)
+ {
+ // MI print "%s^error,msg=\"Command '-stack-select-frame'. Frame ID invalid\""
+ const CMICmnMIValueConst miValueConst(
+ CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FRAME_INVALID), m_cmdData.strMiCmd.c_str()));
+ const CMICmnMIValueResult miValueResult("msg", miValueConst);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
+ m_miResultRecord = miRecordResult;
+
+ return MIstatus::success;
+ }
+
+ 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 *
+CMICmdCmdStackSelectFrame::CreateSelf(void)
+{
+ return new CMICmdCmdStackSelectFrame();
+}
diff --git a/tools/lldb-mi/MICmdCmdStack.h b/tools/lldb-mi/MICmdCmdStack.h
index ebef7e197f5f..ed141fcf942f 100644
--- a/tools/lldb-mi/MICmdCmdStack.h
+++ b/tools/lldb-mi/MICmdCmdStack.h
@@ -7,13 +7,12 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdStack.h
-//
// Overview: CMICmdCmdStackInfoDepth interface.
+// CMICmdCmdStackInfoFrame interface.
// CMICmdCmdStackListFrames interface.
// CMICmdCmdStackListArguments interface.
// CMICmdCmdStackListLocals interface.
+// CMICmdCmdStackSelectFrame interface.
//
// To implement new MI commands derive a new command class from the command base
// class. To enable the new command for interpretation add the new command class
@@ -23,19 +22,13 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
// In-house headers:
#include "MICmdBase.h"
#include "MICmnMIValueList.h"
+#include "MICmnMIValueTuple.h"
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
@@ -73,6 +66,35 @@ class CMICmdCmdStackInfoDepth : public CMICmdBase
//++ ============================================================================
// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "stack-info-frame".
+//--
+class CMICmdCmdStackInfoFrame : public CMICmdBase
+{
+ // Statics:
+ public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase *CreateSelf(void);
+
+ // Methods:
+ public:
+ /* ctor */ CMICmdCmdStackInfoFrame(void);
+
+ // Overridden:
+ public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute(void);
+ virtual bool Acknowledge(void);
+ virtual bool ParseArgs(void);
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdStackInfoFrame(void);
+
+ // Attributes:
+ private:
+ CMICmnMIValueTuple m_miValueTuple;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
// *this class implements MI command "stack-list-frames".
// Gotchas: None.
// Authors: Illya Rudkin 21/03/2014.
@@ -144,9 +166,8 @@ class CMICmdCmdStackListArguments : public CMICmdBase
CMICmnMIValueList m_miValueList;
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgPrintValues;
- const CMIUtilString m_constStrArgNoValues;
- const CMIUtilString m_constStrArgAllValues;
- const CMIUtilString m_constStrArgSimpleValues;
+ const CMIUtilString m_constStrArgFrameLow;
+ const CMIUtilString m_constStrArgFrameHigh;
};
//++ ============================================================================
@@ -183,7 +204,67 @@ class CMICmdCmdStackListLocals : public CMICmdBase
const CMIUtilString m_constStrArgThread; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgFrame; // Not specified in MI spec but Eclipse gives this option
const CMIUtilString m_constStrArgPrintValues;
- const CMIUtilString m_constStrArgNoValues;
- const CMIUtilString m_constStrArgAllValues;
- const CMIUtilString m_constStrArgSimpleValues;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "stack-list-variables".
+//--
+class CMICmdCmdStackListVariables : public CMICmdBase
+{
+ // Statics:
+public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase *CreateSelf(void);
+
+ // Methods:
+public:
+ /* ctor */ CMICmdCmdStackListVariables(void);
+
+ // Overridden:
+public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute(void);
+ virtual bool Acknowledge(void);
+ virtual bool ParseArgs(void);
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdStackListVariables(void);
+
+ // Attributes
+private:
+ bool m_bThreadInvalid; // True = yes invalid thread, false = thread object valid
+ CMICmnMIValueList m_miValueList;
+ const CMIUtilString m_constStrArgThread;
+ const CMIUtilString m_constStrArgFrame;
+ const CMIUtilString m_constStrArgPrintValues;
+};
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "stack-select-frame".
+//--
+class CMICmdCmdStackSelectFrame : public CMICmdBase
+{
+ // Statics:
+ public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase *CreateSelf(void);
+
+ // Methods:
+ public:
+ /* ctor */ CMICmdCmdStackSelectFrame(void);
+
+ // Overridden:
+ public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute(void);
+ virtual bool Acknowledge(void);
+ virtual bool ParseArgs(void);
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdStackSelectFrame(void);
+
+ // Attributes:
+ private:
+ bool m_bFrameInvalid; // True = yes invalid frame, false = ok
+ const CMIUtilString m_constStrArgFrame;
};
diff --git a/tools/lldb-mi/MICmdCmdSupportInfo.cpp b/tools/lldb-mi/MICmdCmdSupportInfo.cpp
index c2fc572f8c17..2d04ef8dddf9 100644
--- a/tools/lldb-mi/MICmdCmdSupportInfo.cpp
+++ b/tools/lldb-mi/MICmdCmdSupportInfo.cpp
@@ -7,17 +7,7 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdSupportListInfo.cpp
-//
// Overview: CMICmdCmdSupportInfoMiCmdQuery implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// In-house headers:
#include "MICmdCmdSupportInfo.h"
diff --git a/tools/lldb-mi/MICmdCmdSupportInfo.h b/tools/lldb-mi/MICmdCmdSupportInfo.h
index b643d4af1aa4..a8c22526484d 100644
--- a/tools/lldb-mi/MICmdCmdSupportInfo.h
+++ b/tools/lldb-mi/MICmdCmdSupportInfo.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdSupportInfo.h
-//
// Overview: CMICmdCmdSupportInfoMiCmdQuery interface.
//
// To implement new MI commands derive a new command class from the command base
@@ -20,13 +17,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
diff --git a/tools/lldb-mi/MICmdCmdSupportList.cpp b/tools/lldb-mi/MICmdCmdSupportList.cpp
index 02728b95feb0..6cf4b0b533bc 100644
--- a/tools/lldb-mi/MICmdCmdSupportList.cpp
+++ b/tools/lldb-mi/MICmdCmdSupportList.cpp
@@ -7,17 +7,7 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdSupportList.cpp
-//
// Overview: CMICmdCmdSupportListFeatures implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// In-house headers:
#include "MICmdCmdSupportList.h"
diff --git a/tools/lldb-mi/MICmdCmdSupportList.h b/tools/lldb-mi/MICmdCmdSupportList.h
index 24267579d676..16c140bca349 100644
--- a/tools/lldb-mi/MICmdCmdSupportList.h
+++ b/tools/lldb-mi/MICmdCmdSupportList.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdSupportList.h
-//
// Overview: CMICmdCmdSupportListFeatures interface.
//
// To implement new MI commands derive a new command class from the command base
@@ -20,13 +17,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
diff --git a/tools/lldb-mi/MICmdCmdSymbol.cpp b/tools/lldb-mi/MICmdCmdSymbol.cpp
new file mode 100644
index 000000000000..2649389d7686
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdSymbol.cpp
@@ -0,0 +1,173 @@
+//===-- MICmdCmdSymbol.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Overview: CMICmdCmdSymbolListLines implementation.
+
+// Third Party Headers:
+#include "lldb/API/SBCommandInterpreter.h"
+
+// In-house headers:
+#include "MICmdArgValFile.h"
+#include "MICmdCmdSymbol.h"
+#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmnMIResultRecord.h"
+#include "MICmnMIValueList.h"
+#include "MICmnMIValueTuple.h"
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdSymbolListLines constructor.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdSymbolListLines::CMICmdCmdSymbolListLines(void)
+ : m_constStrArgNameFile("file")
+{
+ // Command factory matches this name with that received from the stdin stream
+ m_strMiCmd = "symbol-list-lines";
+
+ // Required by the CMICmdFactory when registering *this command
+ m_pSelfCreatorFn = &CMICmdCmdSymbolListLines::CreateSelf;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmdCmdSymbolListLines destructor.
+// Type: Overrideable.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+CMICmdCmdSymbolListLines::~CMICmdCmdSymbolListLines(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
+CMICmdCmdSymbolListLines::ParseArgs(void)
+{
+ bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValFile(m_constStrArgNameFile, true, 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: -symbol-list-lines file
+// Ref: http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Symbol-Query.html#GDB_002fMI-Symbol-Query
+// Type: Overridden.
+// Args: None.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmdCmdSymbolListLines::Execute(void)
+{
+ CMICMDBASE_GETOPTION(pArgFile, File, m_constStrArgNameFile);
+
+ const CMIUtilString &strFilePath(pArgFile->GetValue());
+ const CMIUtilString strCmd(CMIUtilString::Format("target modules dump line-table \"%s\"", strFilePath.AddSlashes().c_str()));
+
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ const lldb::ReturnStatus rtn = rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(strCmd.c_str(), m_lldbResult);
+ MIunused(rtn);
+
+ 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
+CMICmdCmdSymbolListLines::Acknowledge(void)
+{
+ if (m_lldbResult.GetErrorSize() > 0)
+ {
+ const char *pLldbErr = m_lldbResult.GetError();
+ const CMIUtilString strMsg(CMIUtilString(pLldbErr).StripCRAll());
+ const CMICmnMIValueConst miValueConst(strMsg);
+ const CMICmnMIValueResult miValueResult("message", miValueConst);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
+ m_miResultRecord = miRecordResult;
+ }
+ else
+ {
+ CMIUtilString::VecString_t vecLines;
+ const CMIUtilString strLldbMsg(m_lldbResult.GetOutput());
+ const MIuint nLines(strLldbMsg.SplitLines(vecLines));
+
+ CMICmnMIValueList miValueList(true);
+ for (MIuint i = 1; i < nLines; ++i)
+ {
+ // String looks like:
+ // 0x0000000100000e70: /path/to/file:3[:4]
+ const CMIUtilString &rLine(vecLines[i]);
+
+ // 0x0000000100000e70: /path/to/file:3[:4]
+ // ^^^^^^^^^^^^^^^^^^ -- pc
+ const size_t nAddrEndPos = rLine.find(':');
+ const CMIUtilString strAddr(rLine.substr(0, nAddrEndPos).c_str());
+ const CMICmnMIValueConst miValueConst(strAddr);
+ const CMICmnMIValueResult miValueResult("pc", miValueConst);
+ CMICmnMIValueTuple miValueTuple(miValueResult);
+
+ // 0x0000000100000e70: /path/to/file:3[:4]
+ // ^ -- line
+ const size_t nLineOrColumnStartPos = rLine.rfind(':');
+ const CMIUtilString strLineOrColumn(rLine.substr(nLineOrColumnStartPos + 1).c_str());
+ const size_t nPathOrLineStartPos = rLine.rfind(':', nLineOrColumnStartPos - 1);
+ const size_t nPathOrLineLen = nLineOrColumnStartPos - nPathOrLineStartPos - 1;
+ const CMIUtilString strPathOrLine(rLine.substr(nPathOrLineStartPos + 1, nPathOrLineLen).c_str());
+ const CMIUtilString strLine(strPathOrLine.IsNumber() ? strPathOrLine : strLineOrColumn);
+ const CMICmnMIValueConst miValueConst2(strLine);
+ const CMICmnMIValueResult miValueResult2("line", miValueConst2);
+ bool bOk = miValueTuple.Add(miValueResult2);
+
+ bOk = bOk && miValueList.Add(miValueTuple);
+ if (!bOk)
+ return MIstatus::failure;
+ }
+
+ // MI print "%s^done,lines=[{pc=\"%d\",line=\"%d\"}...]"
+ const CMICmnMIValueResult miValueResult("lines", miValueList);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
+ 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 *
+CMICmdCmdSymbolListLines::CreateSelf(void)
+{
+ return new CMICmdCmdSymbolListLines();
+}
diff --git a/tools/lldb-mi/MICmdCmdSymbol.h b/tools/lldb-mi/MICmdCmdSymbol.h
new file mode 100644
index 000000000000..449d8aed81b0
--- /dev/null
+++ b/tools/lldb-mi/MICmdCmdSymbol.h
@@ -0,0 +1,57 @@
+//===-- MICmdCmdSymbol.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Overview: CMICmdCmdSymbolListLines interface.
+//
+// To implement new MI commands derive a new command class from the command base
+// class. To enable the new command for interpretation add the new command class
+// to the command factory. The files of relevance are:
+// MICmdCommands.cpp
+// MICmdBase.h / .cpp
+// MICmdCmd.h / .cpp
+// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
+// command class as an example.
+
+#pragma once
+
+// Third party headers:
+#include "lldb/API/SBCommandReturnObject.h"
+
+// In-house headers:
+#include "MICmdBase.h"
+
+//++ ============================================================================
+// Details: MI command class. MI commands derived from the command base class.
+// *this class implements MI command "symbol-list-lines".
+//--
+class CMICmdCmdSymbolListLines : public CMICmdBase
+{
+ // Statics:
+ public:
+ // Required by the CMICmdFactory when registering *this command
+ static CMICmdBase *CreateSelf(void);
+
+ // Methods:
+ public:
+ /* ctor */ CMICmdCmdSymbolListLines(void);
+
+ // Overridden:
+ public:
+ // From CMICmdInvoker::ICmd
+ virtual bool Execute(void);
+ virtual bool Acknowledge(void);
+ virtual bool ParseArgs(void);
+ // From CMICmnBase
+ /* dtor */ virtual ~CMICmdCmdSymbolListLines(void);
+
+ // Attributes:
+ private:
+ lldb::SBCommandReturnObject m_lldbResult;
+ const CMIUtilString m_constStrArgNameFile;
+};
diff --git a/tools/lldb-mi/MICmdCmdTarget.cpp b/tools/lldb-mi/MICmdCmdTarget.cpp
index c3ef0b44e806..6655682eee38 100644
--- a/tools/lldb-mi/MICmdCmdTarget.cpp
+++ b/tools/lldb-mi/MICmdCmdTarget.cpp
@@ -7,17 +7,7 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdTarget.cpp
-//
// Overview: CMICmdCmdTargetSelect implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// Third Party Headers:
#include "lldb/API/SBStream.h"
@@ -32,6 +22,9 @@
#include "MICmnLLDBDebugger.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmdArgValString.h"
+#include "MICmdArgValOptionLong.h"
+#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValNumber.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmdCmdTargetSelect constructor.
@@ -118,7 +111,7 @@ CMICmdCmdTargetSelect::Execute(void)
const CMIUtilString strUrl = CMIUtilString::Format("connect://%s", pArgParameters->GetValue().c_str());
// Ask LLDB to collect to the target port
- const MIchar *pPlugin("gdb-remote");
+ const char *pPlugin("gdb-remote");
lldb::SBError error;
lldb::SBProcess process = rSessionInfo.GetTarget().ConnectRemote(rSessionInfo.GetListener(), strUrl.c_str(), pPlugin, error);
@@ -214,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();
+}
diff --git a/tools/lldb-mi/MICmdCmdTarget.h b/tools/lldb-mi/MICmdCmdTarget.h
index 0ed790f01e02..b3810305d4d9 100644
--- a/tools/lldb-mi/MICmdCmdTarget.h
+++ b/tools/lldb-mi/MICmdCmdTarget.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdTarget.h
-//
// Overview: CMICmdCmdTargetSelect interface.
//
// To implement new MI commands derive a new command class from the command base
@@ -20,13 +17,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
@@ -68,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);
+};
+
diff --git a/tools/lldb-mi/MICmdCmdThread.cpp b/tools/lldb-mi/MICmdCmdThread.cpp
index 52fd96050632..df6de269bd49 100644
--- a/tools/lldb-mi/MICmdCmdThread.cpp
+++ b/tools/lldb-mi/MICmdCmdThread.cpp
@@ -7,17 +7,7 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdThread.cpp
-//
// Overview: CMICmdCmdThreadInfo implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// Third Party Headers:
#include "lldb/API/SBBreakpointLocation.h"
@@ -105,12 +95,12 @@ CMICmdCmdThreadInfo::Execute(void)
if (m_bSingleThread)
{
thread = sbProcess.GetThreadByIndexID(nThreadId);
- m_bThreadInvalid = thread.IsValid();
- if (!m_bThreadInvalid)
+ m_bThreadInvalid = !thread.IsValid();
+ if (m_bThreadInvalid)
return MIstatus::success;
CMICmnMIValueTuple miTuple;
- if (!rSessionInfo.MIResponseFormThreadInfo3(m_cmdData, thread, miTuple))
+ if (!rSessionInfo.MIResponseFormThreadInfo(m_cmdData, thread, CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple))
return MIstatus::failure;
m_miValueTupleThread = miTuple;
@@ -127,7 +117,7 @@ CMICmdCmdThreadInfo::Execute(void)
if (thread.IsValid())
{
CMICmnMIValueTuple miTuple;
- if (!rSessionInfo.MIResponseFormThreadInfo3(m_cmdData, thread, miTuple))
+ if (!rSessionInfo.MIResponseFormThreadInfo(m_cmdData, thread, CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, miTuple))
return MIstatus::failure;
m_vecMIValueTuple.push_back(miTuple);
@@ -151,7 +141,7 @@ CMICmdCmdThreadInfo::Acknowledge(void)
{
if (m_bSingleThread)
{
- if (!m_bThreadInvalid)
+ if (m_bThreadInvalid)
{
const CMICmnMIValueConst miValueConst("invalid thread id");
const CMICmnMIValueResult miValueResult("msg", miValueConst);
diff --git a/tools/lldb-mi/MICmdCmdThread.h b/tools/lldb-mi/MICmdCmdThread.h
index 59b6b124cce1..6b268f40e8eb 100644
--- a/tools/lldb-mi/MICmdCmdThread.h
+++ b/tools/lldb-mi/MICmdCmdThread.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdThread.h
-//
// Overview: CMICmdCmdThreadInfo interface.
//
// To implement new MI commands derive a new command class from the command base
@@ -20,13 +17,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
diff --git a/tools/lldb-mi/MICmdCmdTrace.cpp b/tools/lldb-mi/MICmdCmdTrace.cpp
index 4ee72d300cc4..c0d5fc920373 100644
--- a/tools/lldb-mi/MICmdCmdTrace.cpp
+++ b/tools/lldb-mi/MICmdCmdTrace.cpp
@@ -7,17 +7,7 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdTrace.cpp
-//
// Overview: CMICmdCmdTraceStatus implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// In-house headers:
#include "MICmdCmdTrace.h"
diff --git a/tools/lldb-mi/MICmdCmdTrace.h b/tools/lldb-mi/MICmdCmdTrace.h
index efe8e50b5c98..c9a6f72a379a 100644
--- a/tools/lldb-mi/MICmdCmdTrace.h
+++ b/tools/lldb-mi/MICmdCmdTrace.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdTrace.h
-//
// Overview: CMICmdCmdTraceStatus interface.
//
// To implement new MI commands derive a new command class from the command base
@@ -20,13 +17,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
diff --git a/tools/lldb-mi/MICmdCmdVar.cpp b/tools/lldb-mi/MICmdCmdVar.cpp
index e9568beb173c..8c4abbda1128 100644
--- a/tools/lldb-mi/MICmdCmdVar.cpp
+++ b/tools/lldb-mi/MICmdCmdVar.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdVar.cpp
-//
// Overview: CMICmdCmdVarCreate implementation.
// CMICmdCmdVarUpdate implementation.
// CMICmdCmdVarDelete implementation.
@@ -19,16 +16,10 @@
// CMICmdCmdVarEvaluateExpression implementation.
// CMICmdCmdVarInfoPathExpression implementation.
// CMICmdCmdVarShowAttributes implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// Third Party Headers:
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBType.h"
#include "lldb/API/SBThread.h"
// In-house headers:
@@ -42,6 +33,7 @@
#include "MICmdArgValThreadGrp.h"
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValOptionShort.h"
+#include "MICmdArgValPrintValues.h"
#include "MICmdArgValListOfN.h"
#include "MICmnLLDBProxySBValue.h"
#include "MICmnLLDBUtilSBValue.h"
@@ -186,11 +178,29 @@ CMICmdCmdVarCreate::Execute(void)
lldb::SBThread thread = (nThreadId != UINT64_MAX) ? sbProcess.GetThreadByIndexID(nThreadId) : sbProcess.GetSelectedThread();
m_nThreadId = thread.GetIndexID();
lldb::SBFrame frame = bCurrentFrame ? thread.GetSelectedFrame() : thread.GetFrameAtIndex(nFrame);
- lldb::SBValue value = frame.FindVariable(rStrExpression.c_str());
+ lldb::SBValue value;
+
+ if (rStrExpression[0] == '$')
+ {
+ const CMIUtilString rStrRegister(rStrExpression.substr(1).c_str());
+ value = frame.FindRegister(rStrRegister.c_str());
+ }
+ else
+ {
+ const bool bArgs = true;
+ const bool bLocals = true;
+ const bool bStatics = true;
+ const bool bInScopeOnly = false;
+ const lldb::SBValueList valueList = frame.GetVariables(bArgs, bLocals, bStatics, bInScopeOnly);
+ value = valueList.GetFirstValueByName(rStrExpression.c_str());
+ }
+
if (!value.IsValid())
value = frame.EvaluateExpression(rStrExpression.c_str());
- if (value.IsValid())
+
+ if (value.IsValid() && value.GetError().Success())
{
+ CompleteSBValue(value);
m_bValid = true;
m_nChildren = value.GetNumChildren();
m_strType = CMICmnLLDBUtilSBValue(value).GetTypeNameDisplay();
@@ -199,6 +209,12 @@ CMICmdCmdVarCreate::Execute(void)
CMICmnLLDBDebugSessionInfoVarObj varObj(rStrExpression, m_strVarName, value);
m_strValue = varObj.GetValueFormatted();
}
+ else
+ {
+ lldb::SBStream err;
+ if (value.GetError().GetDescription(err))
+ m_strValue = err.GetData();
+ }
return MIstatus::success;
}
@@ -239,7 +255,10 @@ CMICmdCmdVarCreate::Acknowledge(void)
return MIstatus::success;
}
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CREATION_FAILED), m_strExpression.c_str()));
+ CMIUtilString strErrMsg(m_strValue);
+ if (m_strValue.empty())
+ strErrMsg = CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CREATION_FAILED), m_strExpression.c_str());
+ const CMICmnMIValueConst miValueConst(strErrMsg);
CMICmnMIValueResult miValueResult("msg", miValueConst);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
m_miResultRecord = miRecordResult;
@@ -261,6 +280,35 @@ CMICmdCmdVarCreate::CreateSelf(void)
return new CMICmdCmdVarCreate();
}
+//++ ------------------------------------------------------------------------------------
+// Details: Complete SBValue object and its children to get SBValue::GetValueDidChange
+// work.
+// Type: Method.
+// Args: vrwValue - (R) Value to update.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+void
+CMICmdCmdVarCreate::CompleteSBValue(lldb::SBValue &vrwValue)
+{
+ // Force a value to update
+ vrwValue.GetValueDidChange();
+
+ // And update its children
+ lldb::SBType valueType = vrwValue.GetType();
+ if (!valueType.IsPointerType() && !valueType.IsReferenceType())
+ {
+ const MIuint nChildren = vrwValue.GetNumChildren();
+ for (MIuint i = 0; i < nChildren; ++i)
+ {
+ lldb::SBValue member = vrwValue.GetChildAtIndex(i);
+ if (member.IsValid())
+ CompleteSBValue(member);
+ }
+ }
+}
+
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
@@ -273,12 +321,9 @@ CMICmdCmdVarCreate::CreateSelf(void)
// Throws: None.
//--
CMICmdCmdVarUpdate::CMICmdCmdVarUpdate(void)
- : m_eVarInfoFormat(CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues)
- , m_constStrArgPrintValues("print-values")
+ : m_constStrArgPrintValues("print-values")
, m_constStrArgName("name")
- , m_bValueChangedArrayType(false)
- , m_bValueChangedCompositeType(false)
- , m_bValueChangedNormalType(false)
+ , m_bValueChanged(false)
, m_miValueList(true)
{
// Command factory matches this name with that received from the stdin stream
@@ -311,7 +356,7 @@ CMICmdCmdVarUpdate::~CMICmdCmdVarUpdate(void)
bool
CMICmdCmdVarUpdate::ParseArgs(void)
{
- bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, true)));
+ bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgName, true, true)));
return (bOk && ParseValidateCmdOptions());
}
@@ -328,9 +373,13 @@ CMICmdCmdVarUpdate::ParseArgs(void)
bool
CMICmdCmdVarUpdate::Execute(void)
{
- CMICMDBASE_GETOPTION(pArgPrintValues, Number, m_constStrArgPrintValues);
+ CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
+ CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
+ if (pArgPrintValues->GetFound())
+ eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(pArgPrintValues->GetValue());
+
const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
if (!CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(rVarObjName, varObj))
@@ -339,73 +388,18 @@ CMICmdCmdVarUpdate::Execute(void)
return MIstatus::failure;
}
- const MIuint nPrintValues = pArgPrintValues->GetValue();
- if (nPrintValues >= CMICmnLLDBDebugSessionInfo::kNumVariableInfoFormats)
- {
- SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PRINT_VALUES), m_cmdData.strMiCmd.c_str()));
+ lldb::SBValue &rValue = varObj.GetValue();
+ if (!ExamineSBValueForChange(rValue, m_bValueChanged))
return MIstatus::failure;
- }
- m_eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(nPrintValues);
- const CMIUtilString &rVarRealName(varObj.GetNameReal());
- MIunused(rVarRealName);
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
- const bool bValid = rValue.IsValid();
- if (bValid && rValue.GetValueDidChange())
+ if (m_bValueChanged)
{
- m_bValueChangedNormalType = true;
varObj.UpdateValue();
- m_strValueName = rVarObjName;
- return MIstatus::success;
- }
-
- // Examine an array type variable
- if (!ExamineSBValueForChange(varObj, false, m_bValueChangedArrayType))
- return MIstatus::failure;
-
- // Handle composite types i.e. struct or arrays
- const MIuint nChildren = rValue.GetNumChildren();
- for (MIuint i = 0; i < nChildren; i++)
- {
- lldb::SBValue member = rValue.GetChildAtIndex(i);
- if (!member.IsValid())
- continue;
-
- const CMIUtilString varName(CMIUtilString::Format("%s.%s", rVarObjName.c_str(), member.GetName()));
- if (member.GetValueDidChange())
- {
- // Handle composite
- const CMIUtilString strValue(
- CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural));
- const CMIUtilString strInScope(member.IsInScope() ? "true" : "false");
- MIFormResponse(varName, strValue, strInScope);
-
- m_bValueChangedCompositeType = true;
- }
- else
- {
- // Handle array of composites
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- if (CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(varName, varObj))
- {
- bool bValueChanged = false;
- if (ExamineSBValueForChange(varObj, true, bValueChanged))
- {
- if (bValueChanged && CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(varName, varObj))
- {
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
- const bool bValid = rValue.IsValid();
- const CMIUtilString strValue(bValid ? varObj.GetValueFormatted() : "<unknown>");
- const CMIUtilString strInScope((bValid && rValue.IsInScope()) ? "true" : "false");
- MIFormResponse(varName, strValue, strInScope);
-
- m_bValueChangedCompositeType = true;
- }
- }
- else
- return MIstatus::failure;
- }
- }
+ const bool bPrintValue((eVarInfoFormat == CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues) ||
+ (eVarInfoFormat == CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues && rValue.GetNumChildren() == 0));
+ const CMIUtilString strValue(bPrintValue ? varObj.GetValueFormatted() : "");
+ const CMIUtilString strInScope(rValue.IsInScope() ? "true" : "false");
+ return MIFormResponse(rVarObjName, bPrintValue ? strValue.c_str() : nullptr, strInScope);
}
return MIstatus::success;
@@ -423,57 +417,20 @@ CMICmdCmdVarUpdate::Execute(void)
bool
CMICmdCmdVarUpdate::Acknowledge(void)
{
- if (m_bValueChangedArrayType || m_bValueChangedNormalType)
+ if (m_bValueChanged)
{
- CMICmnLLDBDebugSessionInfoVarObj varObj;
- CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(m_strValueName, varObj);
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
- const bool bValid = rValue.IsValid();
- const CMIUtilString strValue(bValid ? varObj.GetValueFormatted() : "<unknown>");
- const CMIUtilString strInScope((bValid && rValue.IsInScope()) ? "true" : "false");
-
// MI print "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
- const CMICmnMIValueConst miValueConst(m_strValueName);
- CMICmnMIValueResult miValueResult("name", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- if (m_eVarInfoFormat != CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues)
- {
- const CMICmnMIValueConst miValueConst2(strValue);
- CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- }
- const CMICmnMIValueConst miValueConst3(strInScope);
- CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
- miValueTuple.Add(miValueResult3);
- const CMICmnMIValueConst miValueConst4("false");
- CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
- miValueTuple.Add(miValueResult4);
- const CMICmnMIValueConst miValueConst5("0");
- CMICmnMIValueResult miValueResult5("has_more", miValueConst5);
- miValueTuple.Add(miValueResult5);
- const CMICmnMIValueList miValueList(miValueTuple);
- CMICmnMIValueResult miValueResult6("changelist", miValueList);
- const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6);
- m_miResultRecord = miRecordResult;
-
- return MIstatus::success;
- }
- else if (m_bValueChangedCompositeType)
- {
- // MI print
- // "%s^done,changelist=[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"},{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
- CMICmnMIValueResult miValueResult6("changelist", m_miValueList);
- const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6);
+ CMICmnMIValueResult miValueResult("changelist", m_miValueList);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
m_miResultRecord = miRecordResult;
}
else
{
- // MI: "%s^done,changelist=[]"
+ // MI print "%s^done,changelist=[]"
const CMICmnMIValueList miValueList(true);
CMICmnMIValueResult miValueResult6("changelist", miValueList);
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult6);
m_miResultRecord = miRecordResult;
- return MIstatus::success;
}
return MIstatus::success;
@@ -497,30 +454,34 @@ CMICmdCmdVarUpdate::CreateSelf(void)
// Details: Form the MI response for multiple variables.
// Type: Method.
// Args: vrStrVarName - (R) Session var object's name.
-// vrStrValue - (R) Text version of the value held in the variable.
+// vpValue - (R) Text version of the value held in the variable.
// vrStrScope - (R) In scope "yes" or "no".
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
-CMICmdCmdVarUpdate::MIFormResponse(const CMIUtilString &vrStrVarName, const CMIUtilString &vrStrValue, const CMIUtilString &vrStrScope)
+CMICmdCmdVarUpdate::MIFormResponse(const CMIUtilString &vrStrVarName, const char *const vpValue, const CMIUtilString &vrStrScope)
{
// MI print "[{name=\"%s\",value=\"%s\",in_scope=\"%s\",type_changed=\"false\",has_more=\"0\"}]"
const CMICmnMIValueConst miValueConst(vrStrVarName);
- CMICmnMIValueResult miValueResult("name", miValueConst);
+ const CMICmnMIValueResult miValueResult("name", miValueConst);
CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2(vrStrValue);
- CMICmnMIValueResult miValueResult2("value", miValueConst2);
- bool bOk = miValueTuple.Add(miValueResult2);
+ bool bOk = true;
+ if (vpValue != nullptr)
+ {
+ const CMICmnMIValueConst miValueConst2(vpValue);
+ const CMICmnMIValueResult miValueResult2("value", miValueConst2);
+ bOk = bOk && miValueTuple.Add(miValueResult2);
+ }
const CMICmnMIValueConst miValueConst3(vrStrScope);
- CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
+ const CMICmnMIValueResult miValueResult3("in_scope", miValueConst3);
bOk = bOk && miValueTuple.Add(miValueResult3);
const CMICmnMIValueConst miValueConst4("false");
- CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
+ const CMICmnMIValueResult miValueResult4("type_changed", miValueConst4);
bOk = bOk && miValueTuple.Add(miValueResult4);
const CMICmnMIValueConst miValueConst5("0");
- CMICmnMIValueResult miValueResult5("has_more", miValueConst5);
+ const CMICmnMIValueResult miValueResult5("has_more", miValueConst5);
bOk = bOk && miValueTuple.Add(miValueResult5);
bOk = bOk && m_miValueList.Add(miValueTuple);
@@ -528,74 +489,46 @@ CMICmdCmdVarUpdate::MIFormResponse(const CMIUtilString &vrStrVarName, const CMIU
}
//++ ------------------------------------------------------------------------------------
-// Details: Determine if the var object is a array type variable. LLDB does not 'detect'
-// a value change for some types like elements in an array so have to re-evaluate
-// the expression again.
+// Details: Determine if the var object was changed.
// Type: Method.
// Args: vrVarObj - (R) Session var object to examine.
-// vrwbChanged - (W) True = Is an array type and it changed,
-// False = Not an array type or not changed.
+// vrwbChanged - (W) True = The var object was changed,
+// False = It was not changed.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
-CMICmdCmdVarUpdate::ExamineSBValueForChange(const CMICmnLLDBDebugSessionInfoVarObj &vrVarObj, const bool vbIgnoreVarType, bool &vrwbChanged)
+CMICmdCmdVarUpdate::ExamineSBValueForChange(lldb::SBValue &vrwValue, bool &vrwbChanged)
{
- vrwbChanged = false;
-
- CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
- lldb::SBThread thread = sbProcess.GetSelectedThread();
- if (thread.GetNumFrames() == 0)
+ if (vrwValue.GetValueDidChange())
{
+ vrwbChanged = true;
return MIstatus::success;
}
- const CMIUtilString &strVarObjParentName = vrVarObj.GetVarParentName();
- lldb::SBFrame frame = thread.GetSelectedFrame();
- const CMIUtilString &rExpression(vrVarObj.GetNameReal());
- CMIUtilString varExpression;
- if (strVarObjParentName.empty())
- {
- varExpression = rExpression;
- }
- else
+ lldb::SBType valueType = vrwValue.GetType();
+ if (!valueType.IsPointerType() && !valueType.IsReferenceType())
{
- CMICmnLLDBDebugSessionInfoVarObj varObjParent;
- if (CMICmnLLDBDebugSessionInfoVarObj::VarObjGet(strVarObjParentName, varObjParent))
- varExpression = CMIUtilString::Format("%s.%s", varObjParent.GetNameReal().c_str(), rExpression.c_str());
- else
+ const MIuint nChildren = vrwValue.GetNumChildren();
+ for (MIuint i = 0; i < nChildren; ++i)
{
- // The parent is only assigned in the CMICmdCmdVarListChildren command, we have a problem, need to investigate
- SetError(
- CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_DOESNOTEXIST), m_cmdData.strMiCmd.c_str(), strVarObjParentName.c_str()));
- return MIstatus::failure;
- }
- }
+ lldb::SBValue member = vrwValue.GetChildAtIndex(i);
+ if (!member.IsValid())
+ continue;
- lldb::SBValue value = frame.EvaluateExpression(varExpression.c_str());
- if (!value.IsValid())
- value = frame.FindVariable(rExpression.c_str());
- if (value.IsValid())
- {
- lldb::SBType valueType = value.GetType();
- const lldb::BasicType eValueType = valueType.GetBasicType();
- if (vbIgnoreVarType || (eValueType != lldb::BasicType::eBasicTypeInvalid))
- {
- MIuint64 nPrevValue = 0;
- MIuint64 nRevaluateValue = 0;
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrVarObj.GetValue());
- if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(rValue, nPrevValue) &&
- CMICmnLLDBProxySBValue::GetValueAsUnsigned(value, nRevaluateValue) && (nPrevValue != nRevaluateValue))
+ if (member.GetValueDidChange())
{
- // Have a value change so update the var object
vrwbChanged = true;
- const CMICmnLLDBDebugSessionInfoVarObj varObj(rExpression, vrVarObj.GetName(), value, strVarObjParentName);
+ return MIstatus::success;
}
+ else if (ExamineSBValueForChange(member, vrwbChanged) && vrwbChanged)
+ // Handle composite types (i.e. struct or arrays)
+ return MIstatus::success;
}
}
+ vrwbChanged = false;
return MIstatus::success;
}
@@ -986,13 +919,14 @@ CMICmdCmdVarSetFormat::CreateSelf(void)
// Throws: None.
//--
CMICmdCmdVarListChildren::CMICmdCmdVarListChildren(void)
- : m_bValueValid(false)
- , m_nChildren(0)
- , m_constStrArgPrintValues("print-values")
+ : m_constStrArgPrintValues("print-values")
, m_constStrArgName("name")
- , m_constStrArgNoValues("no-values")
- , m_constStrArgAllValues("all-values")
- , m_constStrArgSimpleValues("simple-values")
+ , m_constStrArgFrom("from")
+ , m_constStrArgTo("to")
+ , m_bValueValid(false)
+ , m_nChildren(0)
+ , m_miValueList(true)
+ , m_bHasMore(false)
{
// Command factory matches this name with that received from the stdin stream
m_strMiCmd = "var-list-children";
@@ -1010,7 +944,6 @@ CMICmdCmdVarListChildren::CMICmdCmdVarListChildren(void)
//--
CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren(void)
{
- m_vecMiValueResult.clear();
}
//++ ------------------------------------------------------------------------------------
@@ -1025,11 +958,10 @@ CMICmdCmdVarListChildren::~CMICmdCmdVarListChildren(void)
bool
CMICmdCmdVarListChildren::ParseArgs(void)
{
- bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgPrintValues, false, true)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgNoValues, false, true)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgAllValues, false, true)));
- bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgSimpleValues, false, true)));
+ bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValPrintValues(m_constStrArgPrintValues, false, true)));
bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgName, true, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgFrom, false, true)));
+ bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgTo, false, true)));
return (bOk && ParseValidateCmdOptions());
}
@@ -1045,25 +977,14 @@ CMICmdCmdVarListChildren::ParseArgs(void)
bool
CMICmdCmdVarListChildren::Execute(void)
{
+ CMICMDBASE_GETOPTION(pArgPrintValues, PrintValues, m_constStrArgPrintValues);
CMICMDBASE_GETOPTION(pArgName, String, m_constStrArgName);
- CMICMDBASE_GETOPTION(pArgPrintValue, Number, m_constStrArgPrintValues);
- CMICMDBASE_GETOPTION(pArgNoValue, OptionLong, m_constStrArgNoValues);
- CMICMDBASE_GETOPTION(pArgAllValue, OptionLong, m_constStrArgAllValues);
- CMICMDBASE_GETOPTION(pArgSimpleValue, OptionLong, m_constStrArgSimpleValues);
+ CMICMDBASE_GETOPTION(pArgFrom, Number, m_constStrArgFrom);
+ CMICMDBASE_GETOPTION(pArgTo, Number, m_constStrArgTo);
- MIuint print_value = 0;
- if (pArgPrintValue->GetFound())
- {
- MIuint tmp = pArgPrintValue->GetValue();
- if (tmp <= 2)
- print_value = tmp;
- }
- else if (pArgNoValue->GetFound())
- print_value = 0; // no value
- else if (pArgAllValue->GetFound())
- print_value = 1; // all values
- else if (pArgSimpleValue->GetFound())
- print_value = 2; // simple values
+ CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e eVarInfoFormat = CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_NoValues;
+ if (pArgPrintValues->GetFound())
+ eVarInfoFormat = static_cast<CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e>(pArgPrintValues->GetValue());
const CMIUtilString &rVarObjName(pArgName->GetValue());
CMICmnLLDBDebugSessionInfoVarObj varObj;
@@ -1073,18 +994,32 @@ CMICmdCmdVarListChildren::Execute(void)
return MIstatus::failure;
}
+ MIuint nFrom = 0;
+ MIuint nTo = UINT32_MAX;
+ if (pArgFrom->GetFound() && pArgTo->GetFound())
+ {
+ nFrom = pArgFrom->GetValue();
+ nTo = pArgTo->GetValue();
+ }
+ else if (pArgFrom->GetFound() || pArgTo->GetFound())
+ {
+ // Only from or to was specified but both are required
+ SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID), m_cmdData.strMiCmd.c_str()));
+ return MIstatus::failure;
+ }
+
lldb::SBValue &rValue = const_cast<lldb::SBValue &>(varObj.GetValue());
m_bValueValid = rValue.IsValid();
if (!m_bValueValid)
return MIstatus::success;
- m_vecMiValueResult.clear();
- m_nChildren = rValue.GetNumChildren();
- for (MIuint i = 0; i < m_nChildren; i++)
+ const MIuint nChildren = rValue.GetNumChildren();
+ m_bHasMore = nTo < nChildren;
+ nTo = std::min(nTo, nChildren);
+ m_nChildren = nFrom < nTo ? nTo - nFrom : 0;
+ for (MIuint i = nFrom; i < nTo; i++)
{
lldb::SBValue member = rValue.GetChildAtIndex(i);
- if (!member.IsValid())
- continue;
const CMICmnLLDBUtilSBValue utilValue(member);
const CMIUtilString strExp = utilValue.GetName();
const CMIUtilString name(CMIUtilString::Format("%s.%s", rVarObjName.c_str(), strExp.c_str()));
@@ -1097,19 +1032,20 @@ CMICmdCmdVarListChildren::Execute(void)
CMICmnMIValueTuple miValueTuple(miValueResult);
const CMICmnMIValueConst miValueConst2(strExp);
const CMICmnMIValueResult miValueResult2("exp", miValueConst2);
- miValueTuple.Add(miValueResult2);
- const CMIUtilString strNumChild(CMIUtilString::Format("%d", nChildren));
+ bool bOk = miValueTuple.Add(miValueResult2);
+ const CMIUtilString strNumChild(CMIUtilString::Format("%u", nChildren));
const CMICmnMIValueConst miValueConst3(strNumChild);
const CMICmnMIValueResult miValueResult3("numchild", miValueConst3);
- miValueTuple.Add(miValueResult3);
+ bOk = bOk && miValueTuple.Add(miValueResult3);
const CMICmnMIValueConst miValueConst5(utilValue.GetTypeNameDisplay());
const CMICmnMIValueResult miValueResult5("type", miValueConst5);
- miValueTuple.Add(miValueResult5);
+ bOk = bOk && miValueTuple.Add(miValueResult5);
const CMICmnMIValueConst miValueConst6(strThreadId);
const CMICmnMIValueResult miValueResult6("thread-id", miValueConst6);
- miValueTuple.Add(miValueResult6);
+ bOk = bOk && miValueTuple.Add(miValueResult6);
// nChildren == 0 is used to check for simple values
- if ( (print_value == 2 && nChildren == 0) || (print_value == 1) )
+ if (eVarInfoFormat == CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues ||
+ (eVarInfoFormat == CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_SimpleValues && nChildren == 0))
{
// Varobj gets added to CMICmnLLDBDebugSessionInfoVarObj static container of varObjs
CMICmnLLDBDebugSessionInfoVarObj var(strExp, name, member, rVarObjName);
@@ -1117,14 +1053,15 @@ CMICmdCmdVarListChildren::Execute(void)
CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural));
const CMICmnMIValueConst miValueConst7(strValue);
const CMICmnMIValueResult miValueResult7("value", miValueConst7);
- miValueTuple.Add(miValueResult7);
+ bOk = bOk && miValueTuple.Add(miValueResult7);
}
const CMICmnMIValueConst miValueConst8("0");
const CMICmnMIValueResult miValueResult8("has_more", miValueConst8);
- miValueTuple.Add(miValueResult8);
+ bOk = bOk && miValueTuple.Add(miValueResult8);
const CMICmnMIValueResult miValueResult9("child", miValueTuple);
- m_vecMiValueResult.push_back(miValueResult9);
-
+ bOk = bOk && m_miValueList.Add(miValueResult9);
+ if (!bOk)
+ return MIstatus::failure;
}
return MIstatus::success;
@@ -1144,41 +1081,29 @@ CMICmdCmdVarListChildren::Acknowledge(void)
{
if (m_bValueValid)
{
- // MI print "%s^done,numchild=\"%u\",children=[]""
+ // MI print "%s^done,numchild=\"%u\",children=[%s],has_more=\"%d\""
const CMIUtilString strNumChild(CMIUtilString::Format("%u", m_nChildren));
const CMICmnMIValueConst miValueConst(strNumChild);
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
- {
- CMICmnMIValueList miValueList(*it);
- ++it;
- while (it != m_vecMiValueResult.end())
- {
- const CMICmnMIValueResult &rResult(*it);
- miValueList.Add(rResult);
-
- // Next
- ++it;
- }
- miValueResult.Add("children", miValueList);
- }
+ bool bOk = MIstatus::success;
+ if (m_nChildren != 0)
+ bOk = bOk && miValueResult.Add("children", m_miValueList);
+ const CMIUtilString strHasMore(m_bHasMore ? "1" : "0");
+ const CMICmnMIValueConst miValueConst2(strHasMore);
+ bOk = bOk && miValueResult.Add("has_more", miValueConst2);
+ if (!bOk)
+ return MIstatus::failure;
const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
m_miResultRecord = miRecordResult;
+
return MIstatus::success;
}
- // MI print "%s^done,numchild=\"0\""
- const CMICmnMIValueConst miValueConst("0");
- const CMICmnMIValueResult miValueResult("numchild", miValueConst);
- const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
+ // MI print "%s^error,msg=\"variable invalid\""
+ const CMICmnMIValueConst miValueConst("variable invalid");
+ const CMICmnMIValueResult miValueResult("msg", miValueConst);
+ const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
@@ -1410,7 +1335,7 @@ CMICmdCmdVarInfoPathExpression::Execute(void)
return MIstatus::failure;
}
- const MIchar *pPathExpression = stream.GetData();
+ const char *pPathExpression = stream.GetData();
if (pPathExpression == nullptr)
{
// Build expression from what we do know
diff --git a/tools/lldb-mi/MICmdCmdVar.h b/tools/lldb-mi/MICmdCmdVar.h
index add2058c029b..b6b65726eb8a 100644
--- a/tools/lldb-mi/MICmdCmdVar.h
+++ b/tools/lldb-mi/MICmdCmdVar.h
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCmdVar.h
-//
// Overview: CMICmdCmdVarCreate interface.
// CMICmdCmdVarUpdate interface.
// CMICmdCmdVarDelete interface.
@@ -28,13 +25,6 @@
// MICmdCmd.h / .cpp
// For an introduction to adding a new command see CMICmdCmdSupportInfoMiCmdQuery
// command class as an example.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
@@ -72,9 +62,16 @@ class CMICmdCmdVarCreate : public CMICmdBase
virtual bool Execute(void);
virtual bool Acknowledge(void);
virtual bool ParseArgs(void);
+
+ // Overridden:
+ public:
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarCreate(void);
+ // Methods:
+ private:
+ void CompleteSBValue(lldb::SBValue &vrwValue);
+
// Attribute:
private:
CMIUtilString m_strVarName;
@@ -124,18 +121,14 @@ class CMICmdCmdVarUpdate : public CMICmdBase
// Methods:
private:
- bool ExamineSBValueForChange(const CMICmnLLDBDebugSessionInfoVarObj &vrVarObj, const bool vbIgnoreVarType, bool &vrwbChanged);
- bool MIFormResponse(const CMIUtilString &vrStrVarName, const CMIUtilString &vrStrValue, const CMIUtilString &vrStrScope);
+ bool ExamineSBValueForChange(lldb::SBValue &vrwValue, bool &vrwbChanged);
+ bool MIFormResponse(const CMIUtilString &vrStrVarName, const char *const vpValue, const CMIUtilString &vrStrScope);
// Attribute:
private:
- CMIUtilString m_strValueName;
- CMICmnLLDBDebugSessionInfo::VariableInfoFormat_e m_eVarInfoFormat;
- const CMIUtilString m_constStrArgPrintValues; // Not handled by *this command
+ const CMIUtilString m_constStrArgPrintValues;
const CMIUtilString m_constStrArgName;
- bool m_bValueChangedArrayType; // True = yes value changed, false = no change
- bool m_bValueChangedCompositeType; // True = yes value changed, false = no change
- bool m_bValueChangedNormalType; // True = yes value changed, false = no change
+ bool m_bValueChanged; // True = yes value changed, false = no change
CMICmnMIValueList m_miValueList;
};
@@ -267,20 +260,16 @@ class CMICmdCmdVarListChildren : public CMICmdBase
// From CMICmnBase
/* dtor */ virtual ~CMICmdCmdVarListChildren(void);
- // Typedefs:
- private:
- typedef std::vector<CMICmnMIValueResult> VecMIValueResult_t;
-
// Attributes:
private:
- bool m_bValueValid; // True = yes SBValue object is valid, false = not valid
- VecMIValueResult_t m_vecMiValueResult;
- MIuint m_nChildren;
const CMIUtilString m_constStrArgPrintValues;
const CMIUtilString m_constStrArgName;
- const CMIUtilString m_constStrArgNoValues;
- const CMIUtilString m_constStrArgAllValues;
- const CMIUtilString m_constStrArgSimpleValues;
+ const CMIUtilString m_constStrArgFrom;
+ const CMIUtilString m_constStrArgTo;
+ bool m_bValueValid; // True = yes SBValue object is valid, false = not valid
+ MIuint m_nChildren;
+ CMICmnMIValueList m_miValueList;
+ bool m_bHasMore;
};
//++ ============================================================================
diff --git a/tools/lldb-mi/MICmdCommands.cpp b/tools/lldb-mi/MICmdCommands.cpp
index 81d10e1ce559..90a5d651f2af 100644
--- a/tools/lldb-mi/MICmdCommands.cpp
+++ b/tools/lldb-mi/MICmdCommands.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCommands.cpp
-//
// Overview: MI command are registered with the MI command factory.
//
// To implement new MI commands derive a new command class from the command base
@@ -18,13 +15,6 @@
// MICmdCommands.cpp
// MICmdBase.h / .cpp
// MICmdCmd.h / .cpp
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
// In-house headers:
#include "MICmdCommands.h"
@@ -37,11 +27,13 @@
#include "MICmdCmdFile.h"
#include "MICmdCmdGdbInfo.h"
#include "MICmdCmdGdbSet.h"
+#include "MICmdCmdGdbShow.h"
#include "MICmdCmdGdbThread.h"
#include "MICmdCmdMiscellanous.h"
#include "MICmdCmdStack.h"
#include "MICmdCmdSupportInfo.h"
#include "MICmdCmdSupportList.h"
+#include "MICmdCmdSymbol.h"
#include "MICmdCmdTarget.h"
#include "MICmdCmdThread.h"
#include "MICmdCmdTrace.h"
@@ -91,6 +83,7 @@ MICmnCommands::RegisterAll(void)
bOk &= Register<CMICmdCmdBreakInsert>();
bOk &= Register<CMICmdCmdDataDisassemble>();
bOk &= Register<CMICmdCmdDataEvaluateExpression>();
+ bOk &= Register<CMICmdCmdDataInfoLine>();
bOk &= Register<CMICmdCmdDataReadMemoryBytes>();
bOk &= Register<CMICmdCmdDataReadMemory>();
bOk &= Register<CMICmdCmdDataListRegisterNames>();
@@ -98,6 +91,8 @@ MICmnCommands::RegisterAll(void)
bOk &= Register<CMICmdCmdDataWriteMemory>();
bOk &= Register<CMICmdCmdEnablePrettyPrinting>();
bOk &= Register<CMICmdCmdEnvironmentCd>();
+ bOk &= Register<CMICmdCmdExecAbort>();
+ bOk &= Register<CMICmdCmdExecArguments>();
bOk &= Register<CMICmdCmdExecContinue>();
bOk &= Register<CMICmdCmdExecInterrupt>();
bOk &= Register<CMICmdCmdExecFinish>();
@@ -110,17 +105,24 @@ MICmnCommands::RegisterAll(void)
bOk &= Register<CMICmdCmdGdbExit>();
bOk &= Register<CMICmdCmdGdbInfo>();
bOk &= Register<CMICmdCmdGdbSet>();
+ bOk &= Register<CMICmdCmdGdbShow>();
bOk &= Register<CMICmdCmdGdbThread>();
bOk &= Register<CMICmdCmdInferiorTtySet>();
bOk &= Register<CMICmdCmdInterpreterExec>();
bOk &= Register<CMICmdCmdListThreadGroups>();
bOk &= Register<CMICmdCmdSource>();
bOk &= Register<CMICmdCmdStackInfoDepth>();
+ bOk &= Register<CMICmdCmdStackInfoFrame>();
bOk &= Register<CMICmdCmdStackListFrames>();
bOk &= Register<CMICmdCmdStackListArguments>();
bOk &= Register<CMICmdCmdStackListLocals>();
+ bOk &= Register<CMICmdCmdStackListVariables>();
+ bOk &= Register<CMICmdCmdStackSelectFrame>();
bOk &= Register<CMICmdCmdSupportListFeatures>();
+ bOk &= Register<CMICmdCmdSymbolListLines>();
bOk &= Register<CMICmdCmdTargetSelect>();
+ bOk &= Register<CMICmdCmdTargetAttach>();
+ bOk &= Register<CMICmdCmdTargetDetach>();
bOk &= Register<CMICmdCmdThreadInfo>();
bOk &= Register<CMICmdCmdVarAssign>();
bOk &= Register<CMICmdCmdVarCreate>();
diff --git a/tools/lldb-mi/MICmdCommands.h b/tools/lldb-mi/MICmdCommands.h
index 0e9d27714302..a99d09c8057a 100644
--- a/tools/lldb-mi/MICmdCommands.h
+++ b/tools/lldb-mi/MICmdCommands.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdCommands.h
-//
-// Overview: CMICmdCommands instantiated.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
namespace MICmnCommands
diff --git a/tools/lldb-mi/MICmdData.cpp b/tools/lldb-mi/MICmdData.cpp
index 44aa3c25dcb8..faafaf52483d 100644
--- a/tools/lldb-mi/MICmdData.cpp
+++ b/tools/lldb-mi/MICmdData.cpp
@@ -7,17 +7,5 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdData.cpp
-//
-// Overview: SMICmdData implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdData.h"
diff --git a/tools/lldb-mi/MICmdData.h b/tools/lldb-mi/MICmdData.h
index 114e32b26336..d58de903a68f 100644
--- a/tools/lldb-mi/MICmdData.h
+++ b/tools/lldb-mi/MICmdData.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdData.h
-//
-// Overview: SMICmdData interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmdFactory.cpp b/tools/lldb-mi/MICmdFactory.cpp
index ba333e7e1d0d..3fe4062b7721 100644
--- a/tools/lldb-mi/MICmdFactory.cpp
+++ b/tools/lldb-mi/MICmdFactory.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdFactory.cpp
-//
-// Overview: CMICmdFactory implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdFactory.h"
#include "MICmnResources.h"
@@ -171,8 +159,8 @@ CMICmdFactory::IsValid(const CMIUtilString &vMiCmd) const
return false;
}
- const MIint nPos = vMiCmd.find(" ");
- if (nPos != (MIint)std::string::npos)
+ const size_t nPos = vMiCmd.find(" ");
+ if (nPos != std::string::npos)
bValid = false;
return bValid;
diff --git a/tools/lldb-mi/MICmdFactory.h b/tools/lldb-mi/MICmdFactory.h
index 7af4b34ad0e7..8ad64fb5eafe 100644
--- a/tools/lldb-mi/MICmdFactory.h
+++ b/tools/lldb-mi/MICmdFactory.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdFactory.h
-//
-// Overview: CMICmdFactory interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers
diff --git a/tools/lldb-mi/MICmdInterpreter.cpp b/tools/lldb-mi/MICmdInterpreter.cpp
index 33db4b8196df..ce5d30e92316 100644
--- a/tools/lldb-mi/MICmdInterpreter.cpp
+++ b/tools/lldb-mi/MICmdInterpreter.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdInterpreter.cpp
-//
-// Overview: CMICmdInterpreter implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdInterpreter.h"
#include "MICmdFactory.h"
@@ -117,8 +105,8 @@ CMICmdInterpreter::ValidateIsMi(const CMIUtilString &vTextLine, bool &vwbYesVali
m_miCmdData.Clear();
m_miCmdData.strMiCmd = vTextLine;
- // The following change m_miCmdData as valid parts are indentified
- vwbYesValid = (MiHasCmdTokenEndingHypthen(vTextLine) || MiHasCmdTokenEndingAlpha(vTextLine));
+ // The following change m_miCmdData as valid parts are identified
+ vwbYesValid = (MiHasCmdTokenEndingHyphen(vTextLine) || MiHasCmdTokenEndingAlpha(vTextLine));
vwbYesValid = vwbYesValid && MiHasCmd(vTextLine);
if (vwbYesValid)
{
@@ -162,11 +150,11 @@ CMICmdInterpreter::HasCmdFactoryGotMiCmd(const SMICmdData &vCmd) const
// Throws: None.
//--
bool
-CMICmdInterpreter::MiHasCmdTokenEndingHypthen(const CMIUtilString &vTextLine)
+CMICmdInterpreter::MiHasCmdTokenEndingHyphen(const CMIUtilString &vTextLine)
{
- // The hythen is mandatory
- const MIint nPos = vTextLine.find("-", 0);
- if ((nPos == (MIint)std::string::npos))
+ // The hyphen is mandatory
+ const size_t nPos = vTextLine.find("-", 0);
+ if ((nPos == std::string::npos))
return false;
if (MiHasCmdTokenPresent(vTextLine))
@@ -198,7 +186,7 @@ CMICmdInterpreter::MiHasCmdTokenEndingHypthen(const CMIUtilString &vTextLine)
bool
CMICmdInterpreter::MiHasCmdTokenEndingAlpha(const CMIUtilString &vTextLine)
{
- MIchar cChar = vTextLine[0];
+ char cChar = vTextLine[0];
MIuint i = 0;
while (::isdigit(cChar) != 0)
{
@@ -218,7 +206,7 @@ CMICmdInterpreter::MiHasCmdTokenEndingAlpha(const CMIUtilString &vTextLine)
//++ ------------------------------------------------------------------------------------
// Details: Does the command entered match the criteria for a MI command format.
-// Is the command token present before the hypen?
+// Is the command token present before the hyphen?
// Type: Method.
// Args: vTextLine - (R) Text data to interpret.
// Return: bool - True = yes command token present, false = token not present.
@@ -227,13 +215,13 @@ CMICmdInterpreter::MiHasCmdTokenEndingAlpha(const CMIUtilString &vTextLine)
bool
CMICmdInterpreter::MiHasCmdTokenPresent(const CMIUtilString &vTextLine)
{
- const MIint nPos = vTextLine.find("-", 0);
+ const size_t nPos = vTextLine.find("-", 0);
return (nPos > 0);
}
//++ ------------------------------------------------------------------------------------
// Details: Does the command name entered match the criteria for a MI command format.
-// Is a recogised command present? The command name is entered into the
+// Is a recognised command present? The command name is entered into the
// command meta data structure whether correct or not for reporting or later
// command execution purposes. Command options is present are also put into the
// command meta data structure.
@@ -245,11 +233,11 @@ CMICmdInterpreter::MiHasCmdTokenPresent(const CMIUtilString &vTextLine)
bool
CMICmdInterpreter::MiHasCmd(const CMIUtilString &vTextLine)
{
- MIint nPos = 0;
+ size_t nPos = 0;
if (m_miCmdData.bMIOldStyle)
{
char cChar = vTextLine[0];
- MIuint i = 0;
+ size_t i = 0;
while (::isdigit(cChar) != 0)
{
cChar = vTextLine[++i];
@@ -262,9 +250,9 @@ CMICmdInterpreter::MiHasCmd(const CMIUtilString &vTextLine)
}
bool bFoundCmd = false;
- const MIint nLen = vTextLine.length();
- const MIint nPos2 = vTextLine.find(" ", nPos);
- if (nPos2 != (MIint)std::string::npos)
+ const size_t nLen = vTextLine.length();
+ const size_t nPos2 = vTextLine.find(" ", nPos);
+ if (nPos2 != std::string::npos)
{
if (nPos2 == nLen)
return false;
diff --git a/tools/lldb-mi/MICmdInterpreter.h b/tools/lldb-mi/MICmdInterpreter.h
index cc06179de882..acb052289ba2 100644
--- a/tools/lldb-mi/MICmdInterpreter.h
+++ b/tools/lldb-mi/MICmdInterpreter.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdInterpreter.h
-//
-// Overview: CMICmdInterpreter interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
@@ -58,7 +46,7 @@ class CMICmdInterpreter : public CMICmnBase, public MI::ISingleton<CMICmdInterpr
void operator=(const CMICmdInterpreter &);
bool HasCmdFactoryGotMiCmd(const SMICmdData &vCmdData) const;
- bool MiHasCmdTokenEndingHypthen(const CMIUtilString &vTextLine);
+ bool MiHasCmdTokenEndingHyphen(const CMIUtilString &vTextLine);
bool MiHasCmdTokenEndingAlpha(const CMIUtilString &vTextLine);
bool MiHasCmd(const CMIUtilString &vTextLine);
bool MiHasCmdTokenPresent(const CMIUtilString &vTextLine);
diff --git a/tools/lldb-mi/MICmdInvoker.cpp b/tools/lldb-mi/MICmdInvoker.cpp
index c415fbaf18b5..ef957c53bd70 100644
--- a/tools/lldb-mi/MICmdInvoker.cpp
+++ b/tools/lldb-mi/MICmdInvoker.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdInvoker.cpp
-//
-// Overview: CMICmdInvoker implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdInvoker.h"
#include "MICmdBase.h"
diff --git a/tools/lldb-mi/MICmdInvoker.h b/tools/lldb-mi/MICmdInvoker.h
index 09c20c909240..a03c2d36103a 100644
--- a/tools/lldb-mi/MICmdInvoker.h
+++ b/tools/lldb-mi/MICmdInvoker.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdInvoker.h
-//
-// Overview: CMICmdInvoker interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers
diff --git a/tools/lldb-mi/MICmdMgr.cpp b/tools/lldb-mi/MICmdMgr.cpp
index 44778b55daf0..998a72f5d07e 100644
--- a/tools/lldb-mi/MICmdMgr.cpp
+++ b/tools/lldb-mi/MICmdMgr.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdMgr.cpp
-//
-// Overview: CMICmdMgr implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdMgr.h"
#include "MICmnResources.h"
diff --git a/tools/lldb-mi/MICmdMgr.h b/tools/lldb-mi/MICmdMgr.h
index f403e1778c96..a45ecb61a3ce 100644
--- a/tools/lldb-mi/MICmdMgr.h
+++ b/tools/lldb-mi/MICmdMgr.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdMgr.h
-//
-// Overview: CMICmdMgr interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers
diff --git a/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp b/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp
index 9bd9e83e1e6b..3f2ccfd10ce6 100644
--- a/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp
+++ b/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmdMgrSetCmdDeleteCallback.cpp
-//
-// Overview: CSetClients implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmdMgrSetCmdDeleteCallback.h"
diff --git a/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h b/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h
index b969af0dacb9..16b11e5d0f4b 100644
--- a/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h
+++ b/tools/lldb-mi/MICmdMgrSetCmdDeleteCallback.h
@@ -6,18 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
-//++
-// File: MICmdMgrSetCmdDeleteCallback.h
-//
-// Overview: ICallback interface.
-// CSetClients interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
//--
#pragma once
diff --git a/tools/lldb-mi/MICmnBase.cpp b/tools/lldb-mi/MICmnBase.cpp
index fce6a1d25562..909393564da4 100644
--- a/tools/lldb-mi/MICmnBase.cpp
+++ b/tools/lldb-mi/MICmnBase.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnBase.cpp
-//
-// Overview: CMICmnBase implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third party headers
#include <stdarg.h> // va_list, va_start, var_end
diff --git a/tools/lldb-mi/MICmnBase.h b/tools/lldb-mi/MICmnBase.h
index 01fdab4dd14f..d2e2bcdf10d2 100644
--- a/tools/lldb-mi/MICmnBase.h
+++ b/tools/lldb-mi/MICmnBase.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnBase.h
-//
-// Overview: CMICmnBase interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmnConfig.h b/tools/lldb-mi/MICmnConfig.h
index 830e2e3b562c..2e31fb629f6b 100644
--- a/tools/lldb-mi/MICmnConfig.h
+++ b/tools/lldb-mi/MICmnConfig.h
@@ -6,45 +6,13 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
-//++
-// File: MICmnConfig.h
-//
-// Overview: Common defines to guide feature inclusion at compile time.
-//
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
//--
#pragma once
-// 1 = Yes compile MI Driver version, 0 = compile original LLDB driver code only.
-// 0 was mainly just for testing purposes and so may be removed at a later time.
-#define MICONFIG_COMPILE_MIDRIVER_VERSION 1
-
// 1 = Show debug process attach modal dialog, 0 = do not show
// For windows only ATM, other OS's code is an infinite loop which a debugger must change a value to continue
#define MICONFIG_DEBUG_SHOW_ATTACH_DBG_DLG 0
-// 1 = Compile in and init LLDB driver code alongside MI version, 0 = do not compile in
-#define MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER 1
-
-// 1 = Give runtime our own custom buffer, 0 = Use runtime managed buffer
-#define MICONFIG_CREATE_OWN_STDIN_BUFFER 0
-
-// 1 = Use the MI driver regardless of --interpreter, 0 = require --interpreter argument
-// This depends on MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
-#define MICONFIG_DEFAULT_TO_MI_DRIVER 0
-
-// 1 = Check for stdin before we issue blocking read, 0 = issue blocking call always
-#define MICONFIG_POLL_FOR_STD_IN 1
-
// 1 = Write to MI's Log file warnings about commands that did not handle arguments or
// options present to them by the driver's client, 0 = no warnings given
#define MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED 1
-
-// 1 = Enable MI Driver in MI mode to create a local debug session, 0 = Report "Not implemented"
-#define MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION 0
diff --git a/tools/lldb-mi/MICmnLLDBBroadcaster.cpp b/tools/lldb-mi/MICmnLLDBBroadcaster.cpp
index 2b563c64d65a..55927b691d77 100644
--- a/tools/lldb-mi/MICmnLLDBBroadcaster.cpp
+++ b/tools/lldb-mi/MICmnLLDBBroadcaster.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBBroadcaster.cpp
-//
-// Overview: CMICmnLLDBBroadcaster implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnLLDBBroadcaster.h"
diff --git a/tools/lldb-mi/MICmnLLDBBroadcaster.h b/tools/lldb-mi/MICmnLLDBBroadcaster.h
index 62ca0542dbf1..469aae969b96 100644
--- a/tools/lldb-mi/MICmnLLDBBroadcaster.h
+++ b/tools/lldb-mi/MICmnLLDBBroadcaster.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBBroadcaster.h
-//
-// Overview: CMICmnLLDBBroadcaster interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
index 7f6d9d53811a..cff651dd4a57 100644
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
+++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
@@ -7,19 +7,8 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBDebugSessionInfo.cpp
-//
-// Overview: CMICmnLLDBDebugSessionInfo implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third party headers:
+#include <inttypes.h> // For PRIx64
#include "lldb/API/SBThread.h"
#ifdef _WIN32
#include <io.h> // For the ::_access()
@@ -51,6 +40,9 @@ CMICmnLLDBDebugSessionInfo::CMICmnLLDBDebugSessionInfo(void)
, m_currentSelectedThread(LLDB_INVALID_THREAD_ID)
, m_constStrSharedDataKeyWkDir("Working Directory")
, m_constStrSharedDataSolibPath("Solib Path")
+ , m_constStrPrintCharArrayAsString("Print CharArrayAsString")
+ , m_constStrPrintExpandAggregates("Print ExpandAggregates")
+ , m_constStrPrintAggregateFieldNames("Print AggregateFieldNames")
{
}
@@ -222,7 +214,8 @@ CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoDelete(const MIuint vnBrkPtId)
// Throws: None.
//--
bool
-CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, CMIUtilString &vwrThreadFrames)
+CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, const FrameInfoFormat_e veFrameInfoFormat,
+ CMIUtilString &vwrThreadFrames)
{
lldb::SBThread thread = GetProcess().GetThreadByIndexID(vThreadIdx);
const uint32_t nFrames = thread.GetNumFrames();
@@ -236,113 +229,13 @@ CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MI
}
// MI print
- // "frame={level=\"%d\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},frame={level=\"%d\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},
+ // "frame={level=\"%d\",addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},frame={level=\"%d\",addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},
// ..."
CMIUtilString strListCommaSeperated;
for (MIuint nLevel = 0; nLevel < nFrames; nLevel++)
{
- lldb::SBFrame frame = thread.GetFrameAtIndex(nLevel);
- lldb::addr_t pc = 0;
- CMIUtilString fnName;
- CMIUtilString fileName;
- CMIUtilString path;
- MIuint nLine = 0;
- if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine))
- return MIstatus::failure;
-
- // Function args
- CMICmnMIValueList miValueList(true);
- const MIuint maskVarTypes = eVariableType_Arguments;
- if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList))
- return MIstatus::failure;
-
- const MIchar *pUnknown = "??";
- if (fnName != pUnknown)
- {
- std::replace(fnName.begin(), fnName.end(), ')', ' ');
- std::replace(fnName.begin(), fnName.end(), '(', ' ');
- std::replace(fnName.begin(), fnName.end(), '\'', ' ');
- }
-
CMICmnMIValueTuple miValueTuple;
- const CMIUtilString strLevel(CMIUtilString::Format("%d", nLevel));
- const CMICmnMIValueConst miValueConst(strLevel);
- const CMICmnMIValueResult miValueResult("level", miValueConst);
- miValueTuple.Add(miValueResult);
- if (!MIResponseFormFrameInfo2(pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple))
- return MIstatus::failure;
-
- const CMICmnMIValueResult miValueResult2("frame", miValueTuple);
- if (nLevel != 0)
- strListCommaSeperated += ",";
- strListCommaSeperated += miValueResult2.GetString();
- }
-
- vwrThreadFrames = strListCommaSeperated;
-
- return MIstatus::success;
-}
-
-// Todo: Refactor maybe to so only one function with this name, but not just yet
-//++ ------------------------------------------------------------------------------------
-// Details: Retrieve the specified thread's frame information.
-// Type: Method.
-// Args: vCmdData - (R) A command's information.
-// vThreadIdx - (R) Thread index.
-// vwrThreadFrames - (W) Frame data.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnLLDBDebugSessionInfo::GetThreadFrames2(const SMICmdData &vCmdData, const MIuint vThreadIdx, CMIUtilString &vwrThreadFrames)
-{
- lldb::SBThread thread = GetProcess().GetThreadByIndexID(vThreadIdx);
- const uint32_t nFrames = thread.GetNumFrames();
- if (nFrames == 0)
- {
- // MI print "frame={}"
- CMICmnMIValueTuple miValueTuple;
- CMICmnMIValueResult miValueResult("frame", miValueTuple);
- vwrThreadFrames = miValueResult.GetString();
- return MIstatus::success;
- }
-
- // MI print
- // "frame={level=\"%d\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},frame={level=\"%d\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},
- // ..."
- CMIUtilString strListCommaSeperated;
- for (MIuint nLevel = 0; nLevel < nFrames; nLevel++)
- {
- lldb::SBFrame frame = thread.GetFrameAtIndex(nLevel);
- lldb::addr_t pc = 0;
- CMIUtilString fnName;
- CMIUtilString fileName;
- CMIUtilString path;
- MIuint nLine = 0;
- if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine))
- return MIstatus::failure;
-
- // Function args
- CMICmnMIValueList miValueList(true);
- const MIuint maskVarTypes = eVariableType_Arguments;
- if (!MIResponseFormVariableInfo2(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList))
- return MIstatus::failure;
-
- const MIchar *pUnknown = "??";
- if (fnName != pUnknown)
- {
- std::replace(fnName.begin(), fnName.end(), ')', ' ');
- std::replace(fnName.begin(), fnName.end(), '(', ' ');
- std::replace(fnName.begin(), fnName.end(), '\'', ' ');
- }
-
- CMICmnMIValueTuple miValueTuple;
- const CMIUtilString strLevel(CMIUtilString::Format("%d", nLevel));
- const CMICmnMIValueConst miValueConst(strLevel);
- const CMICmnMIValueResult miValueResult("level", miValueConst);
- miValueTuple.Add(miValueResult);
- if (!MIResponseFormFrameInfo2(pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple))
+ if (!MIResponseFormFrameInfo(thread, nLevel, veFrameInfoFormat, miValueTuple))
return MIstatus::failure;
const CMICmnMIValueResult miValueResult2("frame", miValueTuple);
@@ -470,78 +363,10 @@ CMICmnLLDBDebugSessionInfo::AccessPath(const CMIUtilString &vPath, bool &vwbYesA
//--
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo(const SMICmdData &vCmdData, const lldb::SBThread &vrThread,
- CMICmnMIValueTuple &vwrMIValueTuple)
-{
- lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);
-
- CMIUtilString strFrames;
- if (!GetThreadFrames(vCmdData, rThread.GetIndexID(), strFrames))
- return MIstatus::failure;
-
- const bool bSuspended = rThread.IsSuspended();
- const lldb::StopReason eReason = rThread.GetStopReason();
- const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid));
- const CMIUtilString strState((bSuspended || bValidReason) ? "stopped" : "running");
-
- // Add "id"
- const CMIUtilString strId(CMIUtilString::Format("%d", rThread.GetIndexID()));
- const CMICmnMIValueConst miValueConst1(strId);
- const CMICmnMIValueResult miValueResult1("id", miValueConst1);
- if (!vwrMIValueTuple.Add(miValueResult1))
- return MIstatus::failure;
-
- // Add "target-id"
- const MIchar *pThreadName = rThread.GetName();
- const MIuint len = (pThreadName != nullptr) ? CMIUtilString(pThreadName).length() : 0;
- const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) &&
- CMIUtilString::IsAllValidAlphaAndNumeric(*pThreadName)); // 32 is arbitary number
- const MIchar *pThrdFmt = bHaveName ? "%s" : "Thread %d";
- CMIUtilString strThread;
- if (bHaveName)
- strThread = CMIUtilString::Format(pThrdFmt, pThreadName);
- else
- strThread = CMIUtilString::Format(pThrdFmt, rThread.GetIndexID());
- const CMICmnMIValueConst miValueConst2(strThread);
- const CMICmnMIValueResult miValueResult2("target-id", miValueConst2);
- if (!vwrMIValueTuple.Add(miValueResult2))
- return MIstatus::failure;
-
- // Add "frame"
- const CMICmnMIValueConst miValueConst3(strFrames, true);
- if (!vwrMIValueTuple.Add(miValueConst3, false))
- return MIstatus::failure;
-
- // Add "state"
- const CMICmnMIValueConst miValueConst4(strState);
- const CMICmnMIValueResult miValueResult4("state", miValueConst4);
- if (!vwrMIValueTuple.Add(miValueResult4))
- return MIstatus::failure;
-
- return MIstatus::success;
-}
-
-// Todo: Refactor maybe to so only one function with this name, but not just yet
-//++ ------------------------------------------------------------------------------------
-// Details: Form MI partial response by appending more MI value type objects to the
-// tuple type object past in.
-// Type: Method.
-// Args: vCmdData - (R) A command's information.
-// vrThread - (R) LLDB thread object.
-// vwrMIValueTuple - (W) MI value tuple object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo3(const SMICmdData &vCmdData, const lldb::SBThread &vrThread,
- CMICmnMIValueTuple &vwrMIValueTuple)
+ const ThreadInfoFormat_e veThreadInfoFormat, CMICmnMIValueTuple &vwrMIValueTuple)
{
lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);
- CMIUtilString strFrames;
- if (!GetThreadFrames2(vCmdData, rThread.GetIndexID(), strFrames))
- return MIstatus::failure;
-
const bool bSuspended = rThread.IsSuspended();
const lldb::StopReason eReason = rThread.GetStopReason();
const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid));
@@ -555,11 +380,11 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo3(const SMICmdData &vCmdData
return MIstatus::failure;
// Add "target-id"
- const MIchar *pThreadName = rThread.GetName();
+ const char *pThreadName = rThread.GetName();
const MIuint len = (pThreadName != nullptr) ? CMIUtilString(pThreadName).length() : 0;
const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) &&
- CMIUtilString::IsAllValidAlphaAndNumeric(*pThreadName)); // 32 is arbitary number
- const MIchar *pThrdFmt = bHaveName ? "%s" : "Thread %d";
+ CMIUtilString::IsAllValidAlphaAndNumeric(pThreadName)); // 32 is arbitary number
+ const char *pThrdFmt = bHaveName ? "%s" : "Thread %d";
CMIUtilString strThread;
if (bHaveName)
strThread = CMIUtilString::Format(pThrdFmt, pThreadName);
@@ -571,64 +396,16 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo3(const SMICmdData &vCmdData
return MIstatus::failure;
// Add "frame"
- const CMICmnMIValueConst miValueConst3(strFrames, true);
- if (!vwrMIValueTuple.Add(miValueConst3, false))
- return MIstatus::failure;
-
- // Add "state"
- const CMICmnMIValueConst miValueConst4(strState);
- const CMICmnMIValueResult miValueResult4("state", miValueConst4);
- if (!vwrMIValueTuple.Add(miValueResult4))
- return MIstatus::failure;
-
- return MIstatus::success;
-}
-
-// Todo: Refactor maybe to so only one function with this name, but not just yet
-//++ ------------------------------------------------------------------------------------
-// Details: Form MI partial response by appending more MI value type objects to the
-// tuple type object past in.
-// Type: Method.
-// Args: vCmdData - (R) A command's information.
-// vrThread - (R) LLDB thread object.
-// vwrMIValueTuple - (W) MI value tuple object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo2(const SMICmdData &vCmdData, const lldb::SBThread &vrThread,
- CMICmnMIValueTuple &vwrMIValueTuple)
-{
- lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);
-
- const bool bSuspended = rThread.IsSuspended();
- const lldb::StopReason eReason = rThread.GetStopReason();
- const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid));
- const CMIUtilString strState((bSuspended || bValidReason) ? "stopped" : "running");
-
- // Add "id"
- const CMIUtilString strId(CMIUtilString::Format("%d", rThread.GetIndexID()));
- const CMICmnMIValueConst miValueConst1(strId);
- const CMICmnMIValueResult miValueResult1("id", miValueConst1);
- if (!vwrMIValueTuple.Add(miValueResult1))
- return MIstatus::failure;
+ if (veThreadInfoFormat != eThreadInfoFormat_NoFrames)
+ {
+ CMIUtilString strFrames;
+ if (!GetThreadFrames(vCmdData, rThread.GetIndexID(), eFrameInfoFormat_AllArgumentsInSimpleForm, strFrames))
+ return MIstatus::failure;
- // Add "target-id"
- const MIchar *pThreadName = rThread.GetName();
- const MIuint len = (pThreadName != nullptr) ? CMIUtilString(pThreadName).length() : 0;
- const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) &&
- CMIUtilString::IsAllValidAlphaAndNumeric(*pThreadName)); // 32 is arbitary number
- const MIchar *pThrdFmt = bHaveName ? "%s" : "Thread %d";
- CMIUtilString strThread;
- if (bHaveName)
- strThread = CMIUtilString::Format(pThrdFmt, pThreadName);
- else
- strThread = CMIUtilString::Format(pThrdFmt, rThread.GetIndexID());
- const CMICmnMIValueConst miValueConst2(strThread);
- const CMICmnMIValueResult miValueResult2("target-id", miValueConst2);
- if (!vwrMIValueTuple.Add(miValueResult2))
- return MIstatus::failure;
+ const CMICmnMIValueConst miValueConst3(strFrames, true);
+ if (!vwrMIValueTuple.Add(miValueConst3, false))
+ return MIstatus::failure;
+ }
// Add "state"
const CMICmnMIValueConst miValueConst4(strState);
@@ -639,48 +416,6 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo2(const SMICmdData &vCmdData
return MIstatus::success;
}
-// Todo: Refactor maybe to so only one function with this name, but not just yet
-//++ ------------------------------------------------------------------------------------
-// Details: Form MI partial response by appending more MI value type objects to the
-// tuple type object past in.
-// Type: Method.
-// Args: vrFrame - (R) LLDB thread object.
-// vMaskVarTypes - (R) Construed according to VariableType_e.
-// veVarInfoFormat - (R) The type of variable info that should be shown.
-// vwrMIValueList - (W) MI value list object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo2(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
- const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList)
-{
- bool bOk = MIstatus::success;
- lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
-
- const bool bArg = (vMaskVarTypes & eVariableType_Arguments);
- const bool bLocals = (vMaskVarTypes & eVariableType_Locals);
- const bool bStatics = (vMaskVarTypes & eVariableType_Statics);
- const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope);
- lldb::SBValueList listArg = rFrame.GetVariables(bArg, bLocals, bStatics, bInScopeOnly);
- const MIuint nArgs = listArg.GetSize();
- for (MIuint i = 0; bOk && (i < nArgs); i++)
- {
- lldb::SBValue value = listArg.GetValueAtIndex(i);
- const CMICmnLLDBUtilSBValue utilValue(value);
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- const CMICmnMIValueConst miValueConst2(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- bOk = vwrMiValueList.Add(miValueTuple);
- }
-
- return bOk;
-}
-
//++ ------------------------------------------------------------------------------------
// Details: Form MI partial response by appending more MI value type objects to the
// tuple type object past in.
@@ -695,7 +430,9 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo2(const lldb::SBFrame &vrF
//--
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
- const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList)
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList,
+ const MIuint vnMaxDepth, /* = 10 */
+ const bool vbMarkArgs /* = false*/)
{
bool bOk = MIstatus::success;
lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
@@ -704,416 +441,100 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFr
const bool bLocals = (vMaskVarTypes & eVariableType_Locals);
const bool bStatics = (vMaskVarTypes & eVariableType_Statics);
const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope);
- const MIuint nMaxRecusiveDepth = 10;
- MIuint nCurrentRecursiveDepth = 0;
- lldb::SBValueList listArg = rFrame.GetVariables(bArg, bLocals, bStatics, bInScopeOnly);
- const MIuint nArgs = listArg.GetSize();
- for (MIuint i = 0; bOk && (i < nArgs); i++)
- {
- lldb::SBValue value = listArg.GetValueAtIndex(i);
- bOk = GetVariableInfo(nMaxRecusiveDepth, value, false, veVarInfoFormat, vwrMiValueList, nCurrentRecursiveDepth);
- }
-
+
+ // Handle arguments first
+ lldb::SBValueList listArg = rFrame.GetVariables(bArg, false, false, false);
+ bOk = bOk && MIResponseForVariableInfoInternal(veVarInfoFormat, vwrMiValueList, listArg, vnMaxDepth, true, vbMarkArgs);
+
+ // Handle remaining variables
+ lldb::SBValueList listVars = rFrame.GetVariables(false, bLocals, bStatics, bInScopeOnly);
+ bOk = bOk && MIResponseForVariableInfoInternal(veVarInfoFormat, vwrMiValueList, listVars, vnMaxDepth, false, vbMarkArgs);
+
return bOk;
}
-// *** Do not refactor this function to be one function with same name as it can break more than
-// *** than one stack type command
-//++ ------------------------------------------------------------------------------------
-// Details: Form MI partial response by appending more MI value type objects to the
-// tuple type object past in.
-// Type: Method.
-// Args: vrFrame - (R) LLDB thread object.
-// vMaskVarTypes - (R) Construed according to VariableType_e.
-// veVarInfoFormat - (R) The type of variable info that should be shown.
-// vwrMIValueList - (W) MI value list object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
bool
-CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo3(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
- const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList)
+CMICmnLLDBDebugSessionInfo::MIResponseForVariableInfoInternal(const VariableInfoFormat_e veVarInfoFormat,
+ CMICmnMIValueList &vwrMiValueList,
+ const lldb::SBValueList &vwrSBValueList,
+ const MIuint vnMaxDepth,
+ const bool vbIsArgs,
+ const bool vbMarkArgs)
{
bool bOk = MIstatus::success;
- lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
-
- const bool bArg = (vMaskVarTypes & eVariableType_Arguments);
- const bool bLocals = (vMaskVarTypes & eVariableType_Locals);
- const bool bStatics = (vMaskVarTypes & eVariableType_Statics);
- const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope);
- const MIuint nMaxRecusiveDepth = 10;
- MIuint nCurrentRecursiveDepth = 0;
- lldb::SBValueList listArg = rFrame.GetVariables(bArg, bLocals, bStatics, bInScopeOnly);
- const MIuint nArgs = listArg.GetSize();
+ const MIuint nArgs = vwrSBValueList.GetSize();
for (MIuint i = 0; bOk && (i < nArgs); i++)
{
- lldb::SBValue value = listArg.GetValueAtIndex(i);
- bOk = GetVariableInfo2(nMaxRecusiveDepth, value, false, veVarInfoFormat, vwrMiValueList, nCurrentRecursiveDepth);
- }
-
- return bOk;
-}
-
-// *** Do not refactor this function to be one function with same name as it can break more than
-// *** than one stack type command
-//++ ------------------------------------------------------------------------------------
-// Details: Extract the value's name and value or recurse into child value object.
-// Type: Method.
-// Args: vnMaxDepth - (R) The max recursive depth for this function.
-// vrValue - (R) LLDB value object.
-// vbIsChildValue - (R) True = Value object is a child of a higher Value object,
-// - False = Value object not a child.
-// veVarInfoFormat - (R) The type of variable info that should be shown.
-// vwrMIValueList - (W) MI value list object.
-// vnDepth - (RW) The current recursive depth of this function.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnLLDBDebugSessionInfo::GetVariableInfo(const MIuint vnMaxDepth, const lldb::SBValue &vrValue, const bool vbIsChildValue,
- const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList,
- MIuint &vrwnDepth)
-{
- // *** Update GetVariableInfo2() with any code changes here ***
-
- // Check recursive depth
- if (vrwnDepth >= vnMaxDepth)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
- const CMICmnLLDBUtilSBValue utilValue(vrValue, true);
- CMICmnMIValueTuple miValueTuple;
- const MIchar *pName = rValue.GetName();
- MIunused(pName);
- const bool bIsPointerType = rValue.GetType().IsPointerType();
- const MIuint nChildren = rValue.GetNumChildren();
- if (nChildren == 0)
- {
- if (vbIsChildValue)
+ CMICmnMIValueTuple miValueTuple;
+ lldb::SBValue value = vwrSBValueList.GetValueAtIndex(i);
+ const CMICmnMIValueConst miValueConst(value.GetName());
+ const CMICmnMIValueResult miValueResultName("name", miValueConst);
+ if (vbMarkArgs && vbIsArgs)
{
- if (utilValue.IsCharType())
- {
- // For char types and try to form text string
- const CMICmnMIValueConst miValueConst(utilValue.GetValue().c_str(), true);
- miValueTuple.Add(miValueConst, true);
- }
- else
- {
- // For composite types
- const CMICmnMIValueConst miValueConst(
- CMIUtilString::Format("%s = %s", utilValue.GetName().c_str(), utilValue.GetValue().c_str()), true);
- miValueTuple.Add(miValueConst, true);
- }
- return vwrMiValueList.Add(CMICmnMIValueConst(miValueTuple.ExtractContentNoBrackets(), true));
+ const CMICmnMIValueConst miValueConstArg("1");
+ const CMICmnMIValueResult miValueResultArg("arg", miValueConstArg);
+ miValueTuple.Add(miValueResultArg);
}
- else
+ if (veVarInfoFormat != eVariableInfoFormat_NoValues)
{
- // Basic types
- switch (veVarInfoFormat)
+ miValueTuple.Add(miValueResultName); // name
+ if (veVarInfoFormat == eVariableInfoFormat_SimpleValues)
{
- case eVariableInfoFormat_NoValues:
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- return vwrMiValueList.Add(miValueResult);
- }
- case eVariableInfoFormat_AllValues:
- case eVariableInfoFormat_SimpleValues:
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
- const CMICmnMIValueConst miValueConst2(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- break;
- }
- default:
- break;
+ const CMICmnMIValueConst miValueConst3(value.GetTypeName());
+ const CMICmnMIValueResult miValueResult3("type", miValueConst3);
+ miValueTuple.Add(miValueResult3);
}
- return vwrMiValueList.Add(miValueTuple);
- }
- }
- else if (bIsPointerType && utilValue.IsChildCharType())
- {
- switch (veVarInfoFormat)
- {
- case eVariableInfoFormat_NoValues:
+ const MIuint nChildren = value.GetNumChildren();
+ const bool bIsPointerType = value.GetType().IsPointerType();
+ if (nChildren == 0 || // no children
+ (bIsPointerType && nChildren == 1) || // pointers
+ veVarInfoFormat == eVariableInfoFormat_AllValues) // show all values
{
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- return vwrMiValueList.Add(miValueResult);
- }
- case eVariableInfoFormat_AllValues:
- case eVariableInfoFormat_SimpleValues:
- {
- // Append string text to the parent value information
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
-
- const CMIUtilString &rText(utilValue.GetChildValueCString());
- if (rText.empty())
+ CMIUtilString strValue;
+ if (GetVariableInfo(value, vnMaxDepth == 0, strValue))
{
- const CMICmnMIValueConst miValueConst(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- miValueTuple.Add(miValueResult);
- }
- else
- {
- if (utilValue.IsValueUnknown())
- {
- const CMICmnMIValueConst miValueConst(rText);
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- miValueTuple.Add(miValueResult);
- }
- else
- {
- // Note code that has const in will not show the text suffix to the string pointer
- // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this
- // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%s %s", utilValue.GetValue().c_str(), rText.c_str()));
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- miValueTuple.Add(miValueResult);
- }
+ const CMICmnMIValueConst miValueConst2(strValue.Escape().AddSlashes());
+ const CMICmnMIValueResult miValueResult2("value", miValueConst2);
+ miValueTuple.Add(miValueResult2);
}
- break;
}
- default:
- break;
+ vwrMiValueList.Add(miValueTuple);
+ continue;
}
- return vwrMiValueList.Add(miValueTuple);
- }
- else if (bIsPointerType)
- {
- if (vbIsChildValue)
+
+ if (vbMarkArgs)
{
- // For composite types
- const CMICmnMIValueConst miValueConst(
- CMIUtilString::Format("%s = %s", utilValue.GetName().c_str(), utilValue.GetValue().c_str()), true);
- miValueTuple.Add(miValueConst, true);
- return vwrMiValueList.Add(CMICmnMIValueConst(miValueTuple.ExtractContentNoBrackets(), true));
+ // If we are printing names only with vbMarkArgs, we still need to add the name to the value tuple
+ miValueTuple.Add(miValueResultName); // name
+ vwrMiValueList.Add(miValueTuple);
}
else
{
- // Basic types
- switch (veVarInfoFormat)
- {
- case eVariableInfoFormat_NoValues:
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- return vwrMiValueList.Add(miValueResult);
- }
- case eVariableInfoFormat_AllValues:
- case eVariableInfoFormat_SimpleValues:
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
- const CMICmnMIValueConst miValueConst2(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- break;
- }
- default:
- break;
- }
- return vwrMiValueList.Add(miValueTuple);
+ // If we are printing name only then no need to put it in the tuple.
+ vwrMiValueList.Add(miValueResultName);
}
}
- else
- {
- switch (veVarInfoFormat)
- {
- case eVariableInfoFormat_NoValues:
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- return vwrMiValueList.Add(miValueResult);
- }
- case eVariableInfoFormat_AllValues:
- case eVariableInfoFormat_SimpleValues:
- {
- // Build parent child composite types
- CMICmnMIValueList miValueList(true);
- for (MIuint i = 0; bOk && (i < nChildren); i++)
- {
- lldb::SBValue member = rValue.GetChildAtIndex(i);
- bOk = GetVariableInfo(vnMaxDepth, member, true, veVarInfoFormat, miValueList, ++vrwnDepth);
- }
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
- const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("{%s}", miValueList.ExtractContentNoBrackets().c_str()));
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- break;
- }
- default:
- break;
- }
- return vwrMiValueList.Add(miValueTuple);
- }
+ return bOk;
}
-// *** Do not refactor this function to be one function with same name as it can break more than
-// *** than one stack type command
//++ ------------------------------------------------------------------------------------
// Details: Extract the value's name and value or recurse into child value object.
// Type: Method.
-// Args: vnMaxDepth - (R) The max recursive depth for this function.
-// vrValue - (R) LLDB value object.
-// vbIsChildValue - (R) True = Value object is a child of a higher Value object,
-// - False = Value object not a child.
-// veVarInfoFormat - (R) The type of variable info that should be shown.
-// vwrMIValueList - (W) MI value list object.
-// vnDepth - (RW) The current recursive depth of this function.
-// // Return: MIstatus::success - Functional succeeded.
+// Args: vrValue - (R) LLDB value object.
+// vbInSimpleForm - (R) True = Get variable info in simple form (i.e. don't expand aggregates).
+// - False = Get variable info (and expand aggregates if any).
+// vwrStrValue t - (W) The string representatin of this value.
+// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
-CMICmnLLDBDebugSessionInfo::GetVariableInfo2(const MIuint vnMaxDepth, const lldb::SBValue &vrValue, const bool vbIsChildValue,
- const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList,
- MIuint &vrwnDepth)
+CMICmnLLDBDebugSessionInfo::GetVariableInfo(const lldb::SBValue &vrValue, const bool vbInSimpleForm, CMIUtilString &vwrStrValue)
{
- // *** Update GetVariableInfo() with any code changes here ***
-
- // Check recursive depth
- if (vrwnDepth >= vnMaxDepth)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
- const CMICmnLLDBUtilSBValue utilValue(vrValue, true);
- CMICmnMIValueTuple miValueTuple;
- const MIchar *pName = rValue.GetName();
- MIunused(pName);
- const MIuint nChildren = rValue.GetNumChildren();
- if (nChildren == 0)
- {
- if (vbIsChildValue && utilValue.IsCharType())
- {
- // For char types and try to form text string
- const CMICmnMIValueConst miValueConst(utilValue.GetValue().c_str(), true);
- miValueTuple.Add(miValueConst, true);
- return vwrMiValueList.Add(CMICmnMIValueConst(miValueTuple.ExtractContentNoBrackets(), true));
- }
- else
- {
- // Basic types
- switch (veVarInfoFormat)
- {
- case eVariableInfoFormat_NoValues:
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- return vwrMiValueList.Add(miValueResult);
- }
- case eVariableInfoFormat_AllValues:
- case eVariableInfoFormat_SimpleValues:
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
- const CMICmnMIValueConst miValueConst2(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- break;
- }
- default:
- break;
- }
- return vwrMiValueList.Add(miValueTuple);
- }
- }
- else if (utilValue.IsChildCharType())
- {
- switch (veVarInfoFormat)
- {
- case eVariableInfoFormat_NoValues:
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- return vwrMiValueList.Add(miValueResult);
- }
- case eVariableInfoFormat_AllValues:
- case eVariableInfoFormat_SimpleValues:
- {
- // Append string text to the parent value information
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
-
- const CMIUtilString &rText(utilValue.GetChildValueCString());
- if (rText.empty())
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetValue());
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- miValueTuple.Add(miValueResult);
- }
- else
- {
- if (utilValue.IsValueUnknown())
- {
- const CMICmnMIValueConst miValueConst(rText);
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- miValueTuple.Add(miValueResult);
- }
- else
- {
- // Note code that has const in will not show the text suffix to the string pointer
- // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this
- // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this
- const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%s %s", utilValue.GetValue().c_str(), rText.c_str()));
- const CMICmnMIValueResult miValueResult("value", miValueConst);
- miValueTuple.Add(miValueResult);
- }
- }
- break;
- }
- default:
- break;
- }
- return vwrMiValueList.Add(miValueTuple);
- }
- else
- {
- switch (veVarInfoFormat)
- {
- case eVariableInfoFormat_NoValues:
- {
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- return vwrMiValueList.Add(miValueResult);
- }
- case eVariableInfoFormat_AllValues:
- case eVariableInfoFormat_SimpleValues:
- {
- // Build parent child composite types
- CMICmnMIValueList miValueList(true);
- for (MIuint i = 0; bOk && (i < nChildren); i++)
- {
- lldb::SBValue member = rValue.GetChildAtIndex(i);
- bOk = GetVariableInfo(vnMaxDepth, member, true, veVarInfoFormat, miValueList, ++vrwnDepth);
- }
- const CMICmnMIValueConst miValueConst(utilValue.GetName());
- const CMICmnMIValueResult miValueResult("name", miValueConst);
- miValueTuple.Add(miValueResult);
- const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("{%s}", miValueList.ExtractContentNoBrackets().c_str()));
- const CMICmnMIValueResult miValueResult2("value", miValueConst2);
- miValueTuple.Add(miValueResult2);
- break;
- }
- default:
- break;
- }
- return vwrMiValueList.Add(miValueTuple);
- }
+ const CMICmnLLDBUtilSBValue utilValue(vrValue, true, false);
+ const bool bExpandAggregates = vbInSimpleForm ? false : true;
+ vwrStrValue = utilValue.GetValue(bExpandAggregates);
+ return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
@@ -1122,13 +543,14 @@ CMICmnLLDBDebugSessionInfo::GetVariableInfo2(const MIuint vnMaxDepth, const lldb
// Type: Method.
// Args: vrThread - (R) LLDB thread object.
// vwrMIValueTuple - (W) MI value tuple object.
+// vArgInfo - (R) Args information in MI response form.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel,
- CMICmnMIValueTuple &vwrMiValueTuple)
+ const FrameInfoFormat_e veFrameInfoFormat, CMICmnMIValueTuple &vwrMiValueTuple)
{
lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);
@@ -1141,15 +563,51 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(const lldb::SBThread &vrThre
if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine))
return MIstatus::failure;
- // MI print "{level=\"0\",addr=\"0x%08llx\",func=\"%s\",file=\"%s\",fullname=\"%s\",line=\"%d\"}"
+ // MI print "{level=\"0\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s\",line=\"%d\"}"
const CMIUtilString strLevel(CMIUtilString::Format("%d", vnLevel));
const CMICmnMIValueConst miValueConst(strLevel);
const CMICmnMIValueResult miValueResult("level", miValueConst);
- CMICmnMIValueTuple miValueTuple(miValueResult);
- if (!MIResponseFormFrameInfo(pc, fnName, fileName, path, nLine, miValueTuple))
+ if (!vwrMiValueTuple.Add(miValueResult))
return MIstatus::failure;
+ const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, pc));
+ const CMICmnMIValueConst miValueConst2(strAddr);
+ const CMICmnMIValueResult miValueResult2("addr", miValueConst2);
+ if (!vwrMiValueTuple.Add(miValueResult2))
+ return MIstatus::failure;
+ const CMICmnMIValueConst miValueConst3(fnName);
+ const CMICmnMIValueResult miValueResult3("func", miValueConst3);
+ if (!vwrMiValueTuple.Add(miValueResult3))
+ return MIstatus::failure;
+ if (veFrameInfoFormat != eFrameInfoFormat_NoArguments)
+ {
+ CMICmnMIValueList miValueList(true);
+ const MIuint maskVarTypes = eVariableType_Arguments;
+ if (veFrameInfoFormat == eFrameInfoFormat_AllArgumentsInSimpleForm)
+ {
+ if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList, 0))
+ return MIstatus::failure;
+ }
+ else
+ if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList))
+ return MIstatus::failure;
- vwrMiValueTuple = miValueTuple;
+ const CMICmnMIValueResult miValueResult4("args", miValueList);
+ if (!vwrMiValueTuple.Add(miValueResult4))
+ return MIstatus::failure;
+ }
+ const CMICmnMIValueConst miValueConst5(fileName);
+ const CMICmnMIValueResult miValueResult5("file", miValueConst5);
+ if (!vwrMiValueTuple.Add(miValueResult5))
+ return MIstatus::failure;
+ const CMICmnMIValueConst miValueConst6(path);
+ const CMICmnMIValueResult miValueResult6("fullname", miValueConst6);
+ if (!vwrMiValueTuple.Add(miValueResult6))
+ return MIstatus::failure;
+ const CMIUtilString strLine(CMIUtilString::Format("%d", nLine));
+ const CMICmnMIValueConst miValueConst7(strLine);
+ const CMICmnMIValueResult miValueResult7("line", miValueConst7);
+ if (!vwrMiValueTuple.Add(miValueResult7))
+ return MIstatus::failure;
return MIstatus::success;
}
@@ -1177,17 +635,17 @@ CMICmnLLDBDebugSessionInfo::GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::add
const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath(&pBuffer[0], sizeof(pBuffer));
MIunused(nBytes);
CMIUtilString strResolvedPath(&pBuffer[0]);
- const MIchar *pUnkwn = "??";
+ const char *pUnkwn = "??";
if (!ResolvePath(pUnkwn, strResolvedPath))
return MIstatus::failure;
vwPath = strResolvedPath;
vwPc = rFrame.GetPC();
- const MIchar *pFnName = rFrame.GetFunctionName();
+ const char *pFnName = rFrame.GetFunctionName();
vwFnName = (pFnName != nullptr) ? pFnName : pUnkwn;
- const MIchar *pFileName = rFrame.GetLineEntry().GetFileSpec().GetFilename();
+ const char *pFileName = rFrame.GetLineEntry().GetFileSpec().GetFilename();
vwFileName = (pFileName != nullptr) ? pFileName : pUnkwn;
vwnLine = rFrame.GetLineEntry().GetLine();
@@ -1199,101 +657,6 @@ CMICmnLLDBDebugSessionInfo::GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::add
// Details: Form MI partial response by appending more MI value type objects to the
// tuple type object past in.
// Type: Method.
-// Args: vPc - (R) Address number.
-// vFnName - (R) Function name.
-// vFileName - (R) File name text.
-// vPath - (R) Full file name and path text.
-// vnLine - (R) File line number.
-// vwrMIValueTuple - (W) MI value tuple object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(const lldb::addr_t vPc, const CMIUtilString &vFnName, const CMIUtilString &vFileName,
- const CMIUtilString &vPath, const MIuint vnLine, CMICmnMIValueTuple &vwrMiValueTuple)
-{
- const CMIUtilString strAddr(CMIUtilString::Format("0x%08llx", vPc));
- const CMICmnMIValueConst miValueConst2(strAddr);
- const CMICmnMIValueResult miValueResult2("addr", miValueConst2);
- if (!vwrMiValueTuple.Add(miValueResult2))
- return MIstatus::failure;
- const CMICmnMIValueConst miValueConst3(vFnName);
- const CMICmnMIValueResult miValueResult3("func", miValueConst3);
- if (!vwrMiValueTuple.Add(miValueResult3))
- return MIstatus::failure;
- const CMICmnMIValueConst miValueConst5(vFileName);
- const CMICmnMIValueResult miValueResult5("file", miValueConst5);
- if (!vwrMiValueTuple.Add(miValueResult5))
- return MIstatus::failure;
- const CMICmnMIValueConst miValueConst6(vPath);
- const CMICmnMIValueResult miValueResult6("fullname", miValueConst6);
- if (!vwrMiValueTuple.Add(miValueResult6))
- return MIstatus::failure;
- const CMIUtilString strLine(CMIUtilString::Format("%d", vnLine));
- const CMICmnMIValueConst miValueConst7(strLine);
- const CMICmnMIValueResult miValueResult7("line", miValueConst7);
- if (!vwrMiValueTuple.Add(miValueResult7))
- return MIstatus::failure;
-
- return MIstatus::success;
-}
-
-// Todo: Refactor maybe to so only one function with this name, but not just yet
-//++ ------------------------------------------------------------------------------------
-// Details: Form MI partial response by appending more MI value type objects to the
-// tuple type object past in.
-// Type: Method.
-// Args: vPc - (R) Address number.
-// vArgInfo - (R) Args information in MI response form.
-// vFnName - (R) Function name.
-// vFileName - (R) File name text.
-// vPath - (R) Full file name and path text.
-// vnLine - (R) File line number.
-// vwrMIValueTuple - (W) MI value tuple object.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo2(const lldb::addr_t vPc, const CMIUtilString &vArgInfo, const CMIUtilString &vFnName,
- const CMIUtilString &vFileName, const CMIUtilString &vPath, const MIuint vnLine,
- CMICmnMIValueTuple &vwrMiValueTuple)
-{
- const CMIUtilString strAddr(CMIUtilString::Format("0x%08llx", vPc));
- const CMICmnMIValueConst miValueConst2(strAddr);
- const CMICmnMIValueResult miValueResult2("addr", miValueConst2);
- if (!vwrMiValueTuple.Add(miValueResult2))
- return MIstatus::failure;
- const CMICmnMIValueConst miValueConst3(vFnName);
- const CMICmnMIValueResult miValueResult3("func", miValueConst3);
- if (!vwrMiValueTuple.Add(miValueResult3))
- return MIstatus::failure;
- const CMICmnMIValueConst miValueConst4(vArgInfo, true);
- const CMICmnMIValueResult miValueResult4("args", miValueConst4);
- if (!vwrMiValueTuple.Add(miValueResult4))
- return MIstatus::failure;
- const CMICmnMIValueConst miValueConst5(vFileName);
- const CMICmnMIValueResult miValueResult5("file", miValueConst5);
- if (!vwrMiValueTuple.Add(miValueResult5))
- return MIstatus::failure;
- const CMICmnMIValueConst miValueConst6(vPath);
- const CMICmnMIValueResult miValueResult6("fullname", miValueConst6);
- if (!vwrMiValueTuple.Add(miValueResult6))
- return MIstatus::failure;
- const CMIUtilString strLine(CMIUtilString::Format("%d", vnLine));
- const CMICmnMIValueConst miValueConst7(strLine);
- const CMICmnMIValueResult miValueResult7("line", miValueConst7);
- if (!vwrMiValueTuple.Add(miValueResult7))
- return MIstatus::failure;
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Form MI partial response by appending more MI value type objects to the
-// tuple type object past in.
-// Type: Method.
// Args: vrBrkPtInfo - (R) Break point information object.
// vwrMIValueTuple - (W) MI value tuple object.
// Return: MIstatus::success - Functional succeeded.
@@ -1303,7 +666,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo2(const lldb::addr_t vPc, con
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple)
{
- const CMIUtilString strAddr(CMIUtilString::Format("0x%08llx", vrBrkPtInfo.m_pc));
+ const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, vrBrkPtInfo.m_pc));
const CMICmnMIValueConst miValueConst2(strAddr);
const CMICmnMIValueResult miValueResult2("addr", miValueConst2);
if (!vwrMiValueTuple.Add(miValueResult2))
@@ -1343,7 +706,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo(const SBrkPtInfo &vrBrk
bool
CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple)
{
- // MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\",
+ // MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\",
// func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
// "number="
@@ -1438,15 +801,17 @@ CMICmnLLDBDebugSessionInfo::GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt, SBrkP
lldb::SBBreakpointLocation brkPtLoc = rBrkPt.GetLocationAtIndex(0);
lldb::SBAddress brkPtAddr = brkPtLoc.GetAddress();
lldb::SBSymbolContext symbolCntxt = brkPtAddr.GetSymbolContext(lldb::eSymbolContextEverything);
- const MIchar *pUnkwn = "??";
+ const char *pUnkwn = "??";
lldb::SBModule rModule = symbolCntxt.GetModule();
- const MIchar *pModule = rModule.IsValid() ? rModule.GetFileSpec().GetFilename() : pUnkwn;
+ const char *pModule = rModule.IsValid() ? rModule.GetFileSpec().GetFilename() : pUnkwn;
MIunused(pModule);
- const MIchar *pFile = pUnkwn;
- const MIchar *pFn = pUnkwn;
- const MIchar *pFilePath = pUnkwn;
+ const char *pFile = pUnkwn;
+ const char *pFn = pUnkwn;
+ const char *pFilePath = pUnkwn;
size_t nLine = 0;
- const size_t nAddr = brkPtAddr.GetLoadAddress(GetTarget());
+ lldb::addr_t nAddr = brkPtAddr.GetLoadAddress(GetTarget());
+ if (nAddr == LLDB_INVALID_ADDRESS)
+ nAddr = brkPtAddr.GetFileAddress();
lldb::SBCompileUnit rCmplUnit = symbolCntxt.GetCompileUnit();
if (rCmplUnit.IsValid())
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
index 2e592f1f43c6..e3e16cd2ca54 100644
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
+++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBDebugSessionInfo.h
-//
-// Overview: CMICmnLLDBDebugSessionInfo interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
@@ -87,7 +75,7 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
CMIUtilString m_strType; // Break point type.
bool m_bDisp; // True = "del", false = "keep".
bool m_bEnabled; // True = enabled, false = disabled break point.
- MIuint m_pc; // Address number.
+ lldb::addr_t m_pc; // Address number.
CMIUtilString m_fnName; // Function name.
CMIUtilString m_fileName; // File name text.
CMIUtilString m_path; // Full file name and path text.
@@ -122,10 +110,28 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
//--
enum VariableInfoFormat_e
{
- eVariableInfoFormat_NoValues,
- eVariableInfoFormat_AllValues,
- eVariableInfoFormat_SimpleValues,
- kNumVariableInfoFormats
+ eVariableInfoFormat_NoValues = 0,
+ eVariableInfoFormat_AllValues = 1,
+ eVariableInfoFormat_SimpleValues = 2
+ };
+
+ //++ ===================================================================
+ // Details: Determine the information that should be shown by using MIResponseFormThreadInfo family functions.
+ //--
+ enum ThreadInfoFormat_e
+ {
+ eThreadInfoFormat_NoFrames,
+ eThreadInfoFormat_AllFrames
+ };
+
+ //++ ===================================================================
+ // Details: Determine the information that should be shown by using MIResponseFormFrameInfo family functions.
+ //--
+ enum FrameInfoFormat_e
+ {
+ eFrameInfoFormat_NoArguments,
+ eFrameInfoFormat_AllArguments,
+ eFrameInfoFormat_AllArgumentsInSimpleForm
};
// Typedefs:
@@ -144,27 +150,15 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
// Common command required functionality
bool AccessPath(const CMIUtilString &vPath, bool &vwbYesAccessible);
- bool GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::addr_t &vwPc, CMIUtilString &vwFnName, CMIUtilString &vwFileName,
- CMIUtilString &vwPath, MIuint &vwnLine);
- bool GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, CMIUtilString &vwrThreadFrames);
- bool GetThreadFrames2(const SMICmdData &vCmdData, const MIuint vThreadIdx, CMIUtilString &vwrThreadFrames);
bool ResolvePath(const SMICmdData &vCmdData, const CMIUtilString &vPath, CMIUtilString &vwrResolvedPath);
bool ResolvePath(const CMIUtilString &vstrUnknown, CMIUtilString &vwrResolvedPath);
- bool MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel, CMICmnMIValueTuple &vwrMiValueTuple);
- bool MIResponseFormFrameInfo(const lldb::addr_t vPc, const CMIUtilString &vFnName, const CMIUtilString &vFileName,
- const CMIUtilString &vPath, const MIuint vnLine, CMICmnMIValueTuple &vwrMiValueTuple);
- bool MIResponseFormFrameInfo2(const lldb::addr_t vPc, const CMIUtilString &vArgInfo, const CMIUtilString &vFnName,
- const CMIUtilString &vFileName, const CMIUtilString &vPath, const MIuint vnLine,
- CMICmnMIValueTuple &vwrMiValueTuple);
- bool MIResponseFormThreadInfo(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, CMICmnMIValueTuple &vwrMIValueTuple);
- bool MIResponseFormThreadInfo2(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, CMICmnMIValueTuple &vwrMIValueTuple);
- bool MIResponseFormThreadInfo3(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, CMICmnMIValueTuple &vwrMIValueTuple);
+ bool MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel,
+ const FrameInfoFormat_e veFrameInfoFormat, CMICmnMIValueTuple &vwrMiValueTuple);
+ bool MIResponseFormThreadInfo(const SMICmdData &vCmdData, const lldb::SBThread &vrThread,
+ const ThreadInfoFormat_e veThreadInfoFormat, CMICmnMIValueTuple &vwrMIValueTuple);
bool MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
- const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList);
- bool MIResponseFormVariableInfo2(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
- const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList);
- bool MIResponseFormVariableInfo3(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
- const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList);
+ const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList,
+ const MIuint vnMaxDepth = 10, const bool vbMarkArgs = false);
bool MIResponseFormBrkPtFrameInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple);
bool MIResponseFormBrkPtInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple);
bool GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt, SBrkPtInfo &vrwBrkPtInfo) const;
@@ -188,6 +182,9 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
// Note: This list is expected to grow and will be moved and abstracted in the future.
const CMIUtilString m_constStrSharedDataKeyWkDir;
const CMIUtilString m_constStrSharedDataSolibPath;
+ const CMIUtilString m_constStrPrintCharArrayAsString;
+ const CMIUtilString m_constStrPrintExpandAggregates;
+ const CMIUtilString m_constStrPrintAggregateFieldNames;
// Typedefs:
private:
@@ -201,10 +198,13 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
/* ctor */ CMICmnLLDBDebugSessionInfo(const CMICmnLLDBDebugSessionInfo &);
void operator=(const CMICmnLLDBDebugSessionInfo &);
//
- bool GetVariableInfo(const MIuint vnMaxDepth, const lldb::SBValue &vrValue, const bool vbIsChildValue,
- const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList, MIuint &vrwnDepth);
- bool GetVariableInfo2(const MIuint vnMaxDepth, const lldb::SBValue &vrValue, const bool vbIsChildValue,
- const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList, MIuint &vrwnDepth);
+ bool GetVariableInfo(const lldb::SBValue &vrValue, const bool vbInSimpleForm, CMIUtilString &vwrStrValue);
+ bool GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::addr_t &vwPc, CMIUtilString &vwFnName, CMIUtilString &vwFileName,
+ CMIUtilString &vwPath, MIuint &vwnLine);
+ bool GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, const FrameInfoFormat_e veFrameInfoFormat,
+ CMIUtilString &vwrThreadFrames);
+ bool MIResponseForVariableInfoInternal(const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList,
+ const lldb::SBValueList &vwrSBValueList, const MIuint vnMaxDepth, const bool vbIsArgs, const bool vbMarkArgs);
// Overridden:
private:
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp
index c9abdd1cf90c..a42964c136cb 100644
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp
+++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.cpp
@@ -7,34 +7,23 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBDebugSessionInfoVarObj.cpp
-//
-// Overview: CMICmnLLDBDebugSessionInfoVarObj implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnLLDBDebugSessionInfoVarObj.h"
#include "MICmnLLDBProxySBValue.h"
#include "MICmnLLDBUtilSBValue.h"
// Instantiations:
-const MIchar *CMICmnLLDBDebugSessionInfoVarObj::ms_aVarFormatStrings[] = {
+const char *CMICmnLLDBDebugSessionInfoVarObj::ms_aVarFormatStrings[] = {
// CODETAG_SESSIONINFO_VARFORMAT_ENUM
// *** Order is import here.
"<Invalid var format>", "binary", "octal", "decimal", "hexadecimal", "natural"};
-const MIchar *CMICmnLLDBDebugSessionInfoVarObj::ms_aVarFormatChars[] = {
+const char *CMICmnLLDBDebugSessionInfoVarObj::ms_aVarFormatChars[] = {
// CODETAG_SESSIONINFO_VARFORMAT_ENUM
// *** Order is import here.
"<Invalid var format>", "t", "o", "d", "x", "N"};
CMICmnLLDBDebugSessionInfoVarObj::MapKeyToVarObj_t CMICmnLLDBDebugSessionInfoVarObj::ms_mapVarIdToVarObj;
MIuint CMICmnLLDBDebugSessionInfoVarObj::ms_nVarUniqueId = 0; // Index from 0
+CMICmnLLDBDebugSessionInfoVarObj::varFormat_e CMICmnLLDBDebugSessionInfoVarObj::ms_eDefaultFormat = eVarFormat_Natural;
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfoVarObj constructor.
@@ -234,7 +223,7 @@ CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(const CMIUtilString &vrS
// CODETAG_SESSIONINFO_VARFORMAT_ENUM
for (MIuint i = 0; i < eVarFormat_count; i++)
{
- const MIchar *pVarFormatString = ms_aVarFormatStrings[i];
+ const char *pVarFormatString = ms_aVarFormatStrings[i];
if (vrStrFormat == pVarFormatString)
return static_cast<varFormat_e>(i);
}
@@ -245,22 +234,22 @@ CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForString(const CMIUtilString &vrS
//++ ------------------------------------------------------------------------------------
// Details: Retrieve the var format enumeration for the specified character.
// Type: Static method.
-// Args: vrcFormat - (R) Character representing the var format.
+// Args: vcFormat - Character representing the var format.
// Return: varFormat_e - Var format enumeration.
// - No match found return eVarFormat_Invalid.
// Throws: None.
//--
CMICmnLLDBDebugSessionInfoVarObj::varFormat_e
-CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar(const MIchar &vrcFormat)
+CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar(char vcFormat)
{
- if ('r' == vrcFormat)
+ if ('r' == vcFormat)
return eVarFormat_Hex;
// CODETAG_SESSIONINFO_VARFORMAT_ENUM
for (MIuint i = 0; i < eVarFormat_count; i++)
{
- const MIchar *pVarFormatChar = ms_aVarFormatChars[i];
- if (*pVarFormatChar == vrcFormat)
+ const char *pVarFormatChar = ms_aVarFormatChars[i];
+ if (*pVarFormatChar == vcFormat)
return static_cast<varFormat_e>(i);
}
@@ -268,7 +257,9 @@ CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar(const MIchar &vrcFormat)
}
//++ ------------------------------------------------------------------------------------
-// Details: Return the equivalent var value formatted string for the given value type.
+// Details: Return the equivalent var value formatted string for the given value type,
+// which was prepared for printing (i.e. value was escaped and now it's ready
+// for wrapping into quotes).
// The SBValue vrValue parameter is checked by LLDB private code for valid
// scalar type via MI Driver proxy function as the valued returned can also be
// an error condition. The proxy function determines if the check was valid
@@ -283,21 +274,18 @@ CMIUtilString
CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(const lldb::SBValue &vrValue,
const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat)
{
- CMIUtilString strFormattedValue;
-
- MIuint64 nValue = 0;
- if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(vrValue, nValue) == MIstatus::success)
- {
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
- strFormattedValue = GetStringFormatted(nValue, rValue.GetValue(), veVarFormat);
- }
- else
+ const CMICmnLLDBUtilSBValue utilValue(vrValue, true);
+ if (utilValue.IsIntegerType())
{
- // Composite variable type i.e. struct
- strFormattedValue = "{...}";
+ MIuint64 nValue = 0;
+ if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(vrValue, nValue))
+ {
+ lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
+ return GetStringFormatted(nValue, rValue.GetValue(), veVarFormat);
+ }
}
- return strFormattedValue;
+ return utilValue.GetValue().Escape().AddSlashes();
}
//++ ------------------------------------------------------------------------------------
@@ -310,12 +298,17 @@ CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(const lldb::SBValue &v
// Throws: None.
//--
CMIUtilString
-CMICmnLLDBDebugSessionInfoVarObj::GetStringFormatted(const MIuint64 vnValue, const MIchar *vpStrValueNatural,
+CMICmnLLDBDebugSessionInfoVarObj::GetStringFormatted(const MIuint64 vnValue, const char *vpStrValueNatural,
const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat)
{
CMIUtilString strFormattedValue;
+ CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veFormat = veVarFormat;
+ if (ms_eDefaultFormat != eVarFormat_Invalid && veVarFormat == eVarFormat_Natural)
+ {
+ veFormat = ms_eDefaultFormat;
+ }
- switch (veVarFormat)
+ switch (veFormat)
{
case eVarFormat_Binary:
strFormattedValue = CMIUtilString::FormatBinary(vnValue);
@@ -434,6 +427,20 @@ CMICmnLLDBDebugSessionInfoVarObj::VarObjIdResetToZero(void)
}
//++ ------------------------------------------------------------------------------------
+// Details: Default format is globally used as the data format when "natural" is in effect, that is, this overrides the default
+// Type: Static method.
+// Args: None.
+// Returns: None.
+// Throws: None.
+//--
+void
+CMICmnLLDBDebugSessionInfoVarObj::VarObjSetFormat(varFormat_e eDefaultFormat)
+{
+ ms_eDefaultFormat = eDefaultFormat;
+}
+
+
+//++ ------------------------------------------------------------------------------------
// Details: A count is kept of the number of var value objects created. This is count is
// used to ID the var value object. Increment the count by 1.
// Type: Static method.
@@ -508,6 +515,19 @@ CMICmnLLDBDebugSessionInfoVarObj::GetValueFormatted(void) const
// Returns: lldb::SBValue & - LLDB Value object.
// Throws: None.
//--
+lldb::SBValue &
+CMICmnLLDBDebugSessionInfoVarObj::GetValue(void)
+{
+ return m_SBValue;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the LLDB Value object.
+// Type: Method.
+// Args: None.
+// Returns: lldb::SBValue & - Constant LLDB Value object.
+// Throws: None.
+//--
const lldb::SBValue &
CMICmnLLDBDebugSessionInfoVarObj::GetValue(void) const
{
@@ -543,7 +563,7 @@ CMICmnLLDBDebugSessionInfoVarObj::SetVarFormat(const varFormat_e veVarFormat)
void
CMICmnLLDBDebugSessionInfoVarObj::UpdateValue(void)
{
- m_strFormattedValue = CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(m_SBValue, m_eVarFormat);
+ m_strFormattedValue = GetValueStringFormatted(m_SBValue, m_eVarFormat);
MIuint64 nValue = 0;
if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(m_SBValue, nValue) == MIstatus::failure)
diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h
index ecc960c85d0a..ad5a6ab680f2 100644
--- a/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h
+++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfoVarObj.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBDebugSessionInfoVarObj.h
-//
-// Overview: CMICmnLLDBDebugSessionInfoVarObj interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third Party Headers:
@@ -69,7 +57,7 @@ class CMICmnLLDBDebugSessionInfoVarObj
// Statics:
public:
static varFormat_e GetVarFormatForString(const CMIUtilString &vrStrFormat);
- static varFormat_e GetVarFormatForChar(const MIchar &vrcFormat);
+ static varFormat_e GetVarFormatForChar(char vcFormat);
static CMIUtilString GetValueStringFormatted(const lldb::SBValue &vrValue, const varFormat_e veVarFormat);
static void VarObjAdd(const CMICmnLLDBDebugSessionInfoVarObj &vrVarObj);
static void VarObjDelete(const CMIUtilString &vrVarName);
@@ -79,6 +67,7 @@ class CMICmnLLDBDebugSessionInfoVarObj
static MIuint VarObjIdGet(void);
static void VarObjIdResetToZero(void);
static void VarObjClear(void);
+ static void VarObjSetFormat(varFormat_e eDefaultFormat);
// Methods:
public:
@@ -97,6 +86,7 @@ class CMICmnLLDBDebugSessionInfoVarObj
const CMIUtilString &GetName(void) const;
const CMIUtilString &GetNameReal(void) const;
const CMIUtilString &GetValueFormatted(void) const;
+ lldb::SBValue &GetValue(void);
const lldb::SBValue &GetValue(void) const;
varType_e GetType(void) const;
bool SetVarFormat(const varFormat_e veVarFormat);
@@ -115,7 +105,7 @@ class CMICmnLLDBDebugSessionInfoVarObj
// Statics:
private:
- static CMIUtilString GetStringFormatted(const MIuint64 vnValue, const MIchar *vpStrValueNatural, varFormat_e veVarFormat);
+ static CMIUtilString GetStringFormatted(const MIuint64 vnValue, const char *vpStrValueNatural, varFormat_e veVarFormat);
// Methods:
private:
@@ -124,10 +114,11 @@ class CMICmnLLDBDebugSessionInfoVarObj
// Attributes:
private:
- static const MIchar *ms_aVarFormatStrings[];
- static const MIchar *ms_aVarFormatChars[];
+ static const char *ms_aVarFormatStrings[];
+ static const char *ms_aVarFormatChars[];
static MapKeyToVarObj_t ms_mapVarIdToVarObj;
static MIuint ms_nVarUniqueId;
+ static varFormat_e ms_eDefaultFormat; // overrides "natural" format
//
// *** Upate the copy move constructors and assignment operator ***
varFormat_e m_eVarFormat;
diff --git a/tools/lldb-mi/MICmnLLDBDebugger.cpp b/tools/lldb-mi/MICmnLLDBDebugger.cpp
index 37ddda4db0ce..5d4a09a8a43b 100644
--- a/tools/lldb-mi/MICmnLLDBDebugger.cpp
+++ b/tools/lldb-mi/MICmnLLDBDebugger.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBDebugger.cpp
-//
-// Overview: CMICmnLLDBDebugger implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third party headers:
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
@@ -234,6 +222,73 @@ CMICmnLLDBDebugger::GetDriver(void) const
}
//++ ------------------------------------------------------------------------------------
+// Details: Wait until all events have been handled.
+// This function works in pair with CMICmnLLDBDebugger::MonitorSBListenerEvents
+// that handles events from queue. When all events were handled and queue is
+// empty the MonitorSBListenerEvents notifies this function that it's ready to
+// go on. To synchronize them the m_mutexEventQueue and
+// m_conditionEventQueueEmpty are used.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+void
+CMICmnLLDBDebugger::WaitForHandleEvent(void)
+{
+ std::unique_lock<std::mutex> lock(m_mutexEventQueue);
+
+ lldb::SBEvent event;
+ if (ThreadIsActive() && m_lldbListener.PeekAtNextEvent(event))
+ m_conditionEventQueueEmpty.wait(lock);
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Check if need to rebroadcast stop event. This function will return true if
+// debugger is in synchronouse mode. In such case the
+// CMICmnLLDBDebugger::RebroadcastStopEvent should be called to rebroadcast
+// a new stop event (if any).
+// Type: Method.
+// Args: None.
+// Return: bool - True = Need to rebroadcast stop event, false = otherwise.
+// Throws: None.
+//--
+bool
+CMICmnLLDBDebugger::CheckIfNeedToRebroadcastStopEvent(void)
+{
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ if (!rSessionInfo.GetDebugger().GetAsync())
+ {
+ const bool include_expression_stops = false;
+ m_nLastStopId = CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetStopID(include_expression_stops);
+ return true;
+ }
+
+ return false;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Rebroadcast stop event if needed. This function should be called only if the
+// CMICmnLLDBDebugger::CheckIfNeedToRebroadcastStopEvent() returned true.
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+void
+CMICmnLLDBDebugger::RebroadcastStopEvent(void)
+{
+ lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ const bool include_expression_stops = false;
+ const uint32_t nStopId = process.GetStopID(include_expression_stops);
+ if (m_nLastStopId != nStopId)
+ {
+ lldb::SBEvent event = process.GetStopEventForStopID(nStopId);
+ process.GetBroadcaster().BroadcastEvent(event);
+ }
+}
+
+//++ ------------------------------------------------------------------------------------
// Details: Initialize the LLDB Debugger object.
// Type: Method.
// Args: None.
@@ -245,11 +300,15 @@ bool
CMICmnLLDBDebugger::InitSBDebugger(void)
{
m_lldbDebugger = lldb::SBDebugger::Create(false);
- if (m_lldbDebugger.IsValid())
- return MIstatus::success;
+ if (!m_lldbDebugger.IsValid())
+ {
+ SetErrorDescription(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDDEBUGGER));
+ return MIstatus::failure;
+ }
- SetErrorDescription(MIRSRC(IDS_LLDBDEBUGGER_ERR_INVALIDDEBUGGER));
- return MIstatus::failure;
+ m_lldbDebugger.GetCommandInterpreter().SetPromptOnQuit(false);
+
+ return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
@@ -275,7 +334,7 @@ CMICmnLLDBDebugger::InitStdStreams(void)
}
//++ ------------------------------------------------------------------------------------
-// Details: Set up the events from the SBDebugger's we would to listent to.
+// Details: Set up the events from the SBDebugger's we would like to listen to.
// Type: Method.
// Args: None.
// Return: MIstatus::success - Functionality succeeded.
@@ -293,7 +352,9 @@ CMICmnLLDBDebugger::InitSBListener(void)
}
const CMIUtilString strDbgId("CMICmnLLDBDebugger1");
- MIuint eventMask = lldb::SBTarget::eBroadcastBitBreakpointChanged;
+ MIuint eventMask = lldb::SBTarget::eBroadcastBitBreakpointChanged | lldb::SBTarget::eBroadcastBitModulesLoaded |
+ lldb::SBTarget::eBroadcastBitModulesUnloaded | lldb::SBTarget::eBroadcastBitWatchpointChanged |
+ lldb::SBTarget::eBroadcastBitSymbolsLoaded;
bool bOk = RegisterForEvent(strDbgId, CMIUtilString(lldb::SBTarget::GetBroadcasterClassName()), eventMask);
eventMask = lldb::SBThread::eBroadcastBitStackChanged;
@@ -306,7 +367,7 @@ CMICmnLLDBDebugger::InitSBListener(void)
eventMask = lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived | lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit |
lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData;
- bOk = bOk && RegisterForEvent(strDbgId, CMIUtilString(lldb::SBCommandInterpreter::GetBroadcasterClass()), eventMask);
+ bOk = bOk && RegisterForEvent(strDbgId, m_lldbDebugger.GetCommandInterpreter().GetBroadcaster(), eventMask);
return bOk;
}
@@ -332,7 +393,7 @@ CMICmnLLDBDebugger::RegisterForEvent(const CMIUtilString &vClientName, const CMI
if (!ClientSaveMask(vClientName, vBroadcasterClass, vEventMask))
return MIstatus::failure;
- const MIchar *pBroadCasterName = vBroadcasterClass.c_str();
+ const char *pBroadCasterName = vBroadcasterClass.c_str();
MIuint eventMask = vEventMask;
eventMask += existingMask;
const MIuint result = m_lldbListener.StartListeningForEventClass(m_lldbDebugger, pBroadCasterName, eventMask);
@@ -359,7 +420,7 @@ CMICmnLLDBDebugger::RegisterForEvent(const CMIUtilString &vClientName, const CMI
bool
CMICmnLLDBDebugger::RegisterForEvent(const CMIUtilString &vClientName, const lldb::SBBroadcaster &vBroadcaster, const MIuint vEventMask)
{
- const MIchar *pBroadcasterName = vBroadcaster.GetName();
+ const char *pBroadcasterName = vBroadcaster.GetName();
if (pBroadcasterName == nullptr)
{
SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME), MIRSRC(IDS_WORD_INVALIDNULLPTR)));
@@ -424,7 +485,7 @@ CMICmnLLDBDebugger::UnregisterForEvent(const CMIUtilString &vClientName, const C
}
}
- const MIchar *pBroadCasterName = vBroadcasterClass.c_str();
+ const char *pBroadCasterName = vBroadcasterClass.c_str();
if (!m_lldbListener.StopListeningForEventClass(m_lldbDebugger, pBroadCasterName, newEventMask))
{
SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_STOPLISTENER), vClientName.c_str(), pBroadCasterName));
@@ -626,7 +687,7 @@ CMICmnLLDBDebugger::ClientGetTheirMask(const CMIUtilString &vClientName, const C
vwEventMask = (*it).second;
}
- SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERD), vClientName.c_str()));
+ SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERED), vClientName.c_str()));
return MIstatus::failure;
}
@@ -635,7 +696,7 @@ CMICmnLLDBDebugger::ClientGetTheirMask(const CMIUtilString &vClientName, const C
// Details: Momentarily wait for an events being broadcast and inspect those that do
// come this way. Check if the target should exit event if so start shutting
// down this thread and the application. Any other events pass on to the
-// Out-of-band handler to futher determine what kind of event arrived.
+// Out-of-band handler to further determine what kind of event arrived.
// This function runs in the thread "MI debugger event".
// Type: Method.
// Args: vrbIsAlive - (W) False = yes exit event monitoring thread, true = continue.
@@ -648,49 +709,48 @@ CMICmnLLDBDebugger::MonitorSBListenerEvents(bool &vrbIsAlive)
{
vrbIsAlive = true;
+ // Lock the mutex of event queue
+ // Note that it should be locked while we are in CMICmnLLDBDebugger::MonitorSBListenerEvents to
+ // avoid a race condition with CMICmnLLDBDebugger::WaitForHandleEvent
+ std::unique_lock<std::mutex> lock(m_mutexEventQueue);
+
lldb::SBEvent event;
const bool bGotEvent = m_lldbListener.GetNextEvent(event);
- if (!bGotEvent || !event.IsValid())
+ if (!bGotEvent)
{
+ // Notify that we are finished and unlock the mutex of event queue before sleeping
+ m_conditionEventQueueEmpty.notify_one();
+ lock.unlock();
+
+ // Wait a bit to reduce CPU load
const std::chrono::milliseconds time(1);
std::this_thread::sleep_for(time);
return MIstatus::success;
}
- if (!event.GetBroadcaster().IsValid())
- return MIstatus::success;
+ assert(event.IsValid());
+ assert(event.GetBroadcaster().IsValid());
// Debugging
m_pLog->WriteLog(CMIUtilString::Format("##### An event occurred: %s", event.GetBroadcasterClass()));
bool bHandledEvent = false;
- bool bExitAppEvent = false;
-
bool bOk = false;
{
// Lock Mutex before handling events so that we don't disturb a running cmd
CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
- bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, bHandledEvent, bExitAppEvent);
+ bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, bHandledEvent);
}
+
if (!bHandledEvent)
{
const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT), event.GetBroadcasterClass()));
m_pLog->WriteLog(msg);
}
+
if (!bOk)
- {
m_pLog->WriteLog(CMICmnLLDBDebuggerHandleEvents::Instance().GetErrorDescription());
- }
-
- if (bExitAppEvent)
- {
- // Set the application to shutdown
- m_pClientDriver->SetExitApplicationFlag(true);
- // Kill *this thread
- vrbIsAlive = false;
- }
-
- return bOk;
+ return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
diff --git a/tools/lldb-mi/MICmnLLDBDebugger.h b/tools/lldb-mi/MICmnLLDBDebugger.h
index 403d71d0e32d..6c7e90006d8e 100644
--- a/tools/lldb-mi/MICmnLLDBDebugger.h
+++ b/tools/lldb-mi/MICmnLLDBDebugger.h
@@ -7,23 +7,12 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBDebugger.h
-//
-// Overview: CMICmnLLDBDebugger interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers
-#include <queue>
+#include <condition_variable>
#include <map>
+#include <mutex>
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBEvent.h"
@@ -60,6 +49,9 @@ class CMICmnLLDBDebugger : public CMICmnBase, public CMIUtilThreadActiveObjBase,
CMIDriverBase &GetDriver(void) const;
lldb::SBDebugger &GetTheDebugger(void);
lldb::SBListener &GetTheListener(void);
+ void WaitForHandleEvent(void);
+ bool CheckIfNeedToRebroadcastStopEvent(void);
+ void RebroadcastStopEvent(void);
// MI Commands can use these functions to listen for events they require
bool RegisterForEvent(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass, const MIuint vEventMask);
@@ -118,4 +110,7 @@ class CMICmnLLDBDebugger : public CMICmnBase, public CMIUtilThreadActiveObjBase,
const CMIUtilString m_constStrThisThreadId;
MapBroadcastClassNameToEventMask_t m_mapBroadcastClassNameToEventMask;
MapIdToEventMask_t m_mapIdToEventMask;
+ std::mutex m_mutexEventQueue;
+ std::condition_variable m_conditionEventQueueEmpty;
+ uint32_t m_nLastStopId;
};
diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
index 50049e643ec7..49fce12739f8 100644
--- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
+++ b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
@@ -7,37 +7,28 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBDebuggerHandleEvents.cpp
-//
-// Overview: CMICmnLLDBDebuggerHandleEvents implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third party headers:
+#include "lldb/API/SBAddress.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBStream.h"
+#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
+#include "lldb/API/SBUnixSignals.h"
#ifdef _WIN32
#include <io.h> // For the ::_access()
#else
#include <unistd.h> // For the ::access()
#endif // _WIN32
-#include <limits.h>
// In-house headers:
#include "MICmnLLDBDebuggerHandleEvents.h"
#include "MICmnResources.h"
#include "MICmnLog.h"
+#include "MICmnLLDBDebugger.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"
@@ -47,6 +38,7 @@
#include "MICmnStreamStderr.h"
#include "MIUtilDebug.h"
#include "MIDriver.h"
+#include "Platform.h" // for PATH_MAX
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebuggerHandleEvents constructor.
@@ -88,6 +80,11 @@ CMICmnLLDBDebuggerHandleEvents::Initialize(void)
return MIstatus::success;
m_bInitialized = MIstatus::success;
+ m_bSignalsInitialized = false;
+ m_SIGINT = 0;
+ m_SIGSTOP = 0;
+ m_SIGSEGV = 0;
+ m_SIGTRAP = 0;
return m_bInitialized;
}
@@ -120,22 +117,20 @@ CMICmnLLDBDebuggerHandleEvents::Shutdown(void)
// Type: Method.
// Args: vEvent - (R) An LLDB broadcast event.
// vrbHandledEvent - (W) True - event handled, false = not handled.
-// vrbExitAppEvent - (W) True - Received LLDB exit app event, false = did not.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool
-CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent, bool &vrbExitAppEvent)
+CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent)
{
bool bOk = MIstatus::success;
vrbHandledEvent = false;
- vrbExitAppEvent = false;
if (lldb::SBProcess::EventIsProcessEvent(vEvent))
{
vrbHandledEvent = true;
- bOk = HandleEventSBProcess(vEvent, vrbExitAppEvent);
+ bOk = HandleEventSBProcess(vEvent);
}
else if (lldb::SBBreakpoint::EventIsBreakpointEvent(vEvent))
{
@@ -147,6 +142,16 @@ CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent, bool &v
vrbHandledEvent = true;
bOk = HandleEventSBThread(vEvent);
}
+ else if (lldb::SBTarget::EventIsTargetEvent(vEvent))
+ {
+ vrbHandledEvent = true;
+ bOk = HandleEventSBTarget(vEvent);
+ }
+ else if (lldb::SBCommandInterpreter::EventIsCommandInterpreterEvent(vEvent))
+ {
+ vrbHandledEvent = true;
+ bOk = HandleEventSBCommandInterpreter(vEvent);
+ }
return bOk;
}
@@ -155,17 +160,16 @@ CMICmnLLDBDebuggerHandleEvents::HandleEvent(const lldb::SBEvent &vEvent, bool &v
// Details: Handle a LLDB SBProcess event.
// Type: Method.
// Args: vEvent - (R) An LLDB broadcast event.
-// vrbExitAppEvent - (W) True - Received LLDB exit app event, false = did not.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool
-CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess(const lldb::SBEvent &vEvent, bool &vrbExitAppEvent)
+CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess(const lldb::SBEvent &vEvent)
{
bool bOk = MIstatus::success;
- const MIchar *pEventType = "";
+ const char *pEventType = "";
const MIuint nEventType = vEvent.GetType();
switch (nEventType)
{
@@ -177,7 +181,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess(const lldb::SBEvent &vEvent
break;
case lldb::SBProcess::eBroadcastBitStateChanged:
pEventType = "eBroadcastBitStateChanged";
- bOk = HandleProcessEventBroadcastBitStateChanged(vEvent, vrbExitAppEvent);
+ bOk = HandleProcessEventBroadcastBitStateChanged(vEvent);
break;
case lldb::SBProcess::eBroadcastBitSTDERR:
pEventType = "eBroadcastBitSTDERR";
@@ -212,7 +216,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakPoint(const lldb::SBEvent &vEv
{
bool bOk = MIstatus::success;
- const MIchar *pEventType = "";
+ const char *pEventType = "";
const lldb::BreakpointEventType eEvent = lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent(vEvent);
switch (eEvent)
{
@@ -239,6 +243,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakPoint(const lldb::SBEvent &vEv
break;
case lldb::eBreakpointEventTypeLocationsResolved:
pEventType = "eBreakpointEventTypeLocationsResolved";
+ bOk = HandleEventSBBreakpointCmn(vEvent);
break;
case lldb::eBreakpointEventTypeEnabled:
pEventType = "eBreakpointEventTypeEnabled";
@@ -335,7 +340,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointCmn(const lldb::SBEvent &
sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
- // MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\",
+ // MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\",
// func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
CMICmnMIValueTuple miValueTuple;
if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple))
@@ -413,7 +418,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointAdded(const lldb::SBEvent
sBrkPtInfo.m_strOrigLoc = CMIUtilString::Format("%s:%d", sBrkPtInfo.m_fileName.c_str(), sBrkPtInfo.m_nLine);
sBrkPtInfo.m_nIgnore = brkPt.GetIgnoreCount();
sBrkPtInfo.m_bPending = false;
- const MIchar *pStrCondition = brkPt.GetCondition();
+ const char *pStrCondition = brkPt.GetCondition();
sBrkPtInfo.m_bCondition = (pStrCondition != nullptr) ? true : false;
sBrkPtInfo.m_strCondition = (pStrCondition != nullptr) ? pStrCondition : "??";
sBrkPtInfo.m_bBrkPtThreadId = (brkPt.GetThreadID() != 0) ? true : false;
@@ -431,7 +436,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointAdded(const lldb::SBEvent
if (bBrkPtExistAlready)
{
// MI print
- // "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
+ // "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
const CMICmnMIValueResult miValueResult("bkpt", miValueTuple);
const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult);
bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
@@ -453,7 +458,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointAdded(const lldb::SBEvent
}
// MI print
- // "=breakpoint-created,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
+ // "=breakpoint-created,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
const CMICmnMIValueResult miValueResult("bkpt", miValueTuple);
const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointCreated, miValueResult);
bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
@@ -477,7 +482,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBThread(const lldb::SBEvent &vEvent)
return MIstatus::failure;
bool bOk = MIstatus::success;
- const MIchar *pEventType = "";
+ const char *pEventType = "";
const MIuint nEventType = vEvent.GetType();
switch (nEventType)
{
@@ -565,6 +570,172 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadBitStackChanged(const lldb::S
}
//++ ------------------------------------------------------------------------------------
+// Details: Handle a LLDB SBTarget event.
+// Type: Method.
+// Args: vEvent - (R) An LLDB broadcast event.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmnLLDBDebuggerHandleEvents::HandleEventSBTarget(const lldb::SBEvent &vEvent)
+{
+ if (!ChkForStateChanges())
+ return MIstatus::failure;
+
+ bool bOk = MIstatus::success;
+ const char *pEventType = "";
+ const MIuint nEventType = vEvent.GetType();
+ switch (nEventType)
+ {
+ case lldb::SBTarget::eBroadcastBitBreakpointChanged:
+ pEventType = "eBroadcastBitBreakpointChanged";
+ break;
+ case lldb::SBTarget::eBroadcastBitModulesLoaded:
+ pEventType = "eBroadcastBitModulesLoaded";
+ bOk = HandleTargetEventBroadcastBitModulesLoaded(vEvent);
+ break;
+ case lldb::SBTarget::eBroadcastBitModulesUnloaded:
+ pEventType = "eBroadcastBitModulesUnloaded";
+ bOk = HandleTargetEventBroadcastBitModulesUnloaded(vEvent);
+ break;
+ case lldb::SBTarget::eBroadcastBitWatchpointChanged:
+ pEventType = "eBroadcastBitWatchpointChanged";
+ break;
+ case lldb::SBTarget::eBroadcastBitSymbolsLoaded:
+ pEventType = "eBroadcastBitSymbolsLoaded";
+ break;
+ default:
+ {
+ const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT), "SBTarget", (MIuint)nEventType));
+ SetErrorDescription(msg);
+ return MIstatus::failure;
+ }
+ }
+ m_pLog->WriteLog(CMIUtilString::Format("##### An SBTarget event occurred: %s", pEventType));
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Print to stdout "=library-loaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016" PRIx64"\""
+// Type: Method.
+// Args: None.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmnLLDBDebuggerHandleEvents::HandleTargetEventBroadcastBitModulesLoaded(const lldb::SBEvent &vEvent)
+{
+ bool bOk = MIstatus::failure;
+ const MIuint nSize = lldb::SBTarget::GetNumModulesFromEvent(vEvent);
+ for (MIuint nIndex = 0; nIndex < nSize; ++nIndex)
+ {
+ const lldb::SBModule sbModule = lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleLoaded);
+ const bool bWithExtraFields = true;
+ bOk = MiHelpGetModuleInfo(sbModule, bWithExtraFields, miOutOfBandRecord);
+ bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ if (!bOk)
+ break;
+ }
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Print to stdout "=library-unloaded,id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016" PRIx64"\""
+// Type: Method.
+// Args: None.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmnLLDBDebuggerHandleEvents::HandleTargetEventBroadcastBitModulesUnloaded(const lldb::SBEvent &vEvent)
+{
+ bool bOk = MIstatus::failure;
+ const MIuint nSize = lldb::SBTarget::GetNumModulesFromEvent(vEvent);
+ for (MIuint nIndex = 0; nIndex < nSize; ++nIndex)
+ {
+ const lldb::SBModule sbModule = lldb::SBTarget::GetModuleAtIndexFromEvent(nIndex, vEvent);
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleUnloaded);
+ const bool bWithExtraFields = false;
+ bOk = MiHelpGetModuleInfo(sbModule, bWithExtraFields, miOutOfBandRecord);
+ bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ if (!bOk)
+ break;
+ }
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Build module information for =library-loaded/=library-unloaded: "id=\"%s\",target-name=\"%s\",host-name=\"%s\",symbols-loaded="%d"[,symbols-path=\"%s\"],loaded_addr=\"0x%016" PRIx64"\""
+// Type: Method.
+// Args: vwrMiValueList - (W) MI value list object.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmnLLDBDebuggerHandleEvents::MiHelpGetModuleInfo(const lldb::SBModule &vModule, const bool vbWithExtraFields,
+ CMICmnMIOutOfBandRecord &vwrMiOutOfBandRecord)
+{
+ bool bOk = MIstatus::success;
+
+ // First, build standard fields:
+ // Build "id" field
+ std::unique_ptr<char[]> apPath(new char[PATH_MAX]);
+ vModule.GetFileSpec().GetPath(apPath.get(), PATH_MAX);
+ const CMIUtilString strTargetPath(apPath.get());
+ const CMICmnMIValueConst miValueConst(strTargetPath);
+ const CMICmnMIValueResult miValueResult("id", miValueConst);
+ bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult);
+ // Build "target-name" field
+ const CMICmnMIValueConst miValueConst2(strTargetPath);
+ const CMICmnMIValueResult miValueResult2("target-name", miValueConst2);
+ bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult2);
+ // Build "host-name" field
+ vModule.GetPlatformFileSpec().GetPath(apPath.get(), PATH_MAX);
+ const CMIUtilString strHostPath(apPath.get());
+ const CMICmnMIValueConst miValueConst3(strHostPath);
+ const CMICmnMIValueResult miValueResult3("host-name", miValueConst3);
+ bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult3);
+
+ // Then build extra fields if needed:
+ if (vbWithExtraFields)
+ {
+ // Build "symbols-loaded" field
+ vModule.GetSymbolFileSpec().GetPath(apPath.get(), PATH_MAX);
+ const CMIUtilString strSymbolsPath(apPath.get());
+ const bool bSymbolsLoaded = !CMIUtilString::Compare(strHostPath, strSymbolsPath);
+ const CMICmnMIValueConst miValueConst4(CMIUtilString::Format("%d", bSymbolsLoaded));
+ const CMICmnMIValueResult miValueResult4("symbols-loaded", miValueConst4);
+ bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult4);
+ // Build "symbols-path" field
+ if (bSymbolsLoaded)
+ {
+ const CMICmnMIValueConst miValueConst5(strSymbolsPath);
+ const CMICmnMIValueResult miValueResult5("symbols-path", miValueConst5);
+ bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult5);
+ }
+ // Build "loaded_addr" field
+ const lldb::SBAddress sbAddress(vModule.GetObjectFileHeaderAddress());
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ const lldb::addr_t nLoadAddress(sbAddress.GetLoadAddress(rSessionInfo.GetTarget()));
+ const CMIUtilString strLoadedAddr(nLoadAddress != LLDB_INVALID_ADDRESS ?
+ CMIUtilString::Format("0x%016" PRIx64, nLoadAddress) : "-");
+ const CMICmnMIValueConst miValueConst6(strLoadedAddr);
+ const CMICmnMIValueResult miValueResult6("loaded_addr", miValueConst6);
+ bOk = bOk && vwrMiOutOfBandRecord.Add(miValueResult6);
+ }
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
// Details: Handle a LLDB SBCommandInterpreter event.
// Type: Method.
// Args: vEvent - (R) An LLDB command interpreter event.
@@ -578,7 +749,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter(const lldb::SBEv
// This function is not used
// *** This function is under development
- const MIchar *pEventType = "";
+ const char *pEventType = "";
const MIuint nEventType = vEvent.GetType();
switch (nEventType)
{
@@ -596,8 +767,12 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter(const lldb::SBEv
pEventType = "eBroadcastBitResetPrompt";
break;
case lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived:
+ {
pEventType = "eBroadcastBitQuitCommandReceived";
+ const bool bForceExit = true;
+ CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag(bForceExit);
break;
+ }
case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData:
pEventType = "eBroadcastBitAsynchronousOutputData";
break;
@@ -621,14 +796,17 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter(const lldb::SBEv
// Details: Handle SBProcess event eBroadcastBitStateChanged.
// Type: Method.
// Args: vEvent - (R) An LLDB event object.
-// vrbExitAppEvent - (W) True - Received LLDB exit app event, false = did not.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool
-CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(const lldb::SBEvent &vEvent, bool &vrbExitAppEvent)
+CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(const lldb::SBEvent &vEvent)
{
+ // Make sure the program hasn't been auto-restarted:
+ if (lldb::SBProcess::GetRestartedFromEvent(vEvent))
+ return MIstatus::success;
+
bool bOk = ChkForStateChanges();
bOk = bOk && GetProcessStdout();
bOk = bOk && GetProcessStderr();
@@ -651,7 +829,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(const
}
bool bShouldBrk = true;
- const MIchar *pEventType = "";
+ const char *pEventType = "";
switch (eEventState)
{
case lldb::eStateUnloaded:
@@ -668,7 +846,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(const
break;
case lldb::eStateStopped:
pEventType = "eStateStopped";
- bOk = HandleProcessEventStateStopped(bShouldBrk);
+ bOk = HandleProcessEventStateStopped(vEvent, bShouldBrk);
if (bShouldBrk)
break;
case lldb::eStateCrashed:
@@ -687,8 +865,8 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(const
pEventType = "eStateDetached";
break;
case lldb::eStateExited:
+ // Don't exit from lldb-mi here. We should be able to re-run target.
pEventType = "eStateExited";
- vrbExitAppEvent = true;
bOk = HandleProcessEventStateExited();
break;
default:
@@ -717,10 +895,6 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged(const
bool
CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended(const lldb::SBEvent &vEvent)
{
- // Make sure the program hasn't been auto-restarted:
- if (lldb::SBProcess::GetRestartedFromEvent(vEvent))
- return MIstatus::success;
-
bool bOk = MIstatus::success;
lldb::SBDebugger &rDebugger = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger();
lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
@@ -761,12 +935,12 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended(const lldb::SBE
// Throws: None.
//--
bool
-CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped(bool &vwrbShouldBrk)
+CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped(const lldb::SBEvent &vrEvent, bool &vwrbShouldBrk)
{
if (!UpdateSelectedThread())
return MIstatus::failure;
- const MIchar *pEventType = "";
+ const char *pEventType = "";
bool bOk = MIstatus::success;
lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
const lldb::StopReason eStoppedReason = sbProcess.GetSelectedThread().GetStopReason();
@@ -792,10 +966,11 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped(bool &vwrbShouldB
break;
case lldb::eStopReasonSignal:
pEventType = "eStopReasonSignal";
- bOk = HandleProcessEventStopSignal(vwrbShouldBrk);
+ bOk = HandleProcessEventStopSignal(vrEvent);
break;
case lldb::eStopReasonException:
pEventType = "eStopReasonException";
+ bOk = HandleProcessEventStopException();
break;
case lldb::eStopReasonExec:
pEventType = "eStopReasonExec";
@@ -821,111 +996,185 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped(bool &vwrbShouldB
//++ ------------------------------------------------------------------------------------
// Details: Asynchronous event handler for LLDB Process stop signal.
// Type: Method.
-// Args: vwrbShouldBrk - (W) True = Yes break, false = do not.
+// Args: vrEvent - (R) An LLDB broadcast event.
// Return: MIstatus::success - Functionality succeeded.
// MIstatus::failure - Functionality failed.
// Throws: None.
//--
bool
-CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal(bool &vwrbShouldBrk)
+CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal(const lldb::SBEvent &vrEvent)
{
bool bOk = MIstatus::success;
+ InitializeSignals ();
lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
const MIuint64 nStopReason = sbProcess.GetSelectedThread().GetStopReasonDataAtIndex(0);
- switch (nStopReason)
+ const bool bInterrupted = lldb::SBProcess::GetInterruptedFromEvent(vrEvent);
+ if (nStopReason == m_SIGINT || (nStopReason == m_SIGSTOP && bInterrupted))
{
- case 2: // Terminal interrupt signal. SIGINT
- {
- // MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGNINT\",signal-meaning=\"Interrupt\",frame={%s}"
- const CMICmnMIValueConst miValueConst("signal-received");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMICmnMIValueConst miValueConst2("SIGINT");
- const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
- bOk = miOutOfBandRecord.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3("Interrupt");
- const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
- bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
- CMICmnMIValueTuple miValueTuple;
- bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
- const CMICmnMIValueResult miValueResult5("frame", miValueTuple);
- bOk = bOk && miOutOfBandRecord.Add(miValueResult5);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && TextToStdout("(gdb)");
- }
- break;
- case 11: // Invalid memory reference. SIGSEGV
- {
- // MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGSEGV\",signal-meaning=\"Segmentation
- // fault\",thread-id=\"%d\",frame={%s}"
- const CMICmnMIValueConst miValueConst("signal-received");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMICmnMIValueConst miValueConst2("SIGSEGV");
- const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
- bOk = miOutOfBandRecord.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3("Segmentation fault");
- const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
- bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
- const CMIUtilString strThreadId(CMIUtilString::Format("%d", sbProcess.GetSelectedThread().GetIndexID()));
- const CMICmnMIValueConst miValueConst4(strThreadId);
- const CMICmnMIValueResult miValueResult4("thread-id", miValueConst4);
- bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
- CMICmnMIValueTuple miValueTuple;
- bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
- const CMICmnMIValueResult miValueResult5("frame", miValueTuple);
- bOk = bOk && miOutOfBandRecord.Add(miValueResult5);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- // Note no "(gdb)" output here
- }
- break;
- case 19:
- if (sbProcess.IsValid())
- sbProcess.Continue();
- break;
- case 5: // Trace/breakpoint trap. SIGTRAP
+ // MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGINT\",signal-meaning=\"Interrupt\",frame={%s},thread-id=\"%d\",stopped-threads=\"all\""
+ const CMICmnMIValueConst miValueConst("signal-received");
+ const CMICmnMIValueResult miValueResult("reason", miValueConst);
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
+ const CMICmnMIValueConst miValueConst2("SIGINT");
+ const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
+ bOk = miOutOfBandRecord.Add(miValueResult2);
+ const CMICmnMIValueConst miValueConst3("Interrupt");
+ const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
+ CMICmnMIValueTuple miValueTuple;
+ bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
+ const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
+ const CMIUtilString strThreadId(CMIUtilString::Format("%" PRIu32, sbProcess.GetSelectedThread().GetIndexID()));
+ const CMICmnMIValueConst miValueConst5(strThreadId);
+ const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult5);
+ const CMICmnMIValueConst miValueConst6("all");
+ const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult6);
+ bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
+ }
+ else if (nStopReason == m_SIGSTOP)
+ {
+ // MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGSTOP\",signal-meaning=\"Stop\",frame={%s},thread-id=\"%d\",stopped-threads=\"all\""
+ const CMICmnMIValueConst miValueConst("signal-received");
+ const CMICmnMIValueResult miValueResult("reason", miValueConst);
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
+ const CMICmnMIValueConst miValueConst2("SIGSTOP");
+ const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
+ bOk = miOutOfBandRecord.Add(miValueResult2);
+ const CMICmnMIValueConst miValueConst3("Stop");
+ const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
+ CMICmnMIValueTuple miValueTuple;
+ bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
+ const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
+ const CMIUtilString strThreadId(CMIUtilString::Format("%" PRIu32, sbProcess.GetSelectedThread().GetIndexID()));
+ const CMICmnMIValueConst miValueConst5(strThreadId);
+ const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult5);
+ const CMICmnMIValueConst miValueConst6("all");
+ const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult6);
+ bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
+ }
+ else if (nStopReason == m_SIGSEGV)
+ {
+ // MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGSEGV\",signal-meaning=\"Segmentation fault\",thread-id=\"%d\",frame={%s}"
+ const CMICmnMIValueConst miValueConst("signal-received");
+ const CMICmnMIValueResult miValueResult("reason", miValueConst);
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
+ const CMICmnMIValueConst miValueConst2("SIGSEGV");
+ const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
+ bOk = miOutOfBandRecord.Add(miValueResult2);
+ const CMICmnMIValueConst miValueConst3("Segmentation fault");
+ const CMICmnMIValueResult miValueResult3("signal-meaning", miValueConst3);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
+ CMICmnMIValueTuple miValueTuple;
+ bOk = bOk && MiHelpGetCurrentThreadFrame(miValueTuple);
+ const CMICmnMIValueResult miValueResult4("frame", miValueTuple);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult4);
+ const CMIUtilString strThreadId(CMIUtilString::Format("%d", sbProcess.GetSelectedThread().GetIndexID()));
+ const CMICmnMIValueConst miValueConst5(strThreadId);
+ const CMICmnMIValueResult miValueResult5("thread-id", miValueConst5);
+ bOk = bOk && miOutOfBandRecord.Add(miValueResult5);
+ bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ // Note no "(gdb)" output here
+ }
+ else if (nStopReason == m_SIGTRAP)
+ {
+ lldb::SBThread thread = sbProcess.GetSelectedThread();
+ const MIuint nFrames = thread.GetNumFrames();
+ if (nFrames > 0)
{
- lldb::SBThread thread = sbProcess.GetSelectedThread();
- const MIuint nFrames = thread.GetNumFrames();
- if (nFrames > 0)
+ lldb::SBFrame frame = thread.GetFrameAtIndex(0);
+ const char *pFnName = frame.GetFunctionName();
+ if (pFnName != nullptr)
{
- lldb::SBFrame frame = thread.GetFrameAtIndex(0);
- const char *pFnName = frame.GetFunctionName();
- if (pFnName != nullptr)
+ const CMIUtilString fnName = CMIUtilString(pFnName);
+ static const CMIUtilString threadCloneFn = CMIUtilString("__pthread_clone");
+
+ if (CMIUtilString::Compare(threadCloneFn, fnName))
{
- const CMIUtilString fnName = CMIUtilString(pFnName);
- static const CMIUtilString threadCloneFn = CMIUtilString("__pthread_clone");
-
- if (CMIUtilString::Compare(threadCloneFn, fnName))
- {
- if (sbProcess.IsValid())
- {
- sbProcess.Continue();
- vwrbShouldBrk = true;
- break;
- }
- }
+ if (sbProcess.IsValid())
+ sbProcess.Continue();
}
}
}
- default:
+ }
+ else
+ {
+ // MI print "*stopped,reason=\"signal-received\",signal-name=\"%s\",thread-id=\"%d\",stopped-threads=\"all\""
+ // MI print "*stopped,reason=\"signal-received\",signal=\"%d\",thread-id=\"%d\",stopped-threads=\"all\""
+ const CMICmnMIValueConst miValueConst("signal-received");
+ const CMICmnMIValueResult miValueResult("reason", miValueConst);
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
+ lldb::SBUnixSignals sbUnixSignals = sbProcess.GetUnixSignals();
+ const char *pSignal = sbUnixSignals.GetSignalAsCString(nStopReason);
+ if (pSignal)
{
- // MI print "*stopped,reason=\"signal-received\",signal=\"%lld\",stopped-threads=\"all\""
- const CMICmnMIValueConst miValueConst("signal-received");
- const CMICmnMIValueResult miValueResult("reason", miValueConst);
- CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
- const CMIUtilString strReason(CMIUtilString::Format("%lld", nStopReason));
- const CMICmnMIValueConst miValueConst2(strReason);
+ const CMICmnMIValueConst miValueConst2(pSignal);
+ const CMICmnMIValueResult miValueResult2("signal-name", miValueConst2);
+ bOk = miOutOfBandRecord.Add(miValueResult2);
+ }
+ else
+ {
+ const CMIUtilString strSignal(CMIUtilString::Format("%" PRIu64, nStopReason));
+ const CMICmnMIValueConst miValueConst2(strSignal);
const CMICmnMIValueResult miValueResult2("signal", miValueConst2);
bOk = miOutOfBandRecord.Add(miValueResult2);
- const CMICmnMIValueConst miValueConst3("all");
- const CMICmnMIValueResult miValueResult3("stopped-threads", miValueConst3);
- bOk = bOk && miOutOfBandRecord.Add(miValueResult3);
- bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && TextToStdout("(gdb)");
}
- } // switch( nStopReason )
+ const CMIUtilString strThreadId(CMIUtilString::Format("%d", sbProcess.GetSelectedThread().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 && CMICmnStreamStdout::WritePrompt();
+ }
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// 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::unique_ptr<char[]> apStopDescription(new char[nStopDescriptionLen]);
+ sbThread.GetStopDescription(apStopDescription.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(apStopDescription.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 && CMICmnStreamStdout::WritePrompt();
return bOk;
}
@@ -966,7 +1215,7 @@ CMICmnLLDBDebuggerHandleEvents::MiHelpGetCurrentThreadFrame(CMICmnMIValueTuple &
}
CMICmnMIValueTuple miValueTuple;
- if (!CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormFrameInfo(thread, 0, miValueTuple))
+ if (!CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormFrameInfo(thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_NoArguments, miValueTuple))
{
SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE), "MiHelpGetCurrentThreadFrame()"));
return MIstatus::failure;
@@ -1045,26 +1294,14 @@ CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint(const MIuint64 vBrkPtId, c
const CMICmnMIValueResult miValueResult6("stopped-threads", miValueConst6);
bOk = bOk && miOutOfBandRecord.Add(miValueResult6);
bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && TextToStdout("(gdb)");
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
return bOk;
}
- CMICmnLLDBDebugSessionInfo &rSession = CMICmnLLDBDebugSessionInfo::Instance();
-
- lldb::SBFrame frame = thread.GetFrameAtIndex(0);
- lldb::addr_t pc = 0;
- CMIUtilString fnName;
- CMIUtilString fileName;
- CMIUtilString path;
- MIuint nLine = 0;
- if (!rSession.GetFrameInfo(frame, pc, fnName, fileName, path, nLine))
- {
- SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET), "MiStoppedAtBreakPoint()"));
- return MIstatus::failure;
- }
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
// MI print
- // "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={addr=\"0x%08x\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
+ // "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
const CMICmnMIValueConst miValueConst("breakpoint-hit");
const CMICmnMIValueResult miValueResult("reason", miValueConst);
CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult);
@@ -1076,15 +1313,11 @@ CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint(const MIuint64 vBrkPtId, c
CMICmnMIValueResult miValueResultB("bkptno", miValueConstB);
bOk = bOk && miOutOfBandRecord.Add(miValueResultB);
- // frame={addr=\"0x%08x\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"}
+ // frame={addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"}
if (bOk)
{
- CMICmnMIValueList miValueList(true);
- const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
- bOk = rSession.MIResponseFormVariableInfo2(frame, maskVarTypes, CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues, miValueList);
-
CMICmnMIValueTuple miValueTuple;
- bOk = bOk && rSession.MIResponseFormFrameInfo2(pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple);
+ bOk = bOk && rSessionInfo.MIResponseFormFrameInfo(thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments, miValueTuple);
const CMICmnMIValueResult miValueResult8("frame", miValueTuple);
bOk = bOk && miOutOfBandRecord.Add(miValueResult8);
}
@@ -1103,7 +1336,7 @@ CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint(const MIuint64 vBrkPtId, c
const CMICmnMIValueResult miValueResult9("stopped-threads", miValueConst9);
bOk = miOutOfBandRecord.Add(miValueResult9);
bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && TextToStdout("(gdb)");
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
}
return MIstatus::success;
@@ -1134,33 +1367,18 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace(void)
const CMICmnMIValueResult miValueResult2("stopped-threads", miValueConst2);
bOk = miOutOfBandRecord.Add(miValueResult2);
bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && TextToStdout("(gdb)");
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
return bOk;
}
- CMICmnLLDBDebugSessionInfo &rSession = CMICmnLLDBDebugSessionInfo::Instance();
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
// MI print
- // "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x%08x\",func=\"%s\",args=[\"%s\"],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
- lldb::SBFrame frame = thread.GetFrameAtIndex(0);
- lldb::addr_t pc = 0;
- CMIUtilString fnName;
- CMIUtilString fileName;
- CMIUtilString path;
- MIuint nLine = 0;
- if (!rSession.GetFrameInfo(frame, pc, fnName, fileName, path, nLine))
- {
- SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET), "HandleProcessEventStopReasonTrace()"));
- return MIstatus::failure;
- }
+ // "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[\"%s\"],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
// Function args
- CMICmnMIValueList miValueList(true);
- const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
- if (!rSession.MIResponseFormVariableInfo2(frame, maskVarTypes, CMICmnLLDBDebugSessionInfo::eVariableInfoFormat_AllValues, miValueList))
- return MIstatus::failure;
CMICmnMIValueTuple miValueTuple;
- if (!rSession.MIResponseFormFrameInfo2(pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple))
+ if (!rSessionInfo.MIResponseFormFrameInfo(thread, 0, CMICmnLLDBDebugSessionInfo::eFrameInfoFormat_AllArguments, miValueTuple))
return MIstatus::failure;
const CMICmnMIValueConst miValueConst("end-stepping-range");
@@ -1183,7 +1401,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace(void)
const CMICmnMIValueResult miValueResult9("stopped-threads", miValueConst9);
bOk = miOutOfBandRecord.Add(miValueResult9);
bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && TextToStdout("(gdb)");
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
}
return bOk;
@@ -1275,7 +1493,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateRunning(void)
CMICmnMIValueResult miValueResult("thread-id", miValueConst);
CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_Running, miValueResult);
bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
- bOk = bOk && TextToStdout("(gdb)");
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
return bOk;
}
@@ -1319,7 +1537,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateExited(void)
CMICmnMIOutOfBandRecord miOutOfBandRecord3(CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult4);
bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord3);
}
- bOk = bOk && TextToStdout("(gdb)");
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
return bOk;
}
@@ -1337,26 +1555,44 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateExited(void)
bool
CMICmnLLDBDebuggerHandleEvents::GetProcessStdout(void)
{
- bool bOk = MIstatus::success;
-
- char c;
- size_t nBytes = 0;
CMIUtilString text;
+ std::unique_ptr<char[]> apStdoutBuffer(new char[1024]);
lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().GetSelectedTarget().GetProcess();
- while (process.GetSTDOUT(&c, 1) > 0)
- {
- CMIUtilString str;
- if (ConvertPrintfCtrlCodeToString(c, str))
- text += str;
- nBytes++;
- }
- if (nBytes > 0)
+ while (1)
{
- const CMIUtilString t(CMIUtilString::Format("~\"%s\"", text.c_str()));
- bOk = TextToStdout(t);
+ const size_t nBytes = process.GetSTDOUT(apStdoutBuffer.get(), 1024);
+ text.append(apStdoutBuffer.get(), nBytes);
+
+ while (1)
+ {
+ const size_t nNewLine = text.find('\n');
+ if (nNewLine == std::string::npos)
+ break;
+
+ const CMIUtilString line(text.substr(0, nNewLine + 1).c_str());
+ text.erase(0, nNewLine + 1);
+ const bool bEscapeQuotes(true);
+ CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
+ const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ if (!bOk)
+ return MIstatus::failure;
+ }
+
+ if (nBytes == 0)
+ {
+ if (!text.empty())
+ {
+ const bool bEscapeQuotes(true);
+ CMICmnMIValueConst miValueConst(text.Escape(bEscapeQuotes));
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
+ return MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ }
+ break;
+ }
}
- return bOk;
+ return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
@@ -1372,69 +1608,40 @@ CMICmnLLDBDebuggerHandleEvents::GetProcessStdout(void)
bool
CMICmnLLDBDebuggerHandleEvents::GetProcessStderr(void)
{
- bool bOk = MIstatus::success;
-
- char c;
- size_t nBytes = 0;
CMIUtilString text;
+ std::unique_ptr<char[]> apStderrBuffer(new char[1024]);
lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger().GetSelectedTarget().GetProcess();
- while (process.GetSTDERR(&c, 1) > 0)
+ while (1)
{
- CMIUtilString str;
- if (ConvertPrintfCtrlCodeToString(c, str))
- text += str;
- nBytes++;
- }
- if (nBytes > 0)
- {
- const CMIUtilString t(CMIUtilString::Format("~\"%s\"", text.c_str()));
- bOk = TextToStdout(t);
- }
+ const size_t nBytes = process.GetSTDERR(apStderrBuffer.get(), 1024);
+ text.append(apStderrBuffer.get(), nBytes);
- return bOk;
-}
+ while (1)
+ {
+ const size_t nNewLine = text.find('\n');
+ if (nNewLine == std::string::npos)
+ break;
-//++ ------------------------------------------------------------------------------------
-// Details: Convert text stream control codes to text equivalent.
-// Type: Method.
-// Args: vCtrl - (R) The control code.
-// vwrStrEquivalent - (W) The text equivalent.
-// Return: MIstatus::success - Functionality succeeded.
-// MIstatus::failure - Functionality failed.
-// Throws: None.
-//--
-bool
-CMICmnLLDBDebuggerHandleEvents::ConvertPrintfCtrlCodeToString(const MIchar vCtrl, CMIUtilString &vwrStrEquivalent)
-{
- switch (vCtrl)
- {
- case '\033':
- vwrStrEquivalent = "\\e";
- break;
- case '\a':
- vwrStrEquivalent = "\\a";
- break;
- case '\b':
- vwrStrEquivalent = "\\b";
- break;
- case '\f':
- vwrStrEquivalent = "\\f";
- break;
- case '\n':
- vwrStrEquivalent = "\\n";
- break;
- case '\r':
- vwrStrEquivalent = "\\r";
- break;
- case '\t':
- vwrStrEquivalent = "\\t";
- break;
- case '\v':
- vwrStrEquivalent = "\\v";
- break;
- default:
- vwrStrEquivalent = CMIUtilString::Format("%c", vCtrl);
+ const CMIUtilString line(text.substr(0, nNewLine + 1).c_str());
+ const bool bEscapeQuotes(true);
+ CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
+ const bool bOk = MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ if (!bOk)
+ return MIstatus::failure;
+ }
+
+ if (nBytes == 0)
+ {
+ if (!text.empty())
+ {
+ const bool bEscapeQuotes(true);
+ CMICmnMIValueConst miValueConst(text.Escape(bEscapeQuotes));
+ CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, miValueConst);
+ return MiOutOfBandRecordToStdout(miOutOfBandRecord);
+ }
break;
+ }
}
return MIstatus::success;
@@ -1451,14 +1658,10 @@ CMICmnLLDBDebuggerHandleEvents::ConvertPrintfCtrlCodeToString(const MIchar vCtrl
bool
CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges(void)
{
- lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
if (!sbProcess.IsValid())
return MIstatus::success;
- lldb::SBTarget sbTarget = CMICmnLLDBDebugSessionInfo::Instance().GetTarget();
- if (!sbTarget.IsValid())
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
// Check for created threads
const MIuint nThread = sbProcess.GetNumThreads();
@@ -1470,33 +1673,20 @@ CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges(void)
if (!thread.IsValid())
continue;
- CMICmnLLDBDebugSessionInfo::VecActiveThreadId_t::const_iterator it =
- CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.begin();
- bool bFound = false;
- while (it != CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.end())
- {
- const MIuint nThreadId = *it;
- if (nThreadId == i)
- {
- bFound = true;
- break;
- }
-
- // Next
- ++it;
- }
+ const MIuint threadIndexID = thread.GetIndexID();
+ const bool bFound = std::find(rSessionInfo.m_vecActiveThreadId.cbegin(), rSessionInfo.m_vecActiveThreadId.cend(), threadIndexID) != rSessionInfo.m_vecActiveThreadId.end();
if (!bFound)
{
- CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.push_back(i);
+ rSessionInfo.m_vecActiveThreadId.push_back(threadIndexID);
// Form MI "=thread-created,id=\"%d\",group-id=\"i1\""
- const CMIUtilString strValue(CMIUtilString::Format("%d", thread.GetIndexID()));
+ const CMIUtilString strValue(CMIUtilString::Format("%d", threadIndexID));
const CMICmnMIValueConst miValueConst(strValue);
const CMICmnMIValueResult miValueResult("id", miValueConst);
CMICmnMIOutOfBandRecord miOutOfBand(CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated, miValueResult);
const CMICmnMIValueConst miValueConst2("i1");
const CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
- bOk = miOutOfBand.Add(miValueResult2);
+ bool bOk = miOutOfBand.Add(miValueResult2);
bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBand);
if (!bOk)
return MIstatus::failure;
@@ -1506,13 +1696,13 @@ CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges(void)
lldb::SBThread currentThread = sbProcess.GetSelectedThread();
if (currentThread.IsValid())
{
- const MIuint threadId = currentThread.GetIndexID();
- if (CMICmnLLDBDebugSessionInfo::Instance().m_currentSelectedThread != threadId)
+ const MIuint currentThreadIndexID = currentThread.GetIndexID();
+ if (rSessionInfo.m_currentSelectedThread != currentThreadIndexID)
{
- CMICmnLLDBDebugSessionInfo::Instance().m_currentSelectedThread = threadId;
+ rSessionInfo.m_currentSelectedThread = currentThreadIndexID;
// Form MI "=thread-selected,id=\"%d\""
- const CMIUtilString strValue(CMIUtilString::Format("%d", currentThread.GetIndexID()));
+ const CMIUtilString strValue(CMIUtilString::Format("%d", currentThreadIndexID));
const CMICmnMIValueConst miValueConst(strValue);
const CMICmnMIValueResult miValueResult("id", miValueConst);
CMICmnMIOutOfBandRecord miOutOfBand(CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, miValueResult);
@@ -1522,31 +1712,34 @@ CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges(void)
}
// Check for invalid (removed) threads
- CMICmnLLDBDebugSessionInfo::VecActiveThreadId_t::const_iterator it = CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.begin();
- while (it != CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.end())
+ CMICmnLLDBDebugSessionInfo::VecActiveThreadId_t::iterator it = rSessionInfo.m_vecActiveThreadId.begin();
+ while (it != rSessionInfo.m_vecActiveThreadId.end())
{
- const MIuint nThreadId = *it;
- lldb::SBThread thread = sbProcess.GetThreadAtIndex(nThreadId);
+ const MIuint threadIndexID = *it;
+ lldb::SBThread thread = sbProcess.GetThreadByIndexID(threadIndexID);
if (!thread.IsValid())
{
// Form MI "=thread-exited,id=\"%ld\",group-id=\"i1\""
- const CMIUtilString strValue(CMIUtilString::Format("%ld", thread.GetIndexID()));
+ const CMIUtilString strValue(CMIUtilString::Format("%ld", threadIndexID));
const CMICmnMIValueConst miValueConst(strValue);
const CMICmnMIValueResult miValueResult("id", miValueConst);
CMICmnMIOutOfBandRecord miOutOfBand(CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult);
const CMICmnMIValueConst miValueConst2("i1");
const CMICmnMIValueResult miValueResult2("group-id", miValueConst2);
- bOk = miOutOfBand.Add(miValueResult2);
+ bool bOk = miOutOfBand.Add(miValueResult2);
bOk = bOk && MiOutOfBandRecordToStdout(miOutOfBand);
if (!bOk)
return MIstatus::failure;
- }
- // Next
- ++it;
+ // Remove current thread from cache and get next
+ it = rSessionInfo.m_vecActiveThreadId.erase(it);
+ }
+ else
+ // Next
+ ++it;
}
- return TextToStdout("(gdb)");
+ return CMICmnStreamStdout::WritePrompt();
}
//++ ------------------------------------------------------------------------------------
@@ -1608,3 +1801,29 @@ CMICmnLLDBDebuggerHandleEvents::TextToStderr(const CMIUtilString &vrTxt)
{
return CMICmnStreamStderr::TextToStderr(vrTxt);
}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Initialize the member variables with the signal values in this process
+// file.
+// Type: Method.
+// Args: None
+// Return: Noen
+// Throws: None.
+//--
+void
+CMICmnLLDBDebuggerHandleEvents::InitializeSignals()
+{
+ if (!m_bSignalsInitialized)
+ {
+ lldb::SBProcess sbProcess = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
+ if (sbProcess.IsValid())
+ {
+ lldb::SBUnixSignals unix_signals = sbProcess.GetUnixSignals();
+ m_SIGINT = unix_signals.GetSignalNumberFromName("SIGINT");
+ m_SIGSTOP = unix_signals.GetSignalNumberFromName("SIGSTOP");
+ m_SIGSEGV = unix_signals.GetSignalNumberFromName("SIGSEGV");
+ m_SIGTRAP = unix_signals.GetSignalNumberFromName("SIGTRAP");
+ m_bSignalsInitialized = true;
+ }
+ }
+}
diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h
index 65b397c13fd9..9b7b5d6f7b03 100644
--- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h
+++ b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.h
@@ -7,22 +7,11 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBDebuggerHandleEvents.h
-//
-// Overview: CMICmnLLDBDebuggerHandleEvents interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
#include "MICmnBase.h"
+#include "MICmnMIValueList.h"
#include "MICmnMIValueTuple.h"
#include "MIUtilSingletonBase.h"
@@ -50,7 +39,7 @@ class CMICmnLLDBDebuggerHandleEvents : public CMICmnBase, public MI::ISingleton<
bool Initialize(void);
bool Shutdown(void);
//
- bool HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent, bool &vrbExitAppEvent);
+ bool HandleEvent(const lldb::SBEvent &vEvent, bool &vrbHandledEvent);
// Methods:
private:
@@ -65,19 +54,25 @@ class CMICmnLLDBDebuggerHandleEvents : public CMICmnBase, public MI::ISingleton<
bool HandleEventSBBreakpointCmn(const lldb::SBEvent &vEvent);
bool HandleEventSBBreakpointAdded(const lldb::SBEvent &vEvent);
bool HandleEventSBBreakpointLocationsAdded(const lldb::SBEvent &vEvent);
- bool HandleEventSBProcess(const lldb::SBEvent &vEvent, bool &vrbExitAppEvent);
+ bool HandleEventSBProcess(const lldb::SBEvent &vEvent);
+ bool HandleEventSBTarget(const lldb::SBEvent &vEvent);
bool HandleEventSBThread(const lldb::SBEvent &vEvent);
bool HandleEventSBThreadBitStackChanged(const lldb::SBEvent &vEvent);
bool HandleEventSBThreadSuspended(const lldb::SBEvent &vEvent);
bool HandleEventSBCommandInterpreter(const lldb::SBEvent &vEvent);
- bool HandleProcessEventBroadcastBitStateChanged(const lldb::SBEvent &vEvent, bool &vrbExitAppEvent);
+ bool HandleProcessEventBroadcastBitStateChanged(const lldb::SBEvent &vEvent);
bool HandleProcessEventStateRunning(void);
bool HandleProcessEventStateExited(void);
- bool HandleProcessEventStateStopped(bool &vwrbShouldBrk);
+ bool HandleProcessEventStateStopped(const lldb::SBEvent &vrEvent, bool &vwrbShouldBrk);
bool HandleProcessEventStopReasonTrace(void);
bool HandleProcessEventStopReasonBreakpoint(void);
- bool HandleProcessEventStopSignal(bool &vwrbShouldBrk);
+ bool HandleProcessEventStopSignal(const lldb::SBEvent &vrEvent);
+ bool HandleProcessEventStopException(void);
bool HandleProcessEventStateSuspended(const lldb::SBEvent &vEvent);
+ bool HandleTargetEventBroadcastBitModulesLoaded(const lldb::SBEvent &vEvent);
+ bool HandleTargetEventBroadcastBitModulesUnloaded(const lldb::SBEvent &vEvent);
+ bool MiHelpGetModuleInfo(const lldb::SBModule &vModule, const bool vbWithExtraFields,
+ CMICmnMIOutOfBandRecord &vwrMiOutOfBandRecord);
bool MiHelpGetCurrentThreadFrame(CMICmnMIValueTuple &vwrMiValueTuple);
bool MiResultRecordToStdout(const CMICmnMIResultRecord &vrMiResultRecord);
bool MiOutOfBandRecordToStdout(const CMICmnMIOutOfBandRecord &vrMiResultRecord);
@@ -85,10 +80,15 @@ class CMICmnLLDBDebuggerHandleEvents : public CMICmnBase, public MI::ISingleton<
bool TextToStdout(const CMIUtilString &vrTxt);
bool TextToStderr(const CMIUtilString &vrTxt);
bool UpdateSelectedThread(void);
- bool ConvertPrintfCtrlCodeToString(const MIchar vCtrl, CMIUtilString &vwrStrEquivalent);
// Overridden:
private:
// From CMICmnBase
/* dtor */ virtual ~CMICmnLLDBDebuggerHandleEvents(void);
+ void InitializeSignals();
+ bool m_bSignalsInitialized;
+ MIuint64 m_SIGINT;
+ MIuint64 m_SIGSTOP;
+ MIuint64 m_SIGSEGV;
+ MIuint64 m_SIGTRAP;
};
diff --git a/tools/lldb-mi/MICmnLLDBProxySBValue.cpp b/tools/lldb-mi/MICmnLLDBProxySBValue.cpp
index 6a07f207840e..b60ce1aa4c4f 100644
--- a/tools/lldb-mi/MICmnLLDBProxySBValue.cpp
+++ b/tools/lldb-mi/MICmnLLDBProxySBValue.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBProxySBValue.cpp
-//
-// Overview: CMICmnLLDBProxySBValue implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#include <stdlib.h>
// Third Party Headers:
@@ -115,11 +103,11 @@ bool
CMICmnLLDBProxySBValue::GetCString(const lldb::SBValue &vrValue, CMIUtilString &vwCString)
{
lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
- const MIchar *pCType = rValue.GetTypeName();
+ const char *pCType = rValue.GetTypeName();
if (pCType == nullptr)
return MIstatus::failure;
- const MIchar *pType = "unsigned char *";
+ const char *pType = "unsigned char *";
if (!CMIUtilString::Compare(pCType, pType))
return MIstatus::failure;
@@ -132,7 +120,7 @@ CMICmnLLDBProxySBValue::GetCString(const lldb::SBValue &vrValue, CMIUtilString &
lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
MIuint nBufferSize = 64;
bool bNeedResize = false;
- MIchar *pBuffer = static_cast<MIchar *>(::malloc(nBufferSize));
+ char *pBuffer = static_cast<char *>(::malloc(nBufferSize));
do
{
lldb::SBError error;
@@ -141,7 +129,7 @@ CMICmnLLDBProxySBValue::GetCString(const lldb::SBValue &vrValue, CMIUtilString &
{
bNeedResize = true;
nBufferSize = nBufferSize << 1;
- pBuffer = static_cast<MIchar *>(::realloc(pBuffer, nBufferSize));
+ pBuffer = static_cast<char *>(::realloc(pBuffer, nBufferSize));
}
else
bNeedResize = false;
diff --git a/tools/lldb-mi/MICmnLLDBProxySBValue.h b/tools/lldb-mi/MICmnLLDBProxySBValue.h
index 39befe9566f3..a4ff0b72b236 100644
--- a/tools/lldb-mi/MICmnLLDBProxySBValue.h
+++ b/tools/lldb-mi/MICmnLLDBProxySBValue.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBProxySBValue.h
-//
-// Overview: CMICmnLLDBProxySBValue interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third Party Headers:
diff --git a/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp b/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
index 66a4efd5a96e..7ccb35e45449 100644
--- a/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
+++ b/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
@@ -7,22 +7,15 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBUtilSBValue.cpp
-//
-// Overview: CMICmnLLDBUtilSBValue implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
+// Third party headers:
+#include <cinttypes>
// In-house headers:
#include "MICmnLLDBUtilSBValue.h"
-#include "MIUtilString.h"
#include "MICmnLLDBDebugSessionInfo.h"
+#include "MICmnMIValueConst.h"
+#include "MICmnMIValueTuple.h"
+#include "MIUtilString.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBUtilSBValue constructor.
@@ -33,10 +26,13 @@
// Return: None.
// Throws: None.
//--
-CMICmnLLDBUtilSBValue::CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue, const bool vbHandleCharType /* = false */)
+CMICmnLLDBUtilSBValue::CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue, const bool vbHandleCharType /* = false */,
+ const bool vbHandleArrayType /* = true */)
: m_rValue(const_cast<lldb::SBValue &>(vrValue))
, m_pUnkwn("??")
+ , m_pComposite("{...}")
, m_bHandleCharType(vbHandleCharType)
+ , m_bHandleArrayType(vbHandleArrayType)
{
m_bValidSBValue = m_rValue.IsValid();
}
@@ -63,7 +59,7 @@ CMICmnLLDBUtilSBValue::~CMICmnLLDBUtilSBValue(void)
CMIUtilString
CMICmnLLDBUtilSBValue::GetName(void) const
{
- const MIchar *pName = m_bValidSBValue ? m_rValue.GetName() : nullptr;
+ const char *pName = m_bValidSBValue ? m_rValue.GetName() : nullptr;
const CMIUtilString text((pName != nullptr) ? pName : m_pUnkwn);
return text;
@@ -79,47 +75,286 @@ CMICmnLLDBUtilSBValue::GetName(void) const
// Throws: None.
//--
CMIUtilString
-CMICmnLLDBUtilSBValue::GetValue(void) const
+CMICmnLLDBUtilSBValue::GetValue(const bool vbExpandAggregates /* = false */) const
{
- CMIUtilString text;
+ if (!m_bValidSBValue)
+ return m_pUnkwn;
- if (m_bHandleCharType && IsCharType())
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ bool bPrintExpandAggregates = false;
+ bPrintExpandAggregates = rSessionInfo.SharedDataRetrieve<bool>(rSessionInfo.m_constStrPrintExpandAggregates,
+ bPrintExpandAggregates) && bPrintExpandAggregates;
+
+ const bool bHandleArrayTypeAsSimple = m_bHandleArrayType && !vbExpandAggregates && !bPrintExpandAggregates;
+ CMIUtilString value;
+ const bool bIsSimpleValue = GetSimpleValue(bHandleArrayTypeAsSimple, value);
+ if (bIsSimpleValue)
+ return value;
+
+ if (!vbExpandAggregates && !bPrintExpandAggregates)
+ return m_pComposite;
+
+ bool bPrintAggregateFieldNames = false;
+ bPrintAggregateFieldNames = !rSessionInfo.SharedDataRetrieve<bool>(rSessionInfo.m_constStrPrintAggregateFieldNames,
+ bPrintAggregateFieldNames) || bPrintAggregateFieldNames;
+
+ CMICmnMIValueTuple miValueTuple;
+ const bool bOk = GetCompositeValue(bPrintAggregateFieldNames, miValueTuple);
+ if (!bOk)
+ return m_pUnkwn;
+
+ value = miValueTuple.GetString();
+ return value;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve from the LLDB SB Value object the value of the variable described in
+// text if it has a simple format (not composite).
+// Type: Method.
+// Args: vwrValue - (W) The SBValue in a string format.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmnLLDBUtilSBValue::GetSimpleValue(const bool vbHandleArrayType, CMIUtilString &vwrValue) const
+{
+ const MIuint nChildren = m_rValue.GetNumChildren();
+ if (nChildren == 0)
{
- const lldb::addr_t addr = m_rValue.GetLoadAddress();
- text = CMIUtilString::Format("0x%08x", addr);
- const CMIUtilString cString(GetValueCString());
- if (!cString.empty())
- text += CMIUtilString::Format(" %s", cString.c_str());
+ if (m_bHandleCharType && IsCharType())
+ {
+ vwrValue = GetSimpleValueChar();
+ return MIstatus::success;
+ }
+ else
+ {
+ const char *pValue = m_rValue.GetValue();
+ vwrValue = pValue != nullptr ? pValue : m_pUnkwn;
+ return MIstatus::success;
+ }
}
- else
+ else if (IsPointerType())
{
- const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr;
- text = (pValue != nullptr) ? pValue : m_pUnkwn;
+ if (m_bHandleCharType && IsFirstChildCharType())
+ {
+ vwrValue = GetSimpleValueCStringPointer();
+ return MIstatus::success;
+ }
+ else
+ {
+ const char *pValue = m_rValue.GetValue();
+ vwrValue = pValue != nullptr ? pValue : m_pUnkwn;
+ return MIstatus::success;
+ }
+ }
+ else if (IsArrayType())
+ {
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ bool bPrintCharArrayAsString = false;
+ bPrintCharArrayAsString = rSessionInfo.SharedDataRetrieve<bool>(rSessionInfo.m_constStrPrintCharArrayAsString,
+ bPrintCharArrayAsString) && bPrintCharArrayAsString;
+ if (bPrintCharArrayAsString && m_bHandleCharType && IsFirstChildCharType())
+ {
+ vwrValue = GetSimpleValueCStringArray();
+ return MIstatus::success;
+ }
+ else if (vbHandleArrayType)
+ {
+ vwrValue = CMIUtilString::Format("[%u]", nChildren);
+ return MIstatus::success;
+ }
}
- return text;
+ // Composite variable type i.e. struct
+ return MIstatus::failure;
}
//++ ------------------------------------------------------------------------------------
-// Details: If the LLDB SB Value object is a char type then form the text data string
-// otherwise return nothing. m_bHandleCharType must be true to return text data
-// if any.
+// Details: Retrieve from the LLDB SB Value object the char value of the variable.
// Type: Method.
// Args: None.
-// Return: CMIUtilString - Text description of the variable's value.
+// Return: CMIUtilString - The char value of the variable.
// Throws: None.
//--
CMIUtilString
-CMICmnLLDBUtilSBValue::GetValueCString(void) const
+CMICmnLLDBUtilSBValue::GetSimpleValueChar(void) const
{
- CMIUtilString text;
+ const uint64_t value = m_rValue.GetValueAsUnsigned();
+ if (value == 0)
+ {
+ const uint64_t nFailValue = 1;
+ if (nFailValue == m_rValue.GetValueAsUnsigned(nFailValue))
+ return m_pUnkwn;
+ }
- if (m_bHandleCharType && IsCharType())
+ const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
+ switch (eType)
{
- text = ReadCStringFromHostMemory(m_rValue);
+ default:
+ assert(0 && "value must be a char type");
+ case lldb::eBasicTypeChar:
+ case lldb::eBasicTypeSignedChar:
+ case lldb::eBasicTypeUnsignedChar:
+ {
+ const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char)value));
+ return CMIUtilString::Format("%" PRIu8 " '%s'", (uint8_t)value, prefix.c_str());
+ }
+ case lldb::eBasicTypeChar16:
+ {
+ const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char16_t)value));
+ return CMIUtilString::Format("U+%04" PRIx16 " u'%s'", (uint16_t)value, prefix.c_str());
+ }
+ case lldb::eBasicTypeChar32:
+ {
+ const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char32_t)value));
+ return CMIUtilString::Format("U+%08" PRIx32 " U'%s'", (uint32_t)value, prefix.c_str());
+ }
}
+}
- return text;
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve from the LLDB SB Value object of type char* the c-string value.
+// Type: Method.
+// Args: None.
+// Return: CMIUtilString - The c-string value of the variable.
+// Throws: None.
+//--
+CMIUtilString
+CMICmnLLDBUtilSBValue::GetSimpleValueCStringPointer(void) const
+{
+ const char *value = m_rValue.GetValue();
+ if (value == nullptr)
+ return m_pUnkwn;
+
+ lldb::SBValue child = m_rValue.GetChildAtIndex(0);
+ const lldb::BasicType eType = child.GetType().GetBasicType();
+ switch (eType)
+ {
+ default:
+ assert(0 && "child must be a char type");
+ case lldb::eBasicTypeChar:
+ case lldb::eBasicTypeSignedChar:
+ case lldb::eBasicTypeUnsignedChar:
+ {
+ // FIXME Add slashes before double quotes
+ const CMIUtilString prefix(ReadCStringFromHostMemory<char>(child).AddSlashes());
+ // Note code that has const in will not show the text suffix to the string pointer
+ // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this
+ // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this
+ return CMIUtilString::Format("%s \"%s\"", value, prefix.c_str());
+ }
+ case lldb::eBasicTypeChar16:
+ {
+ // FIXME Add slashes before double quotes
+ const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(child).AddSlashes());
+ return CMIUtilString::Format("%s u\"%s\"", value, prefix.c_str());
+ }
+ case lldb::eBasicTypeChar32:
+ {
+ // FIXME Add slashes before double quotes
+ const CMIUtilString prefix(ReadCStringFromHostMemory<char32_t>(child).AddSlashes());
+ return CMIUtilString::Format("%s U\"%s\"", value, prefix.c_str());
+ }
+ }
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve from the LLDB SB Value object of type char[] the c-string value.
+// Type: Method.
+// Args: None.
+// Return: CMIUtilString - The c-string value of the variable.
+// Throws: None.
+//--
+CMIUtilString
+CMICmnLLDBUtilSBValue::GetSimpleValueCStringArray(void) const
+{
+ const MIuint nChildren = m_rValue.GetNumChildren();
+ lldb::SBValue child = m_rValue.GetChildAtIndex(0);
+ const lldb::BasicType eType = child.GetType().GetBasicType();
+ switch (eType)
+ {
+ default:
+ assert(0 && "value must be a char[] type");
+ case lldb::eBasicTypeChar:
+ case lldb::eBasicTypeSignedChar:
+ case lldb::eBasicTypeUnsignedChar:
+ {
+ // FIXME Add slashes before double quotes
+ const CMIUtilString prefix(ReadCStringFromHostMemory<char>(m_rValue, nChildren).AddSlashes());
+ // TODO: to match char* it should be the following
+ // return CMIUtilString::Format("[%u] \"%s\"", nChildren, prefix.c_str());
+ return CMIUtilString::Format("\"%s\"", prefix.c_str());
+ }
+ case lldb::eBasicTypeChar16:
+ {
+ // FIXME Add slashes before double quotes
+ const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(m_rValue, nChildren).AddSlashes());
+ return CMIUtilString::Format("u\"%s\"", prefix.c_str());
+ }
+ case lldb::eBasicTypeChar32:
+ {
+ // FIXME Add slashes before double quotes
+ const CMIUtilString prefix(ReadCStringFromHostMemory<char32_t>(m_rValue, nChildren).AddSlashes());
+ return CMIUtilString::Format("U\"%s\"", prefix.c_str());
+ }
+ }
+}
+
+bool
+CMICmnLLDBUtilSBValue::GetCompositeValue(const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple,
+ const MIuint vnDepth /* = 1 */) const
+{
+ const MIuint nMaxDepth = 10;
+ const MIuint nChildren = m_rValue.GetNumChildren();
+ for (MIuint i = 0; i < nChildren; ++i)
+ {
+ const lldb::SBValue member = m_rValue.GetChildAtIndex(i);
+ const CMICmnLLDBUtilSBValue utilMember(member, m_bHandleCharType, m_bHandleArrayType);
+ const bool bHandleArrayTypeAsSimple = false;
+ CMIUtilString value;
+ const bool bIsSimpleValue = utilMember.GetSimpleValue(bHandleArrayTypeAsSimple, value);
+ if (bIsSimpleValue)
+ {
+ // OK. Value is simple (not composite) and was successfully got
+ }
+ else if (vnDepth < nMaxDepth)
+ {
+ // Need to get value from composite type
+ CMICmnMIValueTuple miValueTuple;
+ const bool bOk = utilMember.GetCompositeValue(vbPrintFieldNames, miValueTuple, vnDepth + 1);
+ if (!bOk)
+ // Can't obtain composite type
+ value = m_pUnkwn;
+ else
+ // OK. Value is composite and was successfully got
+ value = miValueTuple.GetString();
+ }
+ else
+ {
+ // Need to get value from composite type, but vnMaxDepth is reached
+ value = m_pComposite;
+ }
+ const bool bNoQuotes = true;
+ const CMICmnMIValueConst miValueConst(value, bNoQuotes);
+ if (vbPrintFieldNames)
+ {
+ const bool bUseSpacing = true;
+ const CMICmnMIValueResult miValueResult(utilMember.GetName(), miValueConst, bUseSpacing);
+ const bool bOk = vwrMiValueTuple.Add(miValueResult, bUseSpacing);
+ if (!bOk)
+ return MIstatus::failure;
+ }
+ else
+ {
+ const bool bUseSpacing = false;
+ const bool bOk = vwrMiValueTuple.Add(miValueConst, bUseSpacing);
+ if (!bOk)
+ return MIstatus::failure;
+ }
+ }
+
+ return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
@@ -133,15 +368,23 @@ CMICmnLLDBUtilSBValue::GetValueCString(void) const
bool
CMICmnLLDBUtilSBValue::IsCharType(void) const
{
- const MIchar *pName = m_rValue.GetName();
- MIunused(pName);
const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
- return ((eType == lldb::eBasicTypeChar) || (eType == lldb::eBasicTypeSignedChar) || (eType == lldb::eBasicTypeUnsignedChar));
+ switch (eType)
+ {
+ case lldb::eBasicTypeChar:
+ case lldb::eBasicTypeSignedChar:
+ case lldb::eBasicTypeUnsignedChar:
+ case lldb::eBasicTypeChar16:
+ case lldb::eBasicTypeChar32:
+ return true;
+ default:
+ return false;
+ }
}
//++ ------------------------------------------------------------------------------------
-// Details: Retrieve the flag stating whether any child value object of *this object is a
-// char type or some other type. Returns false if there are not children. Char
+// Details: Retrieve the flag stating whether first child value object of *this object is
+// a char type or some other type. Returns false if there are not children. Char
// type can be signed or unsigned.
// Type: Method.
// Args: None.
@@ -149,7 +392,7 @@ CMICmnLLDBUtilSBValue::IsCharType(void) const
// Throws: None.
//--
bool
-CMICmnLLDBUtilSBValue::IsChildCharType(void) const
+CMICmnLLDBUtilSBValue::IsFirstChildCharType(void) const
{
const MIuint nChildren = m_rValue.GetNumChildren();
@@ -157,74 +400,87 @@ CMICmnLLDBUtilSBValue::IsChildCharType(void) const
if (nChildren == 0)
return false;
- // Is it a composite type
- if (nChildren > 1)
- return false;
-
- lldb::SBValue member = m_rValue.GetChildAtIndex(0);
+ const lldb::SBValue member = m_rValue.GetChildAtIndex(0);
const CMICmnLLDBUtilSBValue utilValue(member);
return utilValue.IsCharType();
}
//++ ------------------------------------------------------------------------------------
-// Details: Retrieve the C string data for a child of char type (one and only child) for
-// the parent value object. If the child is not a char type or the parent has
-// more than one child then an empty string is returned. Char type can be
-// signed or unsigned.
+// Details: Retrieve the flag stating whether this value object is a integer type or some
+// other type. Char type can be signed or unsigned and short or long/very long.
// Type: Method.
// Args: None.
-// Return: CMIUtilString - Text description of the variable's value.
+// Return: bool - True = Yes is a integer type, false = some other type.
// Throws: None.
//--
-CMIUtilString
-CMICmnLLDBUtilSBValue::GetChildValueCString(void) const
+bool
+CMICmnLLDBUtilSBValue::IsIntegerType(void) const
{
- CMIUtilString text;
- const MIuint nChildren = m_rValue.GetNumChildren();
-
- // Is it a basic type
- if (nChildren == 0)
- return text;
-
- // Is it a composite type
- if (nChildren > 1)
- return text;
+ const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
+ return ((eType == lldb::eBasicTypeShort) || (eType == lldb::eBasicTypeUnsignedShort) ||
+ (eType == lldb::eBasicTypeInt) || (eType == lldb::eBasicTypeUnsignedInt) ||
+ (eType == lldb::eBasicTypeLong) || (eType == lldb::eBasicTypeUnsignedLong) ||
+ (eType == lldb::eBasicTypeLongLong) || (eType == lldb::eBasicTypeUnsignedLongLong) ||
+ (eType == lldb::eBasicTypeInt128) || (eType == lldb::eBasicTypeUnsignedInt128));
+}
- lldb::SBValue member = m_rValue.GetChildAtIndex(0);
- const CMICmnLLDBUtilSBValue utilValue(member);
- if (m_bHandleCharType && utilValue.IsCharType())
- {
- text = ReadCStringFromHostMemory(member);
- }
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the flag stating whether this value object is a pointer type or some
+// other type.
+// Type: Method.
+// Args: None.
+// Return: bool - True = Yes is a pointer type, false = some other type.
+// Throws: None.
+//--
+bool
+CMICmnLLDBUtilSBValue::IsPointerType(void) const
+{
+ return m_rValue.GetType().IsPointerType();
+}
- return text;
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve the flag stating whether this value object is an array type or some
+// other type.
+// Type: Method.
+// Args: None.
+// Return: bool - True = Yes is an array type, false = some other type.
+// Throws: None.
+//--
+bool
+CMICmnLLDBUtilSBValue::IsArrayType(void) const
+{
+ return m_rValue.GetType().IsArrayType();
}
//++ ------------------------------------------------------------------------------------
// Details: Retrieve the C string data of value object by read the memory where the
// variable is held.
// Type: Method.
-// Args: vrValueObj - (R) LLDB SBValue variable object.
+// Args: vrValue - (R) LLDB SBValue variable object.
// Return: CMIUtilString - Text description of the variable's value.
// Throws: None.
//--
+template <typename charT>
CMIUtilString
-CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(const lldb::SBValue &vrValueObj) const
+CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(lldb::SBValue &vrValue, const MIuint vnMaxLen) const
{
- CMIUtilString text;
-
- lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValueObj);
- const lldb::addr_t addr = rValue.GetLoadAddress();
- CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
- const MIuint nBytes(128);
- const MIchar *pBufferMemory = new MIchar[nBytes];
+ std::string result;
+ lldb::addr_t addr = vrValue.GetLoadAddress(), end_addr = addr + vnMaxLen * sizeof(charT);
+ lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
lldb::SBError error;
- const MIuint64 nReadBytes = rSessionInfo.GetProcess().ReadMemory(addr, (void *)pBufferMemory, nBytes, error);
- MIunused(nReadBytes);
- text = CMIUtilString::Format("\\\"%s\\\"", pBufferMemory);
- delete[] pBufferMemory;
+ while (addr < end_addr)
+ {
+ charT ch;
+ const MIuint64 nReadBytes = process.ReadMemory(addr, &ch, sizeof(ch), error);
+ if (error.Fail() || nReadBytes != sizeof(ch))
+ return m_pUnkwn;
+ else if (ch == 0)
+ break;
+ result.append(CMIUtilString::ConvertToPrintableASCII(ch));
+ addr += sizeof(ch);
+ }
- return text;
+ return result.c_str();
}
//++ ------------------------------------------------------------------------------------
@@ -265,7 +521,7 @@ CMICmnLLDBUtilSBValue::IsValueUnknown(void) const
CMIUtilString
CMICmnLLDBUtilSBValue::GetTypeName(void) const
{
- const MIchar *pName = m_bValidSBValue ? m_rValue.GetTypeName() : nullptr;
+ const char *pName = m_bValidSBValue ? m_rValue.GetTypeName() : nullptr;
const CMIUtilString text((pName != nullptr) ? pName : m_pUnkwn);
return text;
@@ -281,7 +537,7 @@ CMICmnLLDBUtilSBValue::GetTypeName(void) const
CMIUtilString
CMICmnLLDBUtilSBValue::GetTypeNameDisplay(void) const
{
- const MIchar *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
+ const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
const CMIUtilString text((pName != nullptr) ? pName : m_pUnkwn);
return text;
@@ -313,7 +569,7 @@ CMICmnLLDBUtilSBValue::HasName(void) const
{
bool bHasAName = false;
- const MIchar *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
+ const char *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr;
if (pName != nullptr)
{
bHasAName = (CMIUtilString(pName).length() > 0);
diff --git a/tools/lldb-mi/MICmnLLDBUtilSBValue.h b/tools/lldb-mi/MICmnLLDBUtilSBValue.h
index a3f2c9c0ffc9..468170b6a731 100644
--- a/tools/lldb-mi/MICmnLLDBUtilSBValue.h
+++ b/tools/lldb-mi/MICmnLLDBUtilSBValue.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLLDBUtilSBValue.h
-//
-// Overview: CMICmnLLDBUtilSBValue interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third Party Headers:
@@ -26,6 +14,7 @@
// In-house headers:
#include "MIDataTypes.h"
+#include "MICmnMIValueTuple.h"
// Declerations:
class CMIUtilString;
@@ -41,17 +30,19 @@ class CMICmnLLDBUtilSBValue
{
// Methods:
public:
- /* ctor */ CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue, const bool vbHandleCharType = false);
+ /* ctor */ CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue, const bool vbHandleCharType = false,
+ const bool vbHandleArrayType = true);
/* dtor */ ~CMICmnLLDBUtilSBValue(void);
//
CMIUtilString GetName(void) const;
- CMIUtilString GetValue(void) const;
- CMIUtilString GetValueCString(void) const;
- CMIUtilString GetChildValueCString(void) const;
+ CMIUtilString GetValue(const bool vbExpandAggregates = false) const;
CMIUtilString GetTypeName(void) const;
CMIUtilString GetTypeNameDisplay(void) const;
bool IsCharType(void) const;
- bool IsChildCharType(void) const;
+ bool IsFirstChildCharType(void) const;
+ bool IsIntegerType(void) const;
+ bool IsPointerType(void) const;
+ bool IsArrayType(void) const;
bool IsLLDBVariable(void) const;
bool IsNameUnknown(void) const;
bool IsValueUnknown(void) const;
@@ -60,12 +51,19 @@ class CMICmnLLDBUtilSBValue
// Methods:
private:
- CMIUtilString ReadCStringFromHostMemory(const lldb::SBValue &vrValueObj) const;
+ template <typename charT> CMIUtilString ReadCStringFromHostMemory(lldb::SBValue &vrValue, const MIuint vnMaxLen = UINT32_MAX) const;
+ bool GetSimpleValue(const bool vbHandleArrayType, CMIUtilString &vrValue) const;
+ CMIUtilString GetSimpleValueChar(void) const;
+ CMIUtilString GetSimpleValueCStringPointer(void) const;
+ CMIUtilString GetSimpleValueCStringArray(void) const;
+ bool GetCompositeValue(const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple, const MIuint vnDepth = 1) const;
// Attributes:
private:
lldb::SBValue &m_rValue;
- const MIchar *m_pUnkwn;
- bool m_bValidSBValue; // True = SBValue is a valid object, false = not valid.
- bool m_bHandleCharType; // True = Yes return text molding to char type, false = just return data.
+ const char *m_pUnkwn;
+ const char *m_pComposite;
+ bool m_bValidSBValue; // True = SBValue is a valid object, false = not valid.
+ bool m_bHandleCharType; // True = Yes return text molding to char type, false = just return data.
+ bool m_bHandleArrayType; // True = Yes return special stub for array type, false = just return data.
};
diff --git a/tools/lldb-mi/MICmnLog.cpp b/tools/lldb-mi/MICmnLog.cpp
index dc7a93d29776..a88ba6b5782a 100644
--- a/tools/lldb-mi/MICmnLog.cpp
+++ b/tools/lldb-mi/MICmnLog.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLog.cpp
-//
-// Overview: CMICmnLog implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnLog.h"
#include "MICmnLogMediumFile.h"
diff --git a/tools/lldb-mi/MICmnLog.h b/tools/lldb-mi/MICmnLog.h
index 6884b614896d..30505359d749 100644
--- a/tools/lldb-mi/MICmnLog.h
+++ b/tools/lldb-mi/MICmnLog.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLog.h
-//
-// Overview: CMICmnLog interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
diff --git a/tools/lldb-mi/MICmnLogMediumFile.cpp b/tools/lldb-mi/MICmnLogMediumFile.cpp
index add4426b9352..4080bc5cf29d 100644
--- a/tools/lldb-mi/MICmnLogMediumFile.cpp
+++ b/tools/lldb-mi/MICmnLogMediumFile.cpp
@@ -7,24 +7,12 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLogMediumFile.cpp
-//
-// Overview: CMICmnLogMediumFile implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnLogMediumFile.h"
#include "MICmnResources.h"
#if defined(_MSC_VER)
#include "MIUtilSystemWindows.h"
-#elif defined(__FreeBSD__) || defined(__linux__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__linux__)
#include "MIUtilSystemLinux.h"
#elif defined(__APPLE__)
#include "MIUtilSystemOsx.h"
@@ -39,7 +27,9 @@
//--
CMICmnLogMediumFile::CMICmnLogMediumFile(void)
: m_constThisMediumName(MIRSRC(IDS_MEDIUMFILE_NAME))
- , m_constMediumFileName("lldb-mi-log.txt")
+ , m_constMediumFileNameFormat("lldb-mi-%s.log")
+ , m_strMediumFileName(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH))
+ , m_strMediumFileDirectory(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH))
, m_fileNamePath(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH))
, m_eVerbosityType(CMICmnLog::eLogVerbosity_Log)
, m_strDate(CMIUtilDateTimeStd().GetDate())
@@ -84,7 +74,8 @@ CMICmnLogMediumFile::Instance(void)
bool
CMICmnLogMediumFile::Initialize(void)
{
- m_bInitialized = FileFormFileNamePath();
+ m_bInitialized = CMIUtilSystem().GetLogFilesPath(m_strMediumFileDirectory);
+ m_bInitialized &= FileFormFileNamePath();
return m_bInitialized;
}
@@ -225,21 +216,15 @@ CMICmnLogMediumFile::FileFormFileNamePath(void)
m_fileNamePath = MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH);
- CMIUtilString strPathName;
- if (CMIUtilSystem().GetLogFilesPath(strPathName))
+ if (m_strMediumFileDirectory.compare(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)) != 0)
{
- const CMIUtilString strPath = CMIUtilFileStd().StripOffFileName(strPathName);
-
-// ToDo: Review this LINUX log file quick fix so not hidden
-// AD:
-// Linux was creating a log file here called '.\log.txt'. The '.' on linux
-// signifies that this file is 'hidden' and not normally visible. A quick fix
-// is to remove the path component all together. Linux also normally uses '/'
-// as directory separators, again leading to the problem of the hidden log.
+ CMIUtilDateTimeStd date;
+ m_strMediumFileName = CMIUtilString::Format(m_constMediumFileNameFormat.c_str(), date.GetDateTimeLogFilename().c_str());
+
#if defined(_MSC_VER)
- m_fileNamePath = CMIUtilString::Format("%s\\%s", strPath.c_str(), m_constMediumFileName.c_str());
+ m_fileNamePath = CMIUtilString::Format("%s\\%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
#else
- m_fileNamePath = CMIUtilString::Format("%s", m_constMediumFileName.c_str());
+ m_fileNamePath = CMIUtilString::Format("%s/%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
#endif // defined ( _MSC_VER )
return MIstatus::success;
@@ -273,7 +258,7 @@ CMICmnLogMediumFile::GetFileNamePath(void) const
const CMIUtilString &
CMICmnLogMediumFile::GetFileName(void) const
{
- return m_constMediumFileName;
+ return m_strMediumFileName;
}
//++ ------------------------------------------------------------------------------------
@@ -291,15 +276,15 @@ CMICmnLogMediumFile::MassagedData(const CMIUtilString &vData, const CMICmnLog::E
{
const CMIUtilString strCr("\n");
CMIUtilString data;
- const MIchar verbosityCode(ConvertLogVerbosityTypeToId(veType));
+ const char verbosityCode(ConvertLogVerbosityTypeToId(veType));
const CMIUtilString dt(CMIUtilString::Format("%s %s", m_strDate.c_str(), m_dateTime.GetTime().c_str()));
data = CMIUtilString::Format("%c,%s,%s", verbosityCode, dt.c_str(), vData.c_str());
data = ConvertCr(data);
// Look for EOL...
- const MIint pos = vData.rfind(strCr);
- if (pos == (MIint)vData.size())
+ const size_t pos = vData.rfind(strCr);
+ if (pos == vData.size())
return data;
// ... did not have an EOL so add one
@@ -315,10 +300,10 @@ CMICmnLogMediumFile::MassagedData(const CMIUtilString &vData, const CMICmnLog::E
// Return: wchar_t - A letter.
// Throws: None.
//--
-MIchar
+char
CMICmnLogMediumFile::ConvertLogVerbosityTypeToId(const CMICmnLog::ELogVerbosity veType) const
{
- MIchar c = 0;
+ char c = 0;
if (veType != 0)
{
MIuint cnt = 0;
@@ -397,11 +382,11 @@ CMICmnLogMediumFile::ConvertCr(const CMIUtilString &vData) const
if (strCr == rCrCmpat)
return vData;
- const MIuint nSizeCmpat(rCrCmpat.size());
- const MIuint nSize(strCr.size());
+ const size_t nSizeCmpat(rCrCmpat.size());
+ const size_t nSize(strCr.size());
CMIUtilString strConv(vData);
- MIint pos = strConv.find(strCr);
- while (pos != (MIint)CMIUtilString::npos)
+ size_t pos = strConv.find(strCr);
+ while (pos != CMIUtilString::npos)
{
strConv.replace(pos, nSize, rCrCmpat);
pos = strConv.find(strCr, pos + nSizeCmpat);
@@ -438,3 +423,19 @@ CMICmnLogMediumFile::GetLineReturn(void) const
{
return m_file.GetLineReturn();
}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Set the diretory to place the log file.
+// Type: Method.
+// Args: vPath - (R) Path to log.
+// Return: MIstatus::success - Functional succeeded.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+bool
+CMICmnLogMediumFile::SetDirectory(const CMIUtilString &vPath)
+{
+ m_strMediumFileDirectory = vPath;
+
+ return FileFormFileNamePath();
+}
diff --git a/tools/lldb-mi/MICmnLogMediumFile.h b/tools/lldb-mi/MICmnLogMediumFile.h
index 8496320db678..53961d8f4f73 100644
--- a/tools/lldb-mi/MICmnLogMediumFile.h
+++ b/tools/lldb-mi/MICmnLogMediumFile.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnLogMediumFile.h
-//
-// Overview: CMICmnLogMediumFile interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
@@ -55,6 +43,7 @@ class CMICmnLogMediumFile : public CMICmnBase, public CMICmnLog::IMedium
bool IsOk(void) const;
bool IsFileExist(void) const;
const CMIUtilString &GetLineReturn(void) const;
+ bool SetDirectory(const CMIUtilString &vPath);
// Overridden:
public:
@@ -77,14 +66,16 @@ class CMICmnLogMediumFile : public CMICmnBase, public CMICmnLog::IMedium
bool FileFormFileNamePath(void);
CMIUtilString MassagedData(const CMIUtilString &vData, const CMICmnLog::ELogVerbosity veType);
bool FileWriteHeader(void);
- MIchar ConvertLogVerbosityTypeToId(const CMICmnLog::ELogVerbosity veType) const;
+ char ConvertLogVerbosityTypeToId(const CMICmnLog::ELogVerbosity veType) const;
CMIUtilString ConvertCr(const CMIUtilString &vData) const;
// Attributes:
private:
const CMIUtilString m_constThisMediumName;
- const CMIUtilString m_constMediumFileName;
+ const CMIUtilString m_constMediumFileNameFormat;
//
+ CMIUtilString m_strMediumFileName;
+ CMIUtilString m_strMediumFileDirectory;
CMIUtilString m_fileNamePath;
MIuint m_eVerbosityType;
CMIUtilString m_strDate;
diff --git a/tools/lldb-mi/MICmnMIOutOfBandRecord.cpp b/tools/lldb-mi/MICmnMIOutOfBandRecord.cpp
index 2977753038a6..84c6695de354 100644
--- a/tools/lldb-mi/MICmnMIOutOfBandRecord.cpp
+++ b/tools/lldb-mi/MICmnMIOutOfBandRecord.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIOutOfBandRecord.h
-//
-// Overview: CMICmnMIOutOfBandRecord implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnMIOutOfBandRecord.h"
#include "MICmnResources.h"
@@ -36,7 +24,10 @@ CMICmnMIOutOfBandRecord::MapOutOfBandToOutOfBandText_t ms_MapOutOfBandToOutOfBan
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, "thread-group-started"},
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated, "thread-created"},
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, "thread-exited"},
- {CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, "thread-selected"}};
+ {CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, "thread-selected"},
+ {CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleLoaded, "library-loaded"},
+ {CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleUnloaded, "library-unloaded"},
+ {CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, ""}};
CMICmnMIOutOfBandRecord::MapOutOfBandToOutOfBandText_t ms_constMapAsyncRecordTextToToken = {
{CMICmnMIOutOfBandRecord::eOutOfBand_Running, "*"},
{CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, "*"},
@@ -49,7 +40,10 @@ CMICmnMIOutOfBandRecord::MapOutOfBandToOutOfBandText_t ms_constMapAsyncRecordTex
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, "="},
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated, "="},
{CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, "="},
- {CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, "="}};
+ {CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, "="},
+ {CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleLoaded, "="},
+ {CMICmnMIOutOfBandRecord::eOutOfBand_TargetModuleUnloaded, "="},
+ {CMICmnMIOutOfBandRecord::eOutOfBand_TargetStreamOutput, "@"}};
//++ ------------------------------------------------------------------------------------
// Details: CMICmnMIOutOfBandRecord constructor.
@@ -81,14 +75,30 @@ CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord(const OutOfBand_e veType)
// Details: CMICmnMIOutOfBandRecord constructor.
// Type: Method.
// Args: veType - (R) A MI Out-of-Bound enumeration.
-// vMIResult - (R) A MI result object.
+// vConst - (R) A MI const object.
+// Return: None.
+// Throws: None.
+//--
+CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord(const OutOfBand_e veType, const CMICmnMIValueConst &vConst)
+ : m_eResultAsyncRecordClass(veType)
+ , m_strAsyncRecord(MIRSRC(IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION))
+{
+ BuildAsyncRecord();
+ m_strAsyncRecord += vConst.GetString();
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: CMICmnMIOutOfBandRecord constructor.
+// Type: Method.
+// Args: veType - (R) A MI Out-of-Bound enumeration.
+// vResult - (R) A MI result object.
// Return: None.
// Throws: None.
//--
-CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord(const OutOfBand_e veType, const CMICmnMIValueResult &vValue)
+CMICmnMIOutOfBandRecord::CMICmnMIOutOfBandRecord(const OutOfBand_e veType, const CMICmnMIValueResult &vResult)
: m_eResultAsyncRecordClass(veType)
, m_strAsyncRecord(MIRSRC(IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION))
- , m_partResult(vValue)
+ , m_partResult(vResult)
{
BuildAsyncRecord();
Add(m_partResult);
@@ -133,7 +143,7 @@ CMICmnMIOutOfBandRecord::GetString(void) const
bool
CMICmnMIOutOfBandRecord::BuildAsyncRecord(void)
{
- const MIchar *pFormat = "%s%s";
+ const char *pFormat = "%s%s";
const CMIUtilString &rStrAsyncRecord(ms_MapOutOfBandToOutOfBandText[m_eResultAsyncRecordClass]);
const CMIUtilString &rStrToken(ms_constMapAsyncRecordTextToToken[m_eResultAsyncRecordClass]);
m_strAsyncRecord = CMIUtilString::Format(pFormat, rStrToken.c_str(), rStrAsyncRecord.c_str());
@@ -144,16 +154,16 @@ CMICmnMIOutOfBandRecord::BuildAsyncRecord(void)
//++ ------------------------------------------------------------------------------------
// Details: Add to *this Out-of-band record additional information.
// Type: Method.
-// Args: vMIValue - (R) A MI value derived object.
+// Args: vResult - (R) A MI result object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
bool
-CMICmnMIOutOfBandRecord::Add(const CMICmnMIValue &vMIValue)
+CMICmnMIOutOfBandRecord::Add(const CMICmnMIValueResult &vResult)
{
m_strAsyncRecord += ",";
- m_strAsyncRecord += vMIValue.GetString();
+ m_strAsyncRecord += vResult.GetString();
return MIstatus::success;
}
diff --git a/tools/lldb-mi/MICmnMIOutOfBandRecord.h b/tools/lldb-mi/MICmnMIOutOfBandRecord.h
index 179e37523524..60a67165a3ff 100644
--- a/tools/lldb-mi/MICmnMIOutOfBandRecord.h
+++ b/tools/lldb-mi/MICmnMIOutOfBandRecord.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIOutOfBandRecord.h
-//
-// Overview: CMICmnMIOutOfBandRecord interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
@@ -27,6 +15,7 @@
// In-house headers:
#include "MICmnBase.h"
#include "MIUtilString.h"
+#include "MICmnMIValueConst.h"
#include "MICmnMIValueResult.h"
//++ ============================================================================
@@ -73,6 +62,9 @@ class CMICmnMIOutOfBandRecord : public CMICmnBase
eOutOfBand_ThreadCreated,
eOutOfBand_ThreadExited,
eOutOfBand_ThreadSelected,
+ eOutOfBand_TargetModuleLoaded,
+ eOutOfBand_TargetModuleUnloaded,
+ eOutOfBand_TargetStreamOutput,
eOutOfBand_count // Always the last one
};
@@ -85,10 +77,11 @@ class CMICmnMIOutOfBandRecord : public CMICmnBase
public:
/* ctor */ CMICmnMIOutOfBandRecord(void);
/* ctor */ CMICmnMIOutOfBandRecord(const OutOfBand_e veType);
- /* ctor */ CMICmnMIOutOfBandRecord(const OutOfBand_e veType, const CMICmnMIValueResult &vValue);
+ /* ctor */ CMICmnMIOutOfBandRecord(const OutOfBand_e veType, const CMICmnMIValueConst &vConst);
+ /* ctor */ CMICmnMIOutOfBandRecord(const OutOfBand_e veType, const CMICmnMIValueResult &vResult);
//
const CMIUtilString &GetString(void) const;
- bool Add(const CMICmnMIValue &vMIValue);
+ bool Add(const CMICmnMIValueResult &vResult);
// Overridden:
public:
diff --git a/tools/lldb-mi/MICmnMIResultRecord.cpp b/tools/lldb-mi/MICmnMIResultRecord.cpp
index 21cf326aca5e..49a31c87519f 100644
--- a/tools/lldb-mi/MICmnMIResultRecord.cpp
+++ b/tools/lldb-mi/MICmnMIResultRecord.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIResultRecord.h
-//
-// Overview: CMICmnMIResultRecord implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnMIResultRecord.h"
#include "MICmnResources.h"
@@ -118,7 +106,7 @@ CMICmnMIResultRecord::GetString(void) const
bool
CMICmnMIResultRecord::BuildResultRecord(void)
{
- const MIchar *pFormat = "%s%s%s";
+ const char *pFormat = "%s%s%s";
const CMIUtilString &rStrResultRecord(ms_MapResultClassToResultClassText[m_eResultRecordResultClass]);
m_strResultRecord =
CMIUtilString::Format(pFormat, m_strResultRecordToken.c_str(), ms_constStrResultRecordHat.c_str(), rStrResultRecord.c_str());
diff --git a/tools/lldb-mi/MICmnMIResultRecord.h b/tools/lldb-mi/MICmnMIResultRecord.h
index 9d1f188c1eef..92666ab87733 100644
--- a/tools/lldb-mi/MICmnMIResultRecord.h
+++ b/tools/lldb-mi/MICmnMIResultRecord.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIResultRecord.h
-//
-// Overview: CMICmnMIResultRecord interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
diff --git a/tools/lldb-mi/MICmnMIValue.cpp b/tools/lldb-mi/MICmnMIValue.cpp
index 8c0440115bf3..2f7041427d2b 100644
--- a/tools/lldb-mi/MICmnMIValue.cpp
+++ b/tools/lldb-mi/MICmnMIValue.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIValue.h
-//
-// Overview: CMICmnMIValue implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnMIValue.h"
#include "MICmnResources.h"
diff --git a/tools/lldb-mi/MICmnMIValue.h b/tools/lldb-mi/MICmnMIValue.h
index 2b60168db524..d5de4275231b 100644
--- a/tools/lldb-mi/MICmnMIValue.h
+++ b/tools/lldb-mi/MICmnMIValue.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIValue.h
-//
-// Overview: CMICmnMIValue interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmnMIValueConst.cpp b/tools/lldb-mi/MICmnMIValueConst.cpp
index 7aa0f7903558..dd4b99344293 100644
--- a/tools/lldb-mi/MICmnMIValueConst.cpp
+++ b/tools/lldb-mi/MICmnMIValueConst.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIValueConst.h
-//
-// Overview: CMICmnMIValueConst implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnMIValueConst.h"
@@ -85,13 +73,13 @@ CMICmnMIValueConst::BuildConst(void)
}
else
{
- const MIchar *pFormat = "%s%s%s";
+ const char *pFormat = "%s%s%s";
m_strValue = CMIUtilString::Format(pFormat, ms_constStrDblQuote.c_str(), strValue.c_str(), ms_constStrDblQuote.c_str());
}
}
else
{
- const MIchar *pFormat = "%s%s";
+ const char *pFormat = "%s%s";
m_strValue = CMIUtilString::Format(pFormat, ms_constStrDblQuote.c_str(), ms_constStrDblQuote.c_str());
}
diff --git a/tools/lldb-mi/MICmnMIValueConst.h b/tools/lldb-mi/MICmnMIValueConst.h
index 72be01fa3db1..72b5f2455f42 100644
--- a/tools/lldb-mi/MICmnMIValueConst.h
+++ b/tools/lldb-mi/MICmnMIValueConst.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIValueConst.h
-//
-// Overview: CMICmnMIValueConst interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmnMIValueList.cpp b/tools/lldb-mi/MICmnMIValueList.cpp
index 2e6078cbea1f..68eceab09cd2 100644
--- a/tools/lldb-mi/MICmnMIValueList.cpp
+++ b/tools/lldb-mi/MICmnMIValueList.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIValueList.h
-//
-// Overview: CMICmnMIValueList implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnMIValueList.h"
#include "MICmnResources.h"
@@ -88,7 +76,7 @@ CMICmnMIValueList::~CMICmnMIValueList(void)
bool
CMICmnMIValueList::BuildList(void)
{
- const MIchar *pFormat = "[%s]";
+ const char *pFormat = "[%s]";
m_strValue = CMIUtilString::Format(pFormat, m_strValue.c_str());
return MIstatus::success;
@@ -148,7 +136,7 @@ CMICmnMIValueList::BuildList(const CMICmnMIValueResult &vResult)
}
const CMIUtilString data(ExtractContentNoBrackets());
- const MIchar *pFormat = "[%s,%s]";
+ const char *pFormat = "[%s,%s]";
m_strValue = CMIUtilString::Format(pFormat, data.c_str(), vResult.GetString().c_str());
return MIstatus::success;
@@ -175,9 +163,12 @@ CMICmnMIValueList::BuildList(const CMICmnMIValue &vValue)
return BuildList();
}
- const MIchar *pFormat = "[%s,%s]";
- m_strValue = m_strValue.FindAndReplace("[", "");
- m_strValue = m_strValue.FindAndReplace("]", "");
+ // Remove already present '[' and ']' from the start and end
+ m_strValue = m_strValue.Trim();
+ size_t len = m_strValue.size();
+ if ( (len > 1) && (m_strValue[0] == '[') && (m_strValue[len - 1] == ']') )
+ m_strValue = m_strValue.substr(1, len - 2);
+ const char *pFormat = "[%s,%s]";
m_strValue = CMIUtilString::Format(pFormat, m_strValue.c_str(), vValue.GetString().c_str());
return MIstatus::success;
diff --git a/tools/lldb-mi/MICmnMIValueList.h b/tools/lldb-mi/MICmnMIValueList.h
index e7811e7d7bab..85bc5d4fbc99 100644
--- a/tools/lldb-mi/MICmnMIValueList.h
+++ b/tools/lldb-mi/MICmnMIValueList.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIValueList.h
-//
-// Overview: CMICmnMIValueList interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmnMIValueResult.cpp b/tools/lldb-mi/MICmnMIValueResult.cpp
index 7735844b14de..55d93ce40ca7 100644
--- a/tools/lldb-mi/MICmnMIValueResult.cpp
+++ b/tools/lldb-mi/MICmnMIValueResult.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIResult.h
-//
-// Overview: CMICmnMIValueResult implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnMIValueResult.h"
#include "MICmnResources.h"
@@ -60,7 +48,7 @@ CMICmnMIValueResult::CMICmnMIValueResult(const CMIUtilString &vrVariable, const
// Type: Method.
// Args: vrVariable - (R) MI value's name.
// vrValue - (R) The MI value.
-// vbUseSpacing - (R) True = put space seperators into the string, false = no spaces used.
+// vbUseSpacing - (R) True = put space separators into the string, false = no spaces used.
// Return: None.
// Throws: None.
//--
@@ -95,7 +83,7 @@ CMICmnMIValueResult::~CMICmnMIValueResult(void)
bool
CMICmnMIValueResult::BuildResult(void)
{
- const MIchar *pFormat = m_bUseSpacing ? "%s %s %s" : "%s%s%s";
+ const char *pFormat = m_bUseSpacing ? "%s %s %s" : "%s%s%s";
m_strValue = CMIUtilString::Format(pFormat, m_strPartVariable.c_str(), ms_constStrEqual.c_str(), m_partMIValue.GetString().c_str());
return MIstatus::success;
@@ -113,7 +101,7 @@ CMICmnMIValueResult::BuildResult(void)
bool
CMICmnMIValueResult::BuildResult(const CMIUtilString &vVariable, const CMICmnMIValue &vValue)
{
- const MIchar *pFormat = m_bUseSpacing ? "%s, %s %s %s" : "%s,%s%s%s";
+ const char *pFormat = m_bUseSpacing ? "%s, %s %s %s" : "%s,%s%s%s";
m_strValue =
CMIUtilString::Format(pFormat, m_strValue.c_str(), vVariable.c_str(), ms_constStrEqual.c_str(), vValue.GetString().c_str());
diff --git a/tools/lldb-mi/MICmnMIValueResult.h b/tools/lldb-mi/MICmnMIValueResult.h
index ec73e713bc93..99051bfc3f26 100644
--- a/tools/lldb-mi/MICmnMIValueResult.h
+++ b/tools/lldb-mi/MICmnMIValueResult.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIResult.h
-//
-// Overview: CMICmnMIValueResult interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
@@ -71,5 +59,5 @@ class CMICmnMIValueResult : public CMICmnMIValue
CMIUtilString m_strPartVariable;
CMICmnMIValue m_partMIValue;
bool m_bEmptyConstruction; // True = *this object used constructor with no parameters, false = constructor with parameters
- bool m_bUseSpacing; // True = put space seperators into the string, false = no spaces used
+ bool m_bUseSpacing; // True = put space separators into the string, false = no spaces used
};
diff --git a/tools/lldb-mi/MICmnMIValueTuple.cpp b/tools/lldb-mi/MICmnMIValueTuple.cpp
index 61fad88b5517..aa92b1f62280 100644
--- a/tools/lldb-mi/MICmnMIValueTuple.cpp
+++ b/tools/lldb-mi/MICmnMIValueTuple.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIValueTuple.h
-//
-// Overview: CMICmnMIValueTuple implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnMIValueTuple.h"
@@ -54,7 +42,7 @@ CMICmnMIValueTuple::CMICmnMIValueTuple(const CMICmnMIValueResult &vResult)
// Details: CMICmnMIValueTuple constructor.
// Type: Method.
// Args: vResult - (R) MI result object.
-// vbUseSpacing - (R) True = put space seperators into the string, false = no spaces used.
+// vbUseSpacing - (R) True = put space separators into the string, false = no spaces used.
// Return: None.
// Throws: None.
//--
@@ -88,7 +76,7 @@ CMICmnMIValueTuple::~CMICmnMIValueTuple(void)
bool
CMICmnMIValueTuple::BuildTuple(void)
{
- const MIchar *pFormat = "{%s}";
+ const char *pFormat = "{%s}";
m_strValue = CMIUtilString::Format(pFormat, m_strValue.c_str());
return MIstatus::success;
@@ -122,7 +110,7 @@ CMICmnMIValueTuple::BuildTuple(const CMICmnMIValueResult &vResult)
m_strValue = m_strValue.substr(0, m_strValue.size() - 1);
}
- const MIchar *pFormat = m_bSpaceAfterComma ? "{%s, %s}" : "{%s,%s}";
+ const char *pFormat = m_bSpaceAfterComma ? "{%s, %s}" : "{%s,%s}";
m_strValue = CMIUtilString::Format(pFormat, m_strValue.c_str(), vResult.GetString().c_str());
return MIstatus::success;
@@ -148,7 +136,7 @@ CMICmnMIValueTuple::BuildTuple(const CMIUtilString &vValue)
}
const CMIUtilString data(ExtractContentNoBrackets());
- const MIchar *pFormat = m_bSpaceAfterComma ? "{%s, %s}" : "{%s,%s}";
+ const char *pFormat = m_bSpaceAfterComma ? "{%s, %s}" : "{%s,%s}";
m_strValue = CMIUtilString::Format(pFormat, data.c_str(), vValue.c_str());
return MIstatus::success;
@@ -176,7 +164,7 @@ CMICmnMIValueTuple::Add(const CMICmnMIValueResult &vResult)
// will return MIstatus::failure.
// Type: Method.
// Args: vValue - (R) The MI value object.
-// vbUseSpacing - (R) True = put space seperators into the string, false = no spaces used.
+// vbUseSpacing - (R) True = put space separators into the string, false = no spaces used.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
@@ -194,7 +182,7 @@ CMICmnMIValueTuple::Add(const CMICmnMIValueResult &vResult, const bool vbUseSpac
// will return MIstatus::failure.
// Type: Method.
// Args: vValue - (R) The MI value object.
-// vbUseSpacing - (R) True = put space seperators into the string, false = no spaces used.
+// vbUseSpacing - (R) True = put space separators into the string, false = no spaces used.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
diff --git a/tools/lldb-mi/MICmnMIValueTuple.h b/tools/lldb-mi/MICmnMIValueTuple.h
index d5cc5326ea44..3b6a8835d25f 100644
--- a/tools/lldb-mi/MICmnMIValueTuple.h
+++ b/tools/lldb-mi/MICmnMIValueTuple.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnMIValueTuple.h
-//
-// Overview: CMICmnMIValueTuple interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
@@ -72,5 +60,5 @@ class CMICmnMIValueTuple : public CMICmnMIValue
// Attributes:
private:
- bool m_bSpaceAfterComma; // True = put space seperators into the string, false = no spaces used
+ bool m_bSpaceAfterComma; // True = put space separators into the string, false = no spaces used
};
diff --git a/tools/lldb-mi/MICmnResources.cpp b/tools/lldb-mi/MICmnResources.cpp
index bc1fa3025cd6..3d8583f29d84 100644
--- a/tools/lldb-mi/MICmnResources.cpp
+++ b/tools/lldb-mi/MICmnResources.cpp
@@ -7,19 +7,8 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnResources.cpp
-//
-// Overview: CMICmnResources implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third party headers
+#include <inttypes.h> // For PRIx64
#include "assert.h"
// In-house headers:
@@ -62,9 +51,6 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{IDS_DRIVERMGR_DRIVER_ERR_INIT, "Driver Manager. Driver '%s' (ID:'%s') initialise failed. %s"},
{IDE_MEDIUMSTDERR_NAME, "Stderr"},
{IDE_MEDIUMSTDOUT_NAME, "Stdout"},
- {IDE_MI_APP_EXIT_OK, "Program exited OK"},
- {IDE_MI_APP_EXIT_WITH_PROBLEM, "Program exited with a problem, see '%s' file"},
- {IDE_MI_APP_EXIT_WITH_PROBLEM_NO_LOG, "Program exited with a problem, the application's log file '%s' was disabled"},
{IDE_MI_APP_DESCRIPTION, "Description:\nThe Machine Interface Driver (MI Driver) is a stand alone executable\nthat either be used via "
"a client i.e. Eclipse or directly from the command\nline. It processes MI commands, actions those commands "
"using the internal\ndebugger then forms MI response formatted text which is returned to the\nclient."},
@@ -75,14 +61,13 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{IDE_MI_APP_ARG_HELP, "-h\n--help\n\tPrints out usage information for the MI debugger. Exit the MI\n\tDriver immediately."},
{IDE_MI_APP_ARG_VERSION, "--version\n\tPrints out GNU (gdb) version information. Exit the MI Driver\n\timmediately."},
{IDE_MI_APP_ARG_VERSION_LONG, "--versionLong\n\tPrints out MI Driver version information. Exit the MI Driver\n\timmediately."},
- {IDE_MI_APP_ARG_INTERPRETER, "--interpreter\n\tUse the MI Driver for the debugger (MI mode)(Default is the\n\tLLDB driver). Any LLDB "
- "command line options are ignored even\n\tif the MI Driver falls through to the LLDB driver. "
- "(Depends\n\ton the build configuration see MICmnConfig.h)\n\tNormally specified by the driver client "
- "i.e. Eclipse.\n\tCannot specify an executable with this option, use --executable."},
- {IDE_MI_APP_ARG_EXECUTEABLE, "--executable\n\tUse the MI Driver in MI mode for the debugging the specified\n\texecutable. Any LLDB "
- "command line options are ignored even\n\tif the MI Driver falls through to the LLDB driver. "
- "(Depends\n\ton the build configuration see MICmnConfig.h)\n\tNormally specified from the command line."},
+ {IDE_MI_APP_ARG_INTERPRETER, "--interpreter\n\t This option is kept for backward compatibility. This executable always run in MI mode"},
+ {IDE_MI_APP_ARG_EXECUTEABLE, "--executable\n\tUse the MI Driver in MI mode for the debugging the specified executable." },
+ {IDE_MI_APP_ARG_SOURCE, "-s <filename>\n--source <filename>\n\t"
+ "Tells the debugger to read in and execute the lldb commands in the\n\t"
+ "given file, after any file provided on the command line has been\n\tloaded."},
{IDE_MI_APP_ARG_APP_LOG, "--log\n\tUse this argument to tell the MI Driver to update it's log\n\tfile '%s'."},
+ {IDE_MI_APP_ARG_APP_LOG_DIR, "--log-dir\n\tUse this argument to specify the directory the MI Driver\n\twill place the log file in, i.e --log-dir=/tmp." },
{IDE_MI_APP_ARG_EXAMPLE, "Example MI command:\n\t3-info-gdb-mi-command gdb-set\n\t3^done,command={exists=\"true\"}"},
{IDE_MI_APP_ARG_EXECUTABLE, "executable (NOT IMPLEMENTED)\n\tThe file path to the executable i.e. '\"C:\\My Dev\\foo.exe\"'."},
{IDS_STDIN_ERR_INVALID_PROMPT, "Stdin. Invalid prompt description '%s'"},
@@ -103,7 +88,6 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{IDS_CMDFACTORY_ERR_CMD_ALREADY_REGED, "Command factory. Command '%s' by that name already registered"},
{IDS_CMDMGR_ERR_CMD_FAILED_CREATE, "Command manager. Command creation failed. %s"},
{IDS_CMDMGR_ERR_CMD_INVOKER, "Command manager. %s "},
- {IDS_PROCESS_SIGNAL_RECEIVED, "Process signal. Application received signal '%s' (%d)"},
{IDS_MI_INIT_ERR_LOG, "Log. Error occurred during initialisation %s"},
{IDS_MI_INIT_ERR_RESOURCES, "Resources. Error occurred during initialisation %s"},
{IDS_MI_INIT_ERR_INIT, "Driver. Error occurred during initialisation %s"},
@@ -143,7 +127,7 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{IDS_LLDBDEBUGGER_ERR_THREAD_DELETE, "LLDB Debugger. Thread failed to delete '%s'"},
{IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER, "LLDB Debugger. Invalid SB broadcaster class name '%s' "},
{IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME, "LLDB Debugger. Invalid client name '%s' "},
- {IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERD, "LLDB Debugger. Client name '%s' not registered for listening events"},
+ {IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERED, "LLDB Debugger. Client name '%s' not registered for listening events"},
{IDS_LLDBDEBUGGER_ERR_STOPLISTENER, "LLDB Debugger. Failure occurred stopping event for client '%s' SBBroadcaster '%s'"},
{IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME, "LLDB Debugger. Broardcaster's name '%s' is not valid"},
{IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT, "LLDB Debugger. Unhandled event '%s'"},
@@ -196,9 +180,7 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{IDS_DRIVER_ERR_MAINLOOP, "Driver. Error in do main loop. %s"},
{IDS_DRIVER_ERR_LOCAL_DEBUG_NOT_IMPL, "Driver. --executable argument given. Local debugging is not implemented."},
{IDS_DRIVER_ERR_LOCAL_DEBUG_INIT, "Driver. --executable argument given. Initialising local debugging failed."},
- {IDS_STDOUT_ERR_NOT_ALL_DATA_WRITTEN, "Stdout. Not all data was written to stream. The data '%s'"},
{IDS_STDERR_ERR_NOT_ALL_DATA_WRITTEN, "Stderr. Not all data was written to stream. The data '%s'"},
- {IDS_CMD_ARGS_ERR_N_OPTIONS_REQUIRED, "Command Args. Missing options, %d or more required"},
{IDS_CMD_ARGS_ERR_OPTION_NOT_FOUND, "Command Args. Option '%s' not found"},
{IDS_CMD_ARGS_ERR_VALIDATION_MANDATORY, "Mandatory args not found: %s"},
{IDS_CMD_ARGS_ERR_VALIDATION_INVALID, "Invalid args: %s"},
@@ -225,6 +207,7 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{IDS_CMD_ERR_FNFAILED, "Command '%s'. Fn '%s' failed"},
{IDS_CMD_ERR_SHARED_DATA_NOT_FOUND, "Command '%s'. Shared data '%s' not found"},
{IDS_CMD_ERR_LLDBPROCESS_DETACH, "Command '%s'. Process detach failed. '%s'"},
+ {IDS_CMD_ERR_LLDBPROCESS_DESTROY, "Command '%s'. Process destroy failed. '%s'"},
{IDS_CMD_ERR_SETWKDIR, "Command '%s'. Failed to set working directory '%s'"},
{IDS_CMD_ERR_INVALID_TARGET, "Command '%s'. Target binary '%s' is invalid. %s"},
{IDS_CMD_ERR_INVALID_TARGET_CURRENT, "Command '%s'. Current SBTarget is invalid"},
@@ -236,6 +219,7 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED, "Command '%s'. Command not implemented as it has been deprecated"},
{IDS_CMD_ERR_CREATE_TARGET, "Command '%s'. Create target failed: %s"},
{IDS_CMD_ERR_BRKPT_LOCATION_FORMAT, "Command '%s'. Incorrect format for breakpoint location '%s'"},
+ {IDS_CMD_ERR_BRKPT_LOCATION_NOT_FOUND, "Command '%s'. Breakpoint location '%s' not found"},
{IDS_CMD_ERR_BRKPT_INVALID, "Command '%s'. Breakpoint '%s' invalid"},
{IDS_CMD_ERR_BRKPT_CNT_EXCEEDED, "Command '%s'. Number of valid breakpoint exceeded %d. Cannot create new breakpoint '%s'"},
{IDS_CMD_ERR_SOME_ERROR, "Command '%s'. Error: %s"},
@@ -246,23 +230,33 @@ const CMICmnResources::SRsrcTextData CMICmnResources::ms_pResourceId2TextData[]
{IDS_CMD_ERR_VARIABLE_ENUM_INVALID, "Command '%s'. Invalid enumeration for variable '%s' formatted string '%s'"},
{IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH, "Command '%s'. Failed to get expression for variable '%s'"},
{IDS_CMD_ERR_VARIABLE_CREATION_FAILED, "Failed to create variable object for '%s'"},
+ {IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID, "Command '%s'. Variable children range invalid"},
{IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION, "<Error: Command run but command did not do anything useful. No MI response formed>"},
{IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION, "<Error: Command run and event caught, did nothing useful. No MI Out-of-Bound formed>"},
{IDS_CMD_ERR_DISASM_ADDR_START_INVALID, "Command '%s'. Invalid start value '%s'"},
{IDS_CMD_ERR_DISASM_ADDR_END_INVALID, "Command '%s'. Invalid end value '%s'"},
{IDS_CMD_ERR_MEMORY_ALLOC_FAILURE, "Command '%s'. Failed to allocate memory %d bytes"},
- {IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK, "Command '%s'. LLDB unable to read entire memory block of %u bytes at address 0x%08x"},
- {IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES, "Command '%s'. Unable to read memory block of %u bytes at address 0x%08x: %s "},
+ {IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK, "Command '%s'. LLDB unable to read entire memory block of %u bytes at address 0x%016" PRIx64 },
+ {IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES, "Command '%s'. Unable to read memory block of %u bytes at address 0x%016" PRIx64 ": %s "},
{IDS_CMD_ERR_INVALID_PROCESS, "Command '%s'. Invalid process during debug session"},
- {IDS_CMD_ERR_INVALID_PRINT_VALUES, "Command '%s'. Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", 1 or \"all-values\", 2 or \"simple-values\""},
+ {IDS_CMD_ERR_INVALID_PRINT_VALUES, "Command '%s'. Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", 1 or \"--all-values\", 2 or \"--simple-values\""},
+ {IDS_CMD_ERR_INVALID_LOCATION_FORMAT, "Command '%s'. Invalid location format '%s'"},
{IDS_CMD_ERR_INVALID_FORMAT_TYPE, "Command '%s'. Invalid var format type '%s'"},
{IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND, "Command '%s'. Breakpoint information for breakpoint ID %d not found"},
- {IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES, "Command '%s'. Unable to write memory block of %u bytes at address 0x%08x: %s "},
- {IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK, "Command '%s'. LLDB unable to write entire memory block of %u bytes at address 0x%08x"},
+ {IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES, "Command '%s'. Unable to write memory block of %u bytes at address 0x%016" PRIx64 ": %s "},
+ {IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK, "Command '%s'. LLDB unable to write entire memory block of %u bytes at address 0x%016" PRIX64},
{IDS_CMD_ERR_SET_NEW_DRIVER_STATE, "Command '%s'. Command tried to set new MI Driver running state and failed. %s"},
- {IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND, "The request '%s' was not recogised, not implemented"},
+ {IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND, "The request '%s' was not recognised, not implemented"},
{IDS_CMD_ERR_INFO_PRINTFN_FAILED, "The request '%s' failed."},
- {IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH, "'solib-search-path' requires at least one argument"}};
+ {IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC, "'target-async' expects \"on\" or \"off\""},
+ {IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH, "'solib-search-path' requires at least one argument"},
+ {IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS, "'print' expects option-name and \"on\" or \"off\""},
+ {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_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.
@@ -391,7 +385,7 @@ CMICmnResources::HasString(const MIuint vResourceId) const
}
//++ ------------------------------------------------------------------------------------
-// Details: Retrieve the resource text data for the given resource ID. If a resourse ID
+// Details: Retrieve the resource text data for the given resource ID. If a resource ID
// cannot be found and error is given returning the ID of the resource that
// cannot be located.
// Type: Method.
@@ -428,7 +422,7 @@ CMICmnResources::GetStringFromResource(const MIuint vResourceId, CMIUtilString &
const MIuint nRsrcId((*it).first);
MIunused(nRsrcId);
- const MIchar *pRsrcData((*it).second);
+ const char *pRsrcData((*it).second);
// Return result
vrwResourceString = pRsrcData;
diff --git a/tools/lldb-mi/MICmnResources.h b/tools/lldb-mi/MICmnResources.h
index b561473fbb79..7e5b70fcbdd2 100644
--- a/tools/lldb-mi/MICmnResources.h
+++ b/tools/lldb-mi/MICmnResources.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnResources.h
-//
-// Overview: CMICmnResources interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers
@@ -77,10 +65,6 @@ enum
IDE_MEDIUMSTDERR_NAME,
IDE_MEDIUMSTDOUT_NAME,
- IDE_MI_APP_EXIT_OK,
- IDE_MI_APP_EXIT_WITH_PROBLEM,
- IDE_MI_APP_EXIT_WITH_PROBLEM_NO_LOG,
-
IDE_MI_APP_DESCRIPTION,
IDE_MI_APP_INFORMATION,
IDE_MI_APP_ARG_USAGE,
@@ -89,7 +73,9 @@ enum
IDE_MI_APP_ARG_VERSION_LONG,
IDE_MI_APP_ARG_INTERPRETER,
IDE_MI_APP_ARG_EXECUTEABLE,
+ IDE_MI_APP_ARG_SOURCE,
IDE_MI_APP_ARG_APP_LOG,
+ IDE_MI_APP_ARG_APP_LOG_DIR,
IDE_MI_APP_ARG_EXAMPLE,
IDE_MI_APP_ARG_EXECUTABLE,
@@ -116,8 +102,6 @@ enum
IDS_CMDMGR_ERR_CMD_FAILED_CREATE,
IDS_CMDMGR_ERR_CMD_INVOKER,
- IDS_PROCESS_SIGNAL_RECEIVED,
-
IDS_MI_INIT_ERR_LOG,
IDS_MI_INIT_ERR_RESOURCES,
IDS_MI_INIT_ERR_INIT,
@@ -154,7 +138,7 @@ enum
IDS_LLDBDEBUGGER_ERR_THREAD_DELETE,
IDS_LLDBDEBUGGER_ERR_INVALIDBROADCASTER,
IDS_LLDBDEBUGGER_ERR_INVALIDCLIENTNAME,
- IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERD,
+ IDS_LLDBDEBUGGER_ERR_CLIENTNOTREGISTERED,
IDS_LLDBDEBUGGER_ERR_STOPLISTENER,
IDS_LLDBDEBUGGER_ERR_BROARDCASTER_NAME,
IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT,
@@ -208,10 +192,8 @@ enum
IDS_DRIVER_WAITING_STDIN_DATA,
- IDS_STDOUT_ERR_NOT_ALL_DATA_WRITTEN,
IDS_STDERR_ERR_NOT_ALL_DATA_WRITTEN,
- IDS_CMD_ARGS_ERR_N_OPTIONS_REQUIRED,
IDS_CMD_ARGS_ERR_OPTION_NOT_FOUND,
IDS_CMD_ARGS_ERR_VALIDATION_MANDATORY,
IDS_CMD_ARGS_ERR_VALIDATION_INVALID,
@@ -241,6 +223,7 @@ enum
IDS_CMD_ERR_FNFAILED,
IDS_CMD_ERR_SHARED_DATA_NOT_FOUND,
IDS_CMD_ERR_LLDBPROCESS_DETACH,
+ IDS_CMD_ERR_LLDBPROCESS_DESTROY,
IDS_CMD_ERR_SETWKDIR,
IDS_CMD_ERR_INVALID_TARGET,
IDS_CMD_ERR_INVALID_TARGET_CURRENT,
@@ -252,6 +235,7 @@ enum
IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED,
IDS_CMD_ERR_CREATE_TARGET,
IDS_CMD_ERR_BRKPT_LOCATION_FORMAT,
+ IDS_CMD_ERR_BRKPT_LOCATION_NOT_FOUND,
IDS_CMD_ERR_BRKPT_INVALID,
IDS_CMD_ERR_BRKPT_CNT_EXCEEDED,
IDS_CMD_ERR_SOME_ERROR,
@@ -262,6 +246,7 @@ enum
IDS_CMD_ERR_VARIABLE_ENUM_INVALID,
IDS_CMD_ERR_VARIABLE_EXPRESSIONPATH,
IDS_CMD_ERR_VARIABLE_CREATION_FAILED,
+ IDS_CMD_ERR_VARIABLE_CHILD_RANGE_INVALID,
IDS_CMD_ERR_CMD_RUN_BUT_NO_ACTION,
IDS_CMD_ERR_EVENT_HANDLED_BUT_NO_ACTION,
IDS_CMD_ERR_DISASM_ADDR_START_INVALID,
@@ -271,6 +256,7 @@ enum
IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES,
IDS_CMD_ERR_INVALID_PROCESS,
IDS_CMD_ERR_INVALID_PRINT_VALUES,
+ IDS_CMD_ERR_INVALID_LOCATION_FORMAT,
IDS_CMD_ERR_INVALID_FORMAT_TYPE,
IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND,
IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES,
@@ -278,7 +264,15 @@ enum
IDS_CMD_ERR_SET_NEW_DRIVER_STATE,
IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND,
IDS_CMD_ERR_INFO_PRINTFN_FAILED,
- IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH
+ IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC,
+ IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH,
+ IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS,
+ 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_ATTACH_FAILED,
+ IDS_CMD_ERR_ATTACH_BAD_ARGS
};
//++ ============================================================================
@@ -303,8 +297,8 @@ class CMICmnResources : public CMICmnBase, public MI::ISingleton<CMICmnResources
// Typedef:
private:
- typedef std::map<MIuint, const MIchar *> MapRscrIdToTextData_t;
- typedef std::pair<MIuint, const MIchar *> MapPairRscrIdToTextData_t;
+ typedef std::map<MIuint, const char *> MapRscrIdToTextData_t;
+ typedef std::pair<MIuint, const char *> MapPairRscrIdToTextData_t;
// Enumerations:
private:
@@ -318,7 +312,7 @@ class CMICmnResources : public CMICmnBase, public MI::ISingleton<CMICmnResources
struct SRsrcTextData
{
MIuint id;
- const MIchar *pTextData;
+ const char *pTextData;
};
// Methods:
diff --git a/tools/lldb-mi/MICmnStreamStderr.cpp b/tools/lldb-mi/MICmnStreamStderr.cpp
index cd09e8fc33d0..74f36121ee63 100644
--- a/tools/lldb-mi/MICmnStreamStderr.cpp
+++ b/tools/lldb-mi/MICmnStreamStderr.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnStreamStderr.cpp
-//
-// Overview: CMICmnStreamStderr implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnStreamStderr.h"
#include "MICmnLog.h"
diff --git a/tools/lldb-mi/MICmnStreamStderr.h b/tools/lldb-mi/MICmnStreamStderr.h
index 4fc363fa6b0a..4f4874ebc9bc 100644
--- a/tools/lldb-mi/MICmnStreamStderr.h
+++ b/tools/lldb-mi/MICmnStreamStderr.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnStreamStderr.h
-//
-// Overview: CMICmnStreamStderr interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
diff --git a/tools/lldb-mi/MICmnStreamStdin.cpp b/tools/lldb-mi/MICmnStreamStdin.cpp
index 2d54921d323c..891b1c9bb994 100644
--- a/tools/lldb-mi/MICmnStreamStdin.cpp
+++ b/tools/lldb-mi/MICmnStreamStdin.cpp
@@ -7,32 +7,19 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilStreamStdin.cpp
-//
-// Overview: CMICmnStreamStdin implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
+// Third Party Headers
+#ifdef _MSC_VER
+#include <Windows.h>
+#endif
+#include <string.h> // For std::strerror()
// In-house headers:
#include "MICmnStreamStdin.h"
#include "MICmnStreamStdout.h"
#include "MICmnResources.h"
#include "MICmnLog.h"
-#include "MICmnThreadMgrStd.h"
-#include "MIUtilSingletonHelper.h"
#include "MIDriver.h"
-#if defined(_MSC_VER)
-#include "MIUtilSystemWindows.h"
-#include "MICmnStreamStdinWindows.h"
-#else
-#include "MICmnStreamStdinLinux.h"
-#endif // defined( _MSC_VER )
+#include "MIUtilSingletonHelper.h"
//++ ------------------------------------------------------------------------------------
// Details: CMICmnStreamStdin constructor.
@@ -42,13 +29,9 @@
// Throws: None.
//--
CMICmnStreamStdin::CMICmnStreamStdin(void)
- : m_constStrThisThreadname("MI stdin thread")
- , m_pVisitor(nullptr)
- , m_strPromptCurrent("(gdb)")
- , m_bKeyCtrlCHit(false)
- , m_bShowPrompt(false)
- , m_bRedrawPrompt(true)
- , m_pStdinReadHandler(nullptr)
+ : m_strPromptCurrent("(gdb)")
+ , m_bShowPrompt(true)
+ , m_pCmdBuffer(nullptr)
{
}
@@ -86,37 +69,19 @@ CMICmnStreamStdin::Initialize(void)
// Note initialisation order is important here as some resources depend on previous
MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleInit<CMICmnThreadMgrStd>(IDS_MI_INIT_ERR_THREADMGR, bOk, errMsg);
-#ifdef _MSC_VER
- MI::ModuleInit<CMICmnStreamStdinWindows>(IDS_MI_INIT_ERR_OS_STDIN_HANDLER, bOk, errMsg);
- bOk = bOk && SetOSStdinHandler(CMICmnStreamStdinWindows::Instance());
-#else
- MI::ModuleInit<CMICmnStreamStdinLinux>(IDS_MI_INIT_ERR_OS_STDIN_HANDLER, bOk, errMsg);
- bOk = bOk && SetOSStdinHandler(CMICmnStreamStdinLinux::Instance());
-#endif // ( _MSC_VER )
-
- // The OS specific stdin stream handler must be set before *this class initialises
- if (bOk && m_pStdinReadHandler == nullptr)
- {
- CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_STREAMSTDIN_OSHANDLER), errMsg.c_str()));
- SetErrorDescription(strInitError);
- return MIstatus::failure;
- }
- // Other resources required
if (bOk)
{
- m_bKeyCtrlCHit = false; // Reset
+ m_pCmdBuffer = new char[m_constBufferSize];
}
-
- m_bInitialized = bOk;
-
- if (!bOk)
+ else
{
CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_STREAMSTDIN), errMsg.c_str()));
SetErrorDescription(strInitError);
+
return MIstatus::failure;
}
+ m_bInitialized = bOk;
return MIstatus::success;
}
@@ -142,19 +107,15 @@ CMICmnStreamStdin::Shutdown(void)
ClrErrorDescription();
+ if (m_pCmdBuffer != nullptr)
+ {
+ delete[] m_pCmdBuffer;
+ m_pCmdBuffer = nullptr;
+ }
+
bool bOk = MIstatus::success;
CMIUtilString errMsg;
- m_pVisitor = nullptr;
- m_bKeyCtrlCHit = false;
-
-// Note shutdown order is important here
-#ifndef _MSC_VER
- MI::ModuleShutdown<CMICmnStreamStdinLinux>(IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER, bOk, errMsg);
-#else
- MI::ModuleShutdown<CMICmnStreamStdinWindows>(IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER, bOk, errMsg);
-#endif // ( _MSC_VER )
- MI::ModuleShutdown<CMICmnThreadMgrStd>(IDS_MI_SHTDWN_ERR_THREADMGR, bOk, errMsg);
MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);
@@ -203,23 +164,6 @@ CMICmnStreamStdin::GetPrompt(void) const
}
//++ ------------------------------------------------------------------------------------
-// Details: Wait on input from stream Stdin. On each line of input received it is
-// validated and providing there are no errors on the stream or the input
-// buffer is not exceeded the data is passed to the visitor.
-// Type: Method.
-// Args: vrVisitor - (W) A client deriver callback.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdin::SetVisitor(IStreamStdin &vrVisitor)
-{
- m_pVisitor = &vrVisitor;
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
// Details: Set whether to display optional command line prompt. The prompt is output to
// stdout. Disable it when this may interfere with the client reading stdout as
// input and it tries to interpret the prompt text to.
@@ -251,199 +195,47 @@ CMICmnStreamStdin::GetEnablePrompt(void) const
}
//++ ------------------------------------------------------------------------------------
-// Details: Determine if stdin has any characters present in its buffer.
-// Type: Method.
-// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdin::InputAvailable(bool &vwbAvail)
-{
- return m_pStdinReadHandler->InputAvailable(vwbAvail);
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: The monitoring on new line data calls back to the visitor object registered
-// with *this stdin monitoring. The monitoring to stops when the visitor returns
-// true for bYesExit flag. Errors output to log file.
-// This function runs in the thread "MI stdin monitor".
+// Details: Wait on new line of data from stdin stream (completed by '\n' or '\r').
// Type: Method.
-// vrwbYesAlive - (W) False = yes exit stdin monitoring, true = continue monitor.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
+// Args: vwErrMsg - (W) Empty string ok or error description.
+// Return: char * - text buffer pointer or NULL on failure.
// Throws: None.
//--
-bool
-CMICmnStreamStdin::MonitorStdin(bool &vrwbYesAlive)
+const char *
+CMICmnStreamStdin::ReadLine(CMIUtilString &vwErrMsg)
{
- if (m_bShowPrompt)
- {
- CMICmnStreamStdout &rStdoutMan = CMICmnStreamStdout::Instance();
- rStdoutMan.WriteMIResponse(m_strPromptCurrent.c_str());
- m_bRedrawPrompt = false;
- }
+ vwErrMsg.clear();
- // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
- if (m_bKeyCtrlCHit)
+ // Read user input
+ const char *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
+ if (pText == nullptr)
{
- CMIDriver &rMIDriver = CMIDriver::Instance();
- rMIDriver.SetExitApplicationFlag(false);
- if (rMIDriver.GetExitApplicationFlag())
+#ifdef _MSC_VER
+ // Was Ctrl-C hit?
+ // On Windows, Ctrl-C gives an ERROR_OPERATION_ABORTED as error on the command-line.
+ // The end-of-file indicator is also set, so without this check we will exit next if statement.
+ if (::GetLastError() == ERROR_OPERATION_ABORTED)
+ return nullptr;
+#endif
+ if (::feof(stdin))
{
- vrwbYesAlive = false;
- return MIstatus::success;
+ const bool bForceExit = true;
+ CMIDriver::Instance().SetExitApplicationFlag(bForceExit);
}
-
- // Reset - the MI Driver received SIGINT during a running debug programm session
- m_bKeyCtrlCHit = false;
+ else if (::ferror(stdin) != 0)
+ vwErrMsg = ::strerror(errno);
+ return nullptr;
}
-#if MICONFIG_POLL_FOR_STD_IN
- bool bAvail = true;
- // Check if there is stdin available
- if (InputAvailable(bAvail))
- {
- // Early exit when there is no input
- if (!bAvail)
- return MIstatus::success;
- }
- else
+ // Strip off new line characters
+ for (char *pI = m_pCmdBuffer; *pI != '\0'; pI++)
{
- vrwbYesAlive = false;
- CMIDriver::Instance().SetExitApplicationFlag(true);
- return MIstatus::failure;
- }
-#endif // MICONFIG_POLL_FOR_STD_IN
-
- // Read a line from std input
- CMIUtilString stdinErrMsg;
- const MIchar *pText = ReadLine(stdinErrMsg);
-
- // Did something go wrong
- const bool bHaveError(!stdinErrMsg.empty());
- if ((pText == nullptr) || bHaveError)
- {
- if (bHaveError)
+ if ((*pI == '\n') || (*pI == '\r'))
{
- CMICmnStreamStdout::Instance().Write(stdinErrMsg);
+ *pI = '\0';
+ break;
}
- return MIstatus::failure;
- }
-
- // We have text so send it off to the visitor
- bool bOk = MIstatus::success;
- if (m_pVisitor != nullptr)
- {
- bool bYesExit = false;
- bOk = m_pVisitor->ReadLine(CMIUtilString(pText), bYesExit);
- m_bRedrawPrompt = true;
- vrwbYesAlive = !bYesExit;
}
- return bOk;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Wait on new line of data from stdin stream (completed by '\n' or '\r').
-// Type: Method.
-// Args: vwErrMsg - (W) Empty string ok or error description.
-// Return: MIchar * - text buffer pointer or NULL on failure.
-// Throws: None.
-//--
-const MIchar *
-CMICmnStreamStdin::ReadLine(CMIUtilString &vwErrMsg)
-{
- return m_pStdinReadHandler->ReadLine(vwErrMsg);
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Inform *this stream that the user hit Control-C key to exit.
-// The function is normally called by the SIGINT signal in sigint_handler() to
-// simulate kill app from the client.
-// This function is called by a Kernel thread.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void
-CMICmnStreamStdin::SetCtrlCHit(void)
-{
- CMIUtilThreadLock lock(m_mutex);
- m_bKeyCtrlCHit = true;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: The main worker method for this thread.
-// Type: Overridden.
-// Args: vrbIsAlive - (W) True = *this thread is working, false = thread has exited.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdin::ThreadRun(bool &vrbIsAlive)
-{
- return MonitorStdin(vrbIsAlive);
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Let this thread clean up after itself.
-// Type: Overridden.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdin::ThreadFinish(void)
-{
- // Do nothing - override to implement
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Retrieve *this thread object's name.
-// Type: Overridden.
-// Args: None.
-// Return: CMIUtilString & - Text.
-// Throws: None.
-//--
-const CMIUtilString &
-CMICmnStreamStdin::ThreadGetName(void) const
-{
- return m_constStrThisThreadname;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Mandatory set the OS specific stream stdin handler. *this class utilises the
-// handler to read data from the stdin stream and put into a queue for the
-// driver to read when able.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdin::SetOSStdinHandler(IOSStdinHandler &vrHandler)
-{
- m_pStdinReadHandler = &vrHandler;
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Do some actions before exiting.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void
-CMICmnStreamStdin::OnExitHandler(void)
-{
- m_pStdinReadHandler->InterruptReadLine();
+ return pText;
}
diff --git a/tools/lldb-mi/MICmnStreamStdin.h b/tools/lldb-mi/MICmnStreamStdin.h
index a6779d531669..309c7d8eed2f 100644
--- a/tools/lldb-mi/MICmnStreamStdin.h
+++ b/tools/lldb-mi/MICmnStreamStdin.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilStreamStdin.h
-//
-// Overview: CMICmnStreamStdin interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
@@ -37,40 +25,11 @@
// Authors: Illya Rudkin 10/02/2014.
// Changes: Factored out OS specific handling of reading stdin - IOR 16/06/2014.
//--
-class CMICmnStreamStdin : public CMICmnBase, public CMIUtilThreadActiveObjBase, public MI::ISingleton<CMICmnStreamStdin>
+class CMICmnStreamStdin : public CMICmnBase, public MI::ISingleton<CMICmnStreamStdin>
{
// Give singleton access to private constructors
friend MI::ISingleton<CMICmnStreamStdin>;
- // Class:
- public:
- //++
- // Description: Visitor pattern. Driver(s) use this interface to get a callback
- // on each new line of data received from stdin.
- //--
- class IStreamStdin
- {
- public:
- virtual bool ReadLine(const CMIUtilString &vStdInBuffer, bool &vrwbYesExit) = 0;
-
- /* dtor */ virtual ~IStreamStdin(void){};
- };
-
- //++
- // Description: Specific OS stdin handling implementations are created and used by *this
- // class. Seperates out functionality and enables handler to be set
- // dynamically depended on the OS detected.
- //--
- class IOSStdinHandler
- {
- public:
- virtual bool InputAvailable(bool &vwbAvail) = 0;
- virtual const MIchar *ReadLine(CMIUtilString &vwErrMsg) = 0;
- virtual void InterruptReadLine(void){};
-
- /* dtor */ virtual ~IOSStdinHandler(void){};
- };
-
// Methods:
public:
bool Initialize(void);
@@ -80,22 +39,7 @@ class CMICmnStreamStdin : public CMICmnBase, public CMIUtilThreadActiveObjBase,
bool SetPrompt(const CMIUtilString &vNewPrompt);
void SetEnablePrompt(const bool vbYes);
bool GetEnablePrompt(void) const;
- void SetCtrlCHit(void);
- bool SetVisitor(IStreamStdin &vrVisitor);
- bool SetOSStdinHandler(IOSStdinHandler &vrHandler);
- void OnExitHandler(void);
-
- // Overridden:
- public:
- // From CMIUtilThreadActiveObjBase
- virtual const CMIUtilString &ThreadGetName(void) const;
-
- // Overridden:
- protected:
- // From CMIUtilThreadActiveObjBase
- virtual bool ThreadRun(bool &vrIsAlive);
- virtual bool
- ThreadFinish(void); // Let this thread clean up after itself
+ const char *ReadLine(CMIUtilString &vwErrMsg);
// Methods:
private:
@@ -103,11 +47,6 @@ class CMICmnStreamStdin : public CMICmnBase, public CMIUtilThreadActiveObjBase,
/* ctor */ CMICmnStreamStdin(const CMICmnStreamStdin &);
void operator=(const CMICmnStreamStdin &);
- bool MonitorStdin(bool &vrwbYesExit);
- const MIchar *ReadLine(CMIUtilString &vwErrMsg);
- bool
- InputAvailable(bool &vbAvail); // Bytes are available on stdin
-
// Overridden:
private:
// From CMICmnBase
@@ -115,11 +54,8 @@ class CMICmnStreamStdin : public CMICmnBase, public CMIUtilThreadActiveObjBase,
// Attributes:
private:
- const CMIUtilString m_constStrThisThreadname;
- IStreamStdin *m_pVisitor;
CMIUtilString m_strPromptCurrent; // Command line prompt as shown to the user
- volatile bool m_bKeyCtrlCHit; // True = User hit Ctrl-C, false = has not yet
bool m_bShowPrompt; // True = Yes prompt is shown/output to the user (stdout), false = no prompt
- bool m_bRedrawPrompt; // True = Prompt needs to be redrawn
- IOSStdinHandler *m_pStdinReadHandler;
+ static const int m_constBufferSize = 2048;
+ char *m_pCmdBuffer;
};
diff --git a/tools/lldb-mi/MICmnStreamStdinLinux.cpp b/tools/lldb-mi/MICmnStreamStdinLinux.cpp
deleted file mode 100644
index 07e652d84c19..000000000000
--- a/tools/lldb-mi/MICmnStreamStdinLinux.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-//===-- MICmnStreamStdinLinux.cpp --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilStreamStdin.cpp
-//
-// Overview: CMICmnStreamStdinLinux implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
-// Third Party Headers:
-#if defined(__APPLE__)
-#include <sys/select.h>
-#include <unistd.h> // For STDIN_FILENO
-#endif // defined( __APPLE__ )
-#include <string.h> // For std::strerror()
-
-// In-house headers:
-#include "MICmnStreamStdinLinux.h"
-#include "MICmnLog.h"
-#include "MICmnResources.h"
-#include "MIUtilSingletonHelper.h"
-
-//++ ------------------------------------------------------------------------------------
-// Details: CMICmnStreamStdinLinux constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnStreamStdinLinux::CMICmnStreamStdinLinux(void)
- : m_constBufferSize(1024)
- , m_pStdin(nullptr)
- , m_pCmdBuffer(nullptr)
-{
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: CMICmnStreamStdinLinux destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnStreamStdinLinux::~CMICmnStreamStdinLinux(void)
-{
- Shutdown();
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Initialize resources for *this Stdin stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdinLinux::Initialize(void)
-{
- if (m_bInitialized)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Note initialisation order is important here as some resources depend on previous
- MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
- MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
-
- // Other resources required
- if (bOk)
- {
- m_pCmdBuffer = new MIchar[m_constBufferSize];
- m_pStdin = stdin;
- }
-
- // Clear error indicators for std input
- ::clearerr(stdin);
-
- m_bInitialized = bOk;
-
- if (!bOk)
- {
- CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_OS_STDIN_HANDLER), errMsg.c_str()));
- SetErrorDescription(strInitError);
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Release resources for *this Stdin stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdinLinux::Shutdown(void)
-{
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = false;
-
- ClrErrorDescription();
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Tidy up
- if (m_pCmdBuffer != nullptr)
- {
- delete[] m_pCmdBuffer;
- m_pCmdBuffer = nullptr;
- }
- m_pStdin = nullptr;
-
- // Note shutdown order is important here
- MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
-
- if (!bOk)
- {
- SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER), errMsg.c_str());
- }
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Determine if stdin has any characters present in its buffer.
-// Type: Method.
-// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdinLinux::InputAvailable(bool &vwbAvail)
-{
-#if defined(__APPLE__)
- // The code below is needed on OSX where lldb-mi hangs when doing -exec-run.
- // The hang seems to come from calling fgets and fileno from different thread.
- // Although this problem was not observed on Linux.
- // A solution based on 'ioctl' was initially committed but it seems to make
- // lldb-mi takes much more processor time. The solution based on 'select' works
- // well but it seems to slow the execution of lldb-mi tests a lot on Linux.
- // As a result, this code is #defined to run only on OSX.
- fd_set setOfStdin;
- FD_ZERO(&setOfStdin);
- FD_SET(STDIN_FILENO, &setOfStdin);
-
- // Wait while input would be available
- if (::select(STDIN_FILENO + 1, &setOfStdin, nullptr, nullptr, nullptr) == -1)
- {
- vwbAvail = false;
- return MIstatus::failure;
- }
-
-#endif // defined( __APPLE__ )
- vwbAvail = true;
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Wait on new line of data from stdin stream (completed by '\n' or '\r').
-// Type: Method.
-// Args: vwErrMsg - (W) Empty string ok or error description.
-// Return: MIchar * - text buffer pointer or NULL on failure.
-// Throws: None.
-//--
-const MIchar *
-CMICmnStreamStdinLinux::ReadLine(CMIUtilString &vwErrMsg)
-{
- vwErrMsg.clear();
-
- // Read user input
- const MIchar *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
- if (pText == nullptr)
- {
- if (::ferror(m_pStdin) != 0)
- vwErrMsg = ::strerror(errno);
- return nullptr;
- }
-
- // Strip off new line characters
- for (MIchar *pI = m_pCmdBuffer; *pI != '\0'; pI++)
- {
- if ((*pI == '\n') || (*pI == '\r'))
- {
- *pI = '\0';
- break;
- }
- }
-
- return pText;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Interrupt current and prevent new ReadLine operations.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void
-CMICmnStreamStdinLinux::InterruptReadLine(void)
-{
- fclose(stdin);
-}
diff --git a/tools/lldb-mi/MICmnStreamStdinLinux.h b/tools/lldb-mi/MICmnStreamStdinLinux.h
deleted file mode 100644
index edac94034f57..000000000000
--- a/tools/lldb-mi/MICmnStreamStdinLinux.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===-- MICmnStreamStdinWindows.h --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilStreamStdin.h
-//
-// Overview: CMICmnStreamStdinLinux interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnStreamStdin.h"
-#include "MIUtilSingletonBase.h"
-
-//++ ============================================================================
-// Details: MI common code class. Specific OS stdin handling implementation.
-// CMICmnStreamStdin instance is set with stdin handler before using the
-// the stream. An instance of this class must be set up and ready to give
-// to the CMICmnStreamStdin before it initialises other CMICmnStreamStdin
-// will give an error.
-// Gotchas: None.
-// Authors: Illya Rudkin 16/06/2014.
-// Changes: None.
-//--
-class CMICmnStreamStdinLinux : public CMICmnBase, public CMICmnStreamStdin::IOSStdinHandler, public MI::ISingleton<CMICmnStreamStdinLinux>
-{
- // Give singleton access to private constructors
- friend MI::ISingleton<CMICmnStreamStdinLinux>;
-
- // Methods:
- public:
- bool Initialize(void);
- bool Shutdown(void);
-
- // Overridden:
- public:
- // From CMICmnStreamStdin::IOSpecificReadStreamStdin
- virtual bool InputAvailable(bool &vwbAvail);
- virtual const MIchar *ReadLine(CMIUtilString &vwErrMsg);
- virtual void InterruptReadLine(void);
-
- // Methods:
- private:
- /* ctor */ CMICmnStreamStdinLinux(void);
- /* ctor */ CMICmnStreamStdinLinux(const CMICmnStreamStdin &);
- void operator=(const CMICmnStreamStdin &);
-
- // Overridden:
- private:
- // From CMICmnBase
- /* dtor */ virtual ~CMICmnStreamStdinLinux(void);
-
- // Attributes:
- private:
- const MIuint m_constBufferSize;
- FILE *m_pStdin;
- MIchar *m_pCmdBuffer;
-};
diff --git a/tools/lldb-mi/MICmnStreamStdinWindows.cpp b/tools/lldb-mi/MICmnStreamStdinWindows.cpp
deleted file mode 100644
index 8d5a3e8aa7c9..000000000000
--- a/tools/lldb-mi/MICmnStreamStdinWindows.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-//===-- MICmnStreamStdinWindows.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilStreamStdin.cpp
-//
-// Overview: CMICmnStreamStdinWindows implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
-// Third Party Headers:
-#if defined(_MSC_VER)
-#include <stdio.h>
-#include <Windows.h>
-#include <io.h>
-#include <conio.h>
-#endif // defined( _MSC_VER )
-#include <string.h>
-
-// In-house headers:
-#include "MICmnStreamStdinWindows.h"
-#include "MICmnLog.h"
-#include "MICmnResources.h"
-#include "MIUtilSystemWindows.h"
-#include "MIUtilSingletonHelper.h"
-
-//++ ------------------------------------------------------------------------------------
-// Details: CMICmnStreamStdinWindows constructor.
-// Type: Method.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnStreamStdinWindows::CMICmnStreamStdinWindows(void)
- : m_constBufferSize(1024)
- , m_pStdin(nullptr)
- , m_pCmdBuffer(nullptr)
- , m_pStdinBuffer(nullptr)
- , m_nBytesToBeRead(0)
- , m_bRunningInConsoleWin(false)
-{
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: CMICmnStreamStdinWindows destructor.
-// Type: Overridable.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-CMICmnStreamStdinWindows::~CMICmnStreamStdinWindows(void)
-{
- Shutdown();
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Initialize resources for *this Stdin stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdinWindows::Initialize(void)
-{
- if (m_bInitialized)
- return MIstatus::success;
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Note initialisation order is important here as some resources depend on previous
- MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
- MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
-
- // Other resources required
- if (bOk)
- {
- m_pCmdBuffer = new MIchar[m_constBufferSize];
- m_pStdin = stdin;
-
-#if MICONFIG_CREATE_OWN_STDIN_BUFFER
- // Give stdinput a user defined buffer
- m_pStdinBuffer = new char[1024];
- ::setbuf(stdin, m_pStdinBuffer);
-#endif // MICONFIG_CREATE_OWN_STDIN_BUFFER
-
- // Clear error indicators for std input
- ::clearerr(stdin);
-
-#if defined(_MSC_VER)
- m_bRunningInConsoleWin = ::_isatty(::fileno(stdin));
-#endif // #if defined( _MSC_VER )
- }
-
- m_bInitialized = bOk;
-
- if (!bOk)
- {
- CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_OS_STDIN_HANDLER), errMsg.c_str()));
- SetErrorDescription(strInitError);
- return MIstatus::failure;
- }
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Release resources for *this Stdin stream.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdinWindows::Shutdown(void)
-{
- if (!m_bInitialized)
- return MIstatus::success;
-
- m_bInitialized = false;
-
- ClrErrorDescription();
-
- bool bOk = MIstatus::success;
- CMIUtilString errMsg;
-
- // Tidy up
- if (m_pCmdBuffer != nullptr)
- {
- delete[] m_pCmdBuffer;
- m_pCmdBuffer = nullptr;
- }
- m_pStdin = nullptr;
-
-#if MICONFIG_CREATE_OWN_STDIN_BUFFER
- if (m_pStdinBuffer)
- delete[] m_pStdinBuffer;
- m_pStdinBuffer = nullptr;
-#endif // MICONFIG_CREATE_OWN_STDIN_BUFFER
-
- // Note shutdown order is important here
- MI::ModuleShutdown<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
- MI::ModuleShutdown<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
-
- if (!bOk)
- {
- SetErrorDescriptionn(MIRSRC(IDS_MI_SHTDWN_ERR_OS_STDIN_HANDLER), errMsg.c_str());
- }
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Determine if stdin has any characters present in its buffer.
-// Type: Method.
-// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdinWindows::InputAvailable(bool &vwbAvail)
-{
- return m_bRunningInConsoleWin ? InputAvailableConsoleWin(vwbAvail) : InputAvailableApplication(vwbAvail);
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Determine if stdin has any characters present in its buffer. If running in a
-// terminal use _kbhit().
-// Type: Method.
-// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdinWindows::InputAvailableConsoleWin(bool &vwbAvail)
-{
-#if defined(_MSC_VER)
- if (m_nBytesToBeRead == 0)
- {
- // Get a windows handle to std input stream
- HANDLE handle = ::GetStdHandle(STD_INPUT_HANDLE);
- DWORD nBytesWaiting = ::_kbhit();
-
- // Save the number of bytes to be read so that we can check if input is available to be read
- m_nBytesToBeRead = nBytesWaiting;
-
- // Return state of whether bytes are waiting or not
- vwbAvail = (nBytesWaiting > 0);
- }
-#endif // #if defined( _MSC_VER )
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Determine if stdin has any characters present in its buffer.
-// Type: Method.
-// Args: vwbAvail - (W) True = There is chars available, false = nothing there.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMICmnStreamStdinWindows::InputAvailableApplication(bool &vwbAvail)
-{
-#if defined(_MSC_VER)
- if (m_nBytesToBeRead == 0)
- {
- // Get a windows handle to std input stream
- HANDLE handle = ::GetStdHandle(STD_INPUT_HANDLE);
- DWORD nBytesWaiting = 0;
-
- // Ask how many bytes are available
- if (::PeekNamedPipe(handle, nullptr, 0, nullptr, &nBytesWaiting, nullptr) == FALSE)
- {
- // This can occur when the client i.e. Eclipse closes the stdin stream 'cause it deems its work is finished
- // for that debug session. May be we should be handling SIGKILL somehow?
- const CMIUtilString osErrMsg(CMIUtilSystemWindows().GetOSLastError().StripCRAll());
- SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_STDIN_ERR_CHKING_BYTE_AVAILABLE), osErrMsg.c_str()));
- return MIstatus::failure;
- }
-
- // Save the number of bytes to be read so that we can check if input is available to be read
- m_nBytesToBeRead = nBytesWaiting;
-
- // Return state of whether bytes are waiting or not
- vwbAvail = (nBytesWaiting > 0);
- }
-#endif // #if defined( _MSC_VER )
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Wait on new line of data from stdin stream (completed by '\n' or '\r').
-// Type: Method.
-// Args: vwErrMsg - (W) Empty string ok or error description.
-// Return: MIchar * - text buffer pointer or NULL on failure.
-// Throws: None.
-//--
-const MIchar *
-CMICmnStreamStdinWindows::ReadLine(CMIUtilString &vwErrMsg)
-{
- vwErrMsg.clear();
-
- // Read user input
- const MIchar *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
- if (pText == nullptr)
- {
- if (::ferror(m_pStdin) != 0)
- vwErrMsg = ::strerror(errno);
- return nullptr;
- }
-
- // Subtract the number of bytes read so that we can check if input is available to be read
- m_nBytesToBeRead = m_nBytesToBeRead - ::strlen(pText);
-
- // Strip off new line characters
- for (MIchar *pI = m_pCmdBuffer; *pI != '\0'; pI++)
- {
- if ((*pI == '\n') || (*pI == '\r'))
- {
- *pI = '\0';
- break;
- }
- }
-
- return pText;
-}
diff --git a/tools/lldb-mi/MICmnStreamStdinWindows.h b/tools/lldb-mi/MICmnStreamStdinWindows.h
deleted file mode 100644
index 40e4e8546fe4..000000000000
--- a/tools/lldb-mi/MICmnStreamStdinWindows.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-- MICmnStreamStdinWindows.h -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilStreamStdin.h
-//
-// Overview: CMICmnStreamStdinWindows interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
-#pragma once
-
-// In-house headers:
-#include "MICmnBase.h"
-#include "MICmnStreamStdin.h"
-#include "MIUtilSingletonBase.h"
-
-//++ ============================================================================
-// Details: MI common code class. Specific OS stdin handling implementation.
-// CMICmnStreamStdin instance is set with stdin handler before using the
-// the stream. An instance of this class must be set up and ready to give
-// to the CMICmnStreamStdin before it initialises other CMICmnStreamStdin
-// will give an error.
-// Gotchas: None.
-// Authors: Illya Rudkin 16/06/2014.
-// Changes: None.
-//--
-class CMICmnStreamStdinWindows : public CMICmnBase,
- public CMICmnStreamStdin::IOSStdinHandler,
- public MI::ISingleton<CMICmnStreamStdinWindows>
-{
- // Give singleton access to private constructors
- friend MI::ISingleton<CMICmnStreamStdinWindows>;
-
- // Methods:
- public:
- bool Initialize(void);
- bool Shutdown(void);
-
- // Overridden:
- public:
- // From CMICmnStreamStdin::IOSpecificReadStreamStdin
- virtual bool InputAvailable(bool &vwbAvail);
- virtual const MIchar *ReadLine(CMIUtilString &vwErrMsg);
-
- // Methods:
- private:
- /* ctor */ CMICmnStreamStdinWindows(void);
- /* ctor */ CMICmnStreamStdinWindows(const CMICmnStreamStdinWindows &);
- void operator=(const CMICmnStreamStdinWindows &);
- //
- bool InputAvailableConsoleWin(bool &vwbAvail);
- bool InputAvailableApplication(bool &vwbAvail);
-
- // Overridden:
- private:
- // From CMICmnBase
- /* dtor */ virtual ~CMICmnStreamStdinWindows(void);
-
- // Attributes:
- private:
- const MIuint m_constBufferSize;
- FILE *m_pStdin;
- MIchar *m_pCmdBuffer;
- MIchar *m_pStdinBuffer; // Custom buffer to store std input
- MIuint m_nBytesToBeRead; // Checks that ::fgets() is holding on to data while ::PeekNamedPipe() returns nothing which causes a problem
- bool m_bRunningInConsoleWin; // True = The application is being run in a Windows command line prompt window, false = by other means
-};
diff --git a/tools/lldb-mi/MICmnStreamStdout.cpp b/tools/lldb-mi/MICmnStreamStdout.cpp
index e32d4fca2446..63dec65a7753 100644
--- a/tools/lldb-mi/MICmnStreamStdout.cpp
+++ b/tools/lldb-mi/MICmnStreamStdout.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilStreamcStdout.cpp
-//
-// Overview: CMICmnStreamStdout implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnStreamStdout.h"
#include "MICmnLog.h"
@@ -168,11 +156,9 @@ CMICmnStreamStdout::WritePriv(const CMIUtilString &vText, const CMIUtilString &v
// Send this text to stdout
const MIint status = ::fputs(vText.c_str(), stdout);
if (status == EOF)
- {
- const CMIUtilString errMsg(CMIUtilString::Format(MIRSRC(IDS_STDOUT_ERR_NOT_ALL_DATA_WRITTEN), vText.c_str()));
- SetErrorDescription(errMsg);
+ // Don't call the CMICmnBase::SetErrorDescription() because it will cause a stack overflow:
+ // CMICmnBase::SetErrorDescription -> CMICmnStreamStdout::Write -> CMICmnStreamStdout::WritePriv -> CMICmnBase::SetErrorDescription
bOk = MIstatus::failure;
- }
else
{
::fprintf(stdout, "\n");
@@ -230,9 +216,23 @@ CMICmnStreamStdout::Unlock(void)
bool
CMICmnStreamStdout::TextToStdout(const CMIUtilString &vrTxt)
{
- const bool bLock = CMICmnStreamStdout::Instance().Lock();
- const bool bOk = bLock && CMICmnStreamStdout::Instance().WriteMIResponse(vrTxt);
- bLock &&CMICmnStreamStdout::Instance().Unlock();
+ const bool bSendToLog = true;
+ return CMICmnStreamStdout::Instance().WriteMIResponse(vrTxt, bSendToLog);
+}
- return bOk;
+//++ ------------------------------------------------------------------------------------
+// Details: Write prompt to stdout if it's enabled.
+// Type: Static method.
+// Args: None.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMICmnStreamStdout::WritePrompt(void)
+{
+ const CMICmnStreamStdin &rStdinMan = CMICmnStreamStdin::Instance();
+ if (rStdinMan.GetEnablePrompt())
+ return TextToStdout(rStdinMan.GetPrompt());
+ return MIstatus::success;
}
diff --git a/tools/lldb-mi/MICmnStreamStdout.h b/tools/lldb-mi/MICmnStreamStdout.h
index 677a5c4a1868..526a322f6e35 100644
--- a/tools/lldb-mi/MICmnStreamStdout.h
+++ b/tools/lldb-mi/MICmnStreamStdout.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnStreamStdout.h
-//
-// Overview: CMICmnStreamStdout interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
@@ -43,6 +31,7 @@ class CMICmnStreamStdout : public CMICmnBase, public MI::ISingleton<CMICmnStream
// Statics:
public:
static bool TextToStdout(const CMIUtilString &vrTxt);
+ static bool WritePrompt(void);
// Methods:
public:
diff --git a/tools/lldb-mi/MICmnThreadMgrStd.cpp b/tools/lldb-mi/MICmnThreadMgrStd.cpp
index 8fa30125b832..f0185b8fcf1d 100644
--- a/tools/lldb-mi/MICmnThreadMgrStd.cpp
+++ b/tools/lldb-mi/MICmnThreadMgrStd.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnThreadMgr.cpp
-//
-// Overview: CMICmnThreadMgr implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MICmnThreadMgrStd.h"
#include "MICmnLog.h"
diff --git a/tools/lldb-mi/MICmnThreadMgrStd.h b/tools/lldb-mi/MICmnThreadMgrStd.h
index 598c98a9def3..8f2d207995c6 100644
--- a/tools/lldb-mi/MICmnThreadMgrStd.h
+++ b/tools/lldb-mi/MICmnThreadMgrStd.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MICmnThreadMgrStd.h
-//
-// Overview: CMICmnThreadMgr interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
diff --git a/tools/lldb-mi/MIDataTypes.h b/tools/lldb-mi/MIDataTypes.h
index aced1c66f8d9..b0583343ab3c 100644
--- a/tools/lldb-mi/MIDataTypes.h
+++ b/tools/lldb-mi/MIDataTypes.h
@@ -7,21 +7,11 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIDataTypes.h
-//
// Overview: Common global switches, macros, etc.
//
// This file contains common data types required by applications
// generally. If supported by the compiler, this file should be
// #include'd as part of the project's PCH (precompiled header).
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
@@ -86,9 +76,6 @@ typedef unsigned int MIuint;
// Fundamentals:
typedef float MIflt;
typedef double MIdbl;
-typedef char MIchar; // Defaults to signed char, i.e. MIschar.
-typedef signed char MIschar; // Range: -128 to 127. More explicit than using MIchar.
-typedef unsigned char MIuchar; // Range: 0 to 255.
typedef long long MIint64; // 64bit signed integer.
typedef unsigned long long MIuint64; // 64bit unsigned integer.
diff --git a/tools/lldb-mi/MIDriver.cpp b/tools/lldb-mi/MIDriver.cpp
index 5628e344952b..549f9e255790 100644
--- a/tools/lldb-mi/MIDriver.cpp
+++ b/tools/lldb-mi/MIDriver.cpp
@@ -7,25 +7,11 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIDriver.cpp
-//
-// Overview: CMIDriver implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third party headers:
-#include <stdarg.h> // va_list, va_start, var_end
-#include <iostream>
+#include <fstream>
#include "lldb/API/SBError.h"
// In-house headers:
-#include "Driver.h"
#include "MIDriver.h"
#include "MICmnResources.h"
#include "MICmnLog.h"
@@ -69,6 +55,7 @@ CMIDriver::CMIDriver(void)
, m_eCurrentDriverState(eDriverState_NotRunning)
, m_bHaveExecutableFileNamePathOnCmdLine(false)
, m_bDriverDebuggingArgExecutable(false)
+ , m_bHaveCommandFileNamePathOnCmdLine(false)
{
}
@@ -86,7 +73,7 @@ CMIDriver::~CMIDriver(void)
//++ ------------------------------------------------------------------------------------
// Details: Set whether *this driver (the parent) is enabled to pass a command to its
// fall through (child) driver to interpret the command and do work instead
-// (if *this driver decides it can't hanled the command).
+// (if *this driver decides it can't handle the command).
// Type: Method.
// Args: vbYes - (R) True = yes fall through, false = do not pass on command.
// Return: MIstatus::success - Functional succeeded.
@@ -103,7 +90,7 @@ CMIDriver::SetEnableFallThru(const bool vbYes)
//++ ------------------------------------------------------------------------------------
// Details: Get whether *this driver (the parent) is enabled to pass a command to its
// fall through (child) driver to interpret the command and do work instead
-// (if *this driver decides it can't hanled the command).
+// (if *this driver decides it can't handle the command).
// Type: Method.
// Args: None.
// Return: bool - True = yes fall through, false = do not pass on command.
@@ -187,22 +174,6 @@ CMIDriver::Initialize(void)
bOk &= m_rLldbDebugger.SetDriver(*this);
MI::ModuleInit<CMICmnLLDBDebugger>(IDS_MI_INIT_ERR_LLDBDEBUGGER, bOk, errMsg);
-#if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
- CMIDriverMgr &rDrvMgr = CMIDriverMgr::Instance();
- bOk = bOk && rDrvMgr.RegisterDriver(*g_driver, "LLDB driver"); // Will be pass thru driver
- if (bOk)
- {
- bOk = SetEnableFallThru(false); // This is intentional at this time - yet to be fully implemented
- bOk = bOk && SetDriverToFallThruTo(*g_driver);
- CMIUtilString strOtherDrvErrMsg;
- if (bOk && GetEnableFallThru() && !g_driver->MISetup(strOtherDrvErrMsg))
- {
- bOk = false;
- errMsg = CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_FALLTHRUDRIVER), strOtherDrvErrMsg.c_str());
- }
- }
-#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
-
m_bExitApp = false;
m_bInitialized = bOk;
@@ -340,20 +311,6 @@ CMIDriver::GetError(void) const
}
//++ ------------------------------------------------------------------------------------
-// Details: Call *this driver to resize the console window.
-// Type: Overridden.
-// Args: vTermWidth - (R) New window column size.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-void
-CMIDriver::DoResizeWindow(const uint32_t vTermWidth)
-{
- GetTheDebugger().SetTerminalWidth(vTermWidth);
-}
-
-//++ ------------------------------------------------------------------------------------
// Details: Call *this driver to return it's debugger.
// Type: Overridden.
// Args: None.
@@ -413,16 +370,16 @@ CMIDriver::DoParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool
// Details: Check the arguments that were passed to this program to make sure they are
// valid and to get their argument values (if any). The following are options
// that are only handled by *this driver:
-// --executable
+// --executable <file>
+// --source <file> or -s <file>
// The application's options --interpreter and --executable in code act very similar.
-// The --executable is necessary to differentiate whither the MI Driver is being
-// using by a client i.e. Eclipse or from the command line. Eclipse issues the option
+// The --executable is necessary to differentiate whether the MI Driver is being
+// used by a client (e.g. Eclipse) or from the command line. Eclipse issues the option
// --interpreter and also passes additional arguments which can be interpreted as an
-// executable if called from the command line. Using --executable tells the MI
-// Driver is being called the command line and that the executable argument is indeed
-// a specified executable an so actions commands to set up the executable for a
-// debug session. Using --interpreter on the commnd line does not action additional
-// commands to initialise a debug session and so be able to launch the process.
+// executable if called from the command line. Using --executable tells the MI Driver
+// it is being called from the command line and to prepare to launch the executable
+// argument for a debug session. Using --interpreter on the command line does not
+// issue additional commands to initialise a debug session.
// Type: Overridden.
// Args: argc - (R) An integer that contains the count of arguments that follow in
// argv. The argc parameter is always greater than or equal to 1.
@@ -452,20 +409,40 @@ CMIDriver::ParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &v
if (bHaveArgs)
{
- // Search right to left to look for the executable
+ // Search right to left to look for filenames
for (MIint i = argc - 1; i > 0; i--)
{
const CMIUtilString strArg(argv[i]);
const CMICmdArgValFile argFile;
+
+ // Check for a filename
if (argFile.IsFilePath(strArg) || CMICmdArgValString(true, false, true).IsStringArg(strArg))
{
+ // Is this the command file for the '-s' or '--source' options?
+ const CMIUtilString strPrevArg(argv[i - 1]);
+ if (strPrevArg.compare("-s") == 0 || strPrevArg.compare("--source") == 0)
+ {
+ m_strCmdLineArgCommandFileNamePath = strArg;
+ m_bHaveCommandFileNamePathOnCmdLine = true;
+ i--; // skip '-s' on the next loop
+ continue;
+ }
+ // Else, must be the executable
bHaveExecutableFileNamePath = true;
- m_strCmdLineArgExecuteableFileNamePath = argFile.GetFileNamePath(strArg);
+ m_strCmdLineArgExecuteableFileNamePath = strArg;
m_bHaveExecutableFileNamePathOnCmdLine = true;
}
- // This argument is also check for in CMIDriverMgr::ParseArgs()
- if (0 == strArg.compare("--executable")) // Used to specify that there is executable argument also on the command line
- { // See fn description.
+ // Report error if no command file was specified for the '-s' or '--source' options
+ else if (strArg.compare("-s") == 0 || strArg.compare("--source") == 0)
+ {
+ vwbExiting = true;
+ const CMIUtilString errMsg = CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF), strArg.c_str());
+ errStatus.SetErrorString(errMsg.c_str());
+ break;
+ }
+ // This argument is also checked for in CMIDriverMgr::ParseArgs()
+ else if (strArg.compare("--executable") == 0) // Used to specify that there is executable argument also on the command line
+ { // See fn description.
bHaveExecutableLongOption = true;
}
}
@@ -473,13 +450,7 @@ CMIDriver::ParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &v
if (bHaveExecutableFileNamePath && bHaveExecutableLongOption)
{
-// CODETAG_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
-#if MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
SetDriverDebuggingArgExecutable();
-#else
- vwbExiting = true;
- errStatus.SetErrorString(MIRSRC(IDS_DRIVER_ERR_LOCAL_DEBUG_NOT_IMPL));
-#endif // MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
}
return errStatus;
@@ -500,42 +471,6 @@ CMIDriver::GetDriverIsGDBMICompatibleDriver(void) const
}
//++ ------------------------------------------------------------------------------------
-// Details: Callback function for monitoring stream stdin object. Part of the visitor
-// pattern.
-// This function is called by the CMICmnStreamStdin::CThreadStdin
-// "stdin monitor" thread (ID).
-// Type: Overridden.
-// Args: vStdInBuffer - (R) Copy of the current stdin line data.
-// vrbYesExit - (RW) True = yes exit stdin monitoring, false = continue monitor.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMIDriver::ReadLine(const CMIUtilString &vStdInBuffer, bool &vrwbYesExit)
-{
- // For debugging. Update prompt show stdin is working
- // printf( "%s\n", vStdInBuffer.c_str() );
- // fflush( stdout );
-
- // Special case look for the quit command here so stop monitoring stdin stream
- // So we do not go back to fgetc() and wait and hang thread on exit
- if (vStdInBuffer == "quit")
- vrwbYesExit = true;
-
- // 1. Put new line in the queue container by stdin monitor thread
- // 2. Then *this driver calls ReadStdinLineQueue() when ready to read the queue in its
- // own thread
- const bool bOk = QueueMICommand(vStdInBuffer);
-
- // Check to see if the *this driver is shutting down (exit application)
- if (!vrwbYesExit)
- vrwbYesExit = m_bDriverIsExiting;
-
- return bOk;
-}
-
-//++ ------------------------------------------------------------------------------------
// Details: Start worker threads for the driver.
// Type: Method.
// Args: None.
@@ -551,16 +486,6 @@ CMIDriver::StartWorkerThreads(void)
// Grab the thread manager
CMICmnThreadMgrStd &rThreadMgr = CMICmnThreadMgrStd::Instance();
- // Start the stdin thread
- bOk &= m_rStdin.SetVisitor(*this);
- if (bOk && !rThreadMgr.ThreadStart<CMICmnStreamStdin>(m_rStdin))
- {
- const CMIUtilString errMsg = CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
- CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str());
- SetErrorDescriptionn(errMsg);
- return MIstatus::failure;
- }
-
// Start the event polling thread
if (bOk && !rThreadMgr.ThreadStart<CMICmnLLDBDebugger>(m_rLldbDebugger))
{
@@ -609,29 +534,53 @@ CMIDriver::DoMainLoop(void)
if (!StartWorkerThreads())
return MIstatus::failure;
- // App is not quitting currently
- m_bExitApp = false;
+ bool bOk = MIstatus::success;
-// CODETAG_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
-#if MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
if (HaveExecutableFileNamePathOnCmdLine())
{
- if (!LocalDebugSessionStartupInjectCommands())
+ if (!LocalDebugSessionStartupExecuteCommands())
{
SetErrorDescription(MIRSRC(IDS_MI_INIT_ERR_LOCAL_DEBUG_SESSION));
- return MIstatus::failure;
+ bOk = MIstatus::failure;
}
}
-#endif // MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION
+
+ // App is not quitting currently
+ m_bExitApp = false;
+
+ // Handle source file
+ if (m_bHaveCommandFileNamePathOnCmdLine)
+ {
+ const bool bAsyncMode = false;
+ ExecuteCommandFile(bAsyncMode);
+ }
// While the app is active
- while (!m_bExitApp)
+ while (bOk && !m_bExitApp)
{
- // Poll stdin queue and dispatch
- if (!ReadStdinLineQueue())
+ CMIUtilString errorText;
+ const char *pCmd = m_rStdin.ReadLine (errorText);
+ if (pCmd != nullptr)
{
- // Something went wrong
- break;
+ CMIUtilString lineText(pCmd);
+ if (!lineText.empty ())
+ {
+ // Check that the handler thread is alive (otherwise we stuck here)
+ assert(CMICmnLLDBDebugger::Instance().ThreadIsActive());
+
+ {
+ // Lock Mutex before processing commands so that we don't disturb an event
+ // being processed
+ CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
+ bOk = InterpretCommand(lineText);
+ }
+
+ // Draw prompt if desired
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
+
+ // Wait while the handler thread handles incoming events
+ CMICmnLLDBDebugger::Instance().WaitForHandleEvent();
+ }
}
}
@@ -648,72 +597,6 @@ CMIDriver::DoMainLoop(void)
}
//++ ------------------------------------------------------------------------------------
-// Details: *this driver sits and waits for input to the stdin line queue shared by *this
-// driver and the stdin monitor thread, it queues, *this reads, interprets and
-// reacts.
-// This function is used by the application's main thread.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMIDriver::ReadStdinLineQueue(void)
-{
- // True when queue contains input
- bool bHaveInput = false;
-
- // Stores the current input line
- CMIUtilString lineText;
- {
- // Lock while we access the queue
- CMIUtilThreadLock lock(m_threadMutex);
- if (!m_queueStdinLine.empty())
- {
- lineText = m_queueStdinLine.front();
- m_queueStdinLine.pop();
- bHaveInput = !lineText.empty();
- }
- }
-
- // Process while we have input
- if (bHaveInput)
- {
- if (lineText == "quit")
- {
- // We want to be exiting when receiving a quit command
- m_bExitApp = true;
- return MIstatus::success;
- }
-
- // Process the command
- bool bOk = false;
- {
- // Lock Mutex before processing commands so that we don't disturb an event
- // that is being processed.
- CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
- bOk = InterpretCommand(lineText);
- }
-
- // Draw prompt if desired
- if (bOk && m_rStdin.GetEnablePrompt())
- m_rStdOut.WriteMIResponse(m_rStdin.GetPrompt());
-
- // Input has been processed
- bHaveInput = false;
- }
- else
- {
- // Give resources back to the OS
- const std::chrono::milliseconds time(1);
- std::this_thread::sleep_for(time);
- }
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
// Details: Set things in motion, set state etc that brings *this driver (and the
// application) to a tidy shutdown.
// This function is used by the application's main thread.
@@ -766,8 +649,8 @@ CMIDriver::InterpretCommandFallThruDriver(const CMIUtilString &vTextLine, bool &
// errMsg = errMsg.StripCREndOfLine();
// errMsg = errMsg.StripCRAll();
// const CMIDriverBase * pOtherDriver = GetDriverToFallThruTo();
- // const MIchar * pName = pOtherDriver->GetDriverName().c_str();
- // const MIchar * pId = pOtherDriver->GetDriverId().c_str();
+ // const char * pName = pOtherDriver->GetDriverName().c_str();
+ // const char * pId = pOtherDriver->GetDriverId().c_str();
// const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_DRIVER_ERR_FALLTHRU_DRIVER_ERR ), pName, pId, errMsg.c_str() )
//);
// m_pLog->WriteMsg( msg );
@@ -926,42 +809,6 @@ CMIDriver::GetId(void) const
}
//++ ------------------------------------------------------------------------------------
-// Details: Inject a command into the command processing system to be interpreted as a
-// command read from stdin. The text representing the command is also written
-// out to stdout as the command did not come from via stdin.
-// Type: Method.
-// Args: vMICmd - (R) Text data representing a possible command.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMIDriver::InjectMICommand(const CMIUtilString &vMICmd)
-{
- const bool bOk = m_rStdOut.WriteMIResponse(vMICmd);
-
- return bOk && QueueMICommand(vMICmd);
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Add a new command candidate to the command queue to be processed by the
-// command system.
-// Type: Method.
-// Args: vMICmd - (R) Text data representing a possible command.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMIDriver::QueueMICommand(const CMIUtilString &vMICmd)
-{
- CMIUtilThreadLock lock(m_threadMutex);
- m_queueStdinLine.push(vMICmd);
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
// Details: Interpret the text data and match against current commands to see if there
// is a match. If a match then the command is issued and actioned on. The
// text data if not understood by *this driver is past on to the Fall Thru
@@ -976,15 +823,92 @@ CMIDriver::QueueMICommand(const CMIUtilString &vMICmd)
bool
CMIDriver::InterpretCommand(const CMIUtilString &vTextLine)
{
+ const bool bNeedToRebroadcastStopEvent = m_rLldbDebugger.CheckIfNeedToRebroadcastStopEvent();
bool bCmdYesValid = false;
bool bOk = InterpretCommandThisDriver(vTextLine, bCmdYesValid);
if (bOk && !bCmdYesValid)
bOk = InterpretCommandFallThruDriver(vTextLine, bCmdYesValid);
+ if (bNeedToRebroadcastStopEvent)
+ m_rLldbDebugger.RebroadcastStopEvent();
+
return bOk;
}
//++ ------------------------------------------------------------------------------------
+// Details: Helper function for CMIDriver::InterpretCommandThisDriver.
+// Convert a CLI command to MI command (just wrap any CLI command
+// into "<tokens>-interpreter-exec command \"<CLI command>\"").
+// Type: Method.
+// Args: vTextLine - (R) Text data representing a possible command.
+// Return: CMIUtilString - The original MI command or converted CLI command.
+// MIstatus::failure - Functional failed.
+// Throws: None.
+//--
+CMIUtilString
+CMIDriver::WrapCLICommandIntoMICommand(const CMIUtilString &vTextLine) const
+{
+ // Tokens contain following digits
+ static const CMIUtilString digits("0123456789");
+
+ // Consider an algorithm on the following example:
+ // 001-file-exec-and-symbols "/path/to/file"
+ //
+ // 1. Skip a command token
+ // For example:
+ // 001-file-exec-and-symbols "/path/to/file"
+ // 001target create "/path/to/file"
+ // ^ -- command starts here (in both cases)
+ // Also possible case when command not found:
+ // 001
+ // ^ -- i.e. only tokens are present (or empty string at all)
+ const size_t nCommandOffset = vTextLine.find_first_not_of(digits);
+
+ // 2. Check if command is empty
+ // For example:
+ // 001-file-exec-and-symbols "/path/to/file"
+ // 001target create "/path/to/file"
+ // ^ -- command not empty (in both cases)
+ // or:
+ // 001
+ // ^ -- command wasn't found
+ const bool bIsEmptyCommand = (nCommandOffset == CMIUtilString::npos);
+
+ // 3. Check and exit if it isn't a CLI command
+ // For example:
+ // 001-file-exec-and-symbols "/path/to/file"
+ // 001
+ // ^ -- it isn't CLI command (in both cases)
+ // or:
+ // 001target create "/path/to/file"
+ // ^ -- it's CLI command
+ const bool bIsCliCommand = !bIsEmptyCommand && (vTextLine.at(nCommandOffset) != '-');
+ if (!bIsCliCommand)
+ return vTextLine;
+
+ // 4. Wrap CLI command to make it MI-compatible
+ //
+ // 001target create "/path/to/file"
+ // ^^^ -- token
+ const std::string vToken(vTextLine.begin(), vTextLine.begin() + nCommandOffset);
+ // 001target create "/path/to/file"
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- CLI command
+ const CMIUtilString vCliCommand(std::string(vTextLine, nCommandOffset).c_str());
+
+ // 5. Escape special characters and embed the command in a string
+ // Result: it looks like -- target create \"/path/to/file\".
+ const std::string vShieldedCliCommand(vCliCommand.AddSlashes());
+
+ // 6. Turn the CLI command into an MI command, as in:
+ // 001-interpreter-exec command "target create \"/path/to/file\""
+ // ^^^ -- token
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ -- wrapper
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- shielded CLI command
+ return CMIUtilString::Format("%s-interpreter-exec command \"%s\"",
+ vToken.c_str(), vShieldedCliCommand.c_str());
+}
+
+//++ ------------------------------------------------------------------------------------
// Details: Interpret the text data and match against current commands to see if there
// is a match. If a match then the command is issued and actioned on. If a
// command cannot be found to match then vwbCmdYesValid is set to false and
@@ -992,7 +916,7 @@ CMIDriver::InterpretCommand(const CMIUtilString &vTextLine)
// This function is used by the application's main thread.
// Type: Method.
// Args: vTextLine - (R) Text data representing a possible command.
-// vwbCmdYesValid - (W) True = Command invalid, false = command acted on.
+// vwbCmdYesValid - (W) True = Command valid, false = command not handled.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
@@ -1000,12 +924,14 @@ CMIDriver::InterpretCommand(const CMIUtilString &vTextLine)
bool
CMIDriver::InterpretCommandThisDriver(const CMIUtilString &vTextLine, bool &vwbCmdYesValid)
{
- vwbCmdYesValid = false;
+ // Convert any CLI commands into MI commands
+ CMIUtilString vMITextLine(WrapCLICommandIntoMICommand(vTextLine));
+ vwbCmdYesValid = false;
bool bCmdNotInCmdFactor = false;
SMICmdData cmdData;
CMICmdMgr &rCmdMgr = CMICmdMgr::Instance();
- if (!rCmdMgr.CmdInterpret(vTextLine, vwbCmdYesValid, bCmdNotInCmdFactor, cmdData))
+ if (!rCmdMgr.CmdInterpret(vMITextLine, vwbCmdYesValid, bCmdNotInCmdFactor, cmdData))
return MIstatus::failure;
if (vwbCmdYesValid)
@@ -1018,13 +944,13 @@ CMIDriver::InterpretCommandThisDriver(const CMIUtilString &vTextLine, bool &vwbC
// Check for escape character, may be cursor control characters
// This code is not necessary for application operation, just want to keep tabs on what
- // is been given to the driver to try and intepret.
- if (vTextLine.at(0) == 27)
+ // has been given to the driver to try and interpret.
+ if (vMITextLine.at(0) == 27)
{
CMIUtilString logInput(MIRSRC(IDS_STDIN_INPUT_CTRL_CHARS));
- for (MIuint i = 0; i < vTextLine.length(); i++)
+ for (MIuint i = 0; i < vMITextLine.length(); i++)
{
- logInput += CMIUtilString::Format("%d ", vTextLine.at(i));
+ logInput += CMIUtilString::Format("%d ", vMITextLine.at(i));
}
m_pLog->WriteLog(logInput);
return MIstatus::success;
@@ -1037,14 +963,14 @@ CMIDriver::InterpretCommandThisDriver(const CMIUtilString &vTextLine, bool &vwbC
strNotInCmdFactory = CMIUtilString::Format(MIRSRC(IDS_DRIVER_CMD_NOT_IN_FACTORY), cmdData.strMiCmd.c_str());
const CMIUtilString strNot(CMIUtilString::Format("%s ", MIRSRC(IDS_WORD_NOT)));
const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDS_DRIVER_CMD_RECEIVED), vTextLine.c_str(), strNot.c_str(), strNotInCmdFactory.c_str()));
+ CMIUtilString::Format(MIRSRC(IDS_DRIVER_CMD_RECEIVED), vMITextLine.c_str(), strNot.c_str(), strNotInCmdFactory.c_str()));
const CMICmnMIValueConst vconst = CMICmnMIValueConst(msg);
const CMICmnMIValueResult valueResult("msg", vconst);
const CMICmnMIResultRecord miResultRecord(cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult);
- m_rStdOut.WriteMIResponse(miResultRecord.GetString());
+ const bool bOk = m_rStdOut.WriteMIResponse(miResultRecord.GetString());
// Proceed to wait for or execute next command
- return MIstatus::success;
+ return bOk;
}
//++ ------------------------------------------------------------------------------------
@@ -1082,7 +1008,6 @@ CMIDriver::SetExitApplicationFlag(const bool vbForceExit)
{
CMIUtilThreadLock lock(m_threadMutex);
m_bExitApp = true;
- m_rStdin.OnExitHandler();
return;
}
@@ -1092,12 +1017,11 @@ CMIDriver::SetExitApplicationFlag(const bool vbForceExit)
// but halt the inferior program being debugged instead
if (m_eCurrentDriverState == eDriverState_RunningDebugging)
{
- InjectMICommand("-exec-interrupt");
+ InterpretCommand("-exec-interrupt");
return;
}
m_bExitApp = true;
- m_rStdin.OnExitHandler();
}
//++ ------------------------------------------------------------------------------------
@@ -1252,9 +1176,7 @@ CMIDriver::InitClientIDEToMIDriver(void) const
bool
CMIDriver::InitClientIDEEclipse(void) const
{
- std::cout << "(gdb)" << std::endl;
-
- return MIstatus::success;
+ return CMICmnStreamStdout::WritePrompt();
}
//++ ------------------------------------------------------------------------------------
@@ -1299,11 +1221,13 @@ CMIDriver::GetExecutableFileNamePathOnCmdLine(void) const
// Throws: None.
//--
bool
-CMIDriver::LocalDebugSessionStartupInjectCommands(void)
+CMIDriver::LocalDebugSessionStartupExecuteCommands(void)
{
- const CMIUtilString strCmd(CMIUtilString::Format("-file-exec-and-symbols %s", m_strCmdLineArgExecuteableFileNamePath.c_str()));
-
- return InjectMICommand(strCmd);
+ const CMIUtilString strCmd(CMIUtilString::Format("-file-exec-and-symbols \"%s\"", m_strCmdLineArgExecuteableFileNamePath.AddSlashes().c_str()));
+ bool bOk = CMICmnStreamStdout::TextToStdout(strCmd);
+ bOk = bOk && InterpretCommand(strCmd);
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
+ return bOk;
}
//++ ------------------------------------------------------------------------------------
@@ -1334,3 +1258,86 @@ CMIDriver::IsDriverDebuggingArgExecutable(void) const
{
return m_bDriverDebuggingArgExecutable;
}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Execute commands from command source file in specified mode, and
+// set exit-flag if needed.
+// Type: Method.
+// Args: vbAsyncMode - (R) True = execute commands in asynchronous mode, false = otherwise.
+// Return: MIstatus::success - Function succeeded.
+// MIstatus::failure - Function failed.
+// Throws: None.
+//--
+bool
+CMIDriver::ExecuteCommandFile(const bool vbAsyncMode)
+{
+ std::ifstream ifsStartScript(m_strCmdLineArgCommandFileNamePath.c_str());
+ if (!ifsStartScript.is_open())
+ {
+ const CMIUtilString errMsg(
+ CMIUtilString::Format(MIRSRC(IDS_UTIL_FILE_ERR_OPENING_FILE_UNKNOWN), m_strCmdLineArgCommandFileNamePath.c_str()));
+ SetErrorDescription(errMsg.c_str());
+ const bool bForceExit = true;
+ SetExitApplicationFlag(bForceExit);
+ return MIstatus::failure;
+ }
+
+ // Switch lldb to synchronous mode
+ CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
+ const bool bAsyncSetting = rSessionInfo.GetDebugger().GetAsync();
+ rSessionInfo.GetDebugger().SetAsync(vbAsyncMode);
+
+ // Execute commands from file
+ bool bOk = MIstatus::success;
+ CMIUtilString strCommand;
+ while (!m_bExitApp && std::getline(ifsStartScript, strCommand))
+ {
+ // Print command
+ bOk = CMICmnStreamStdout::TextToStdout(strCommand);
+
+ // Skip if it's a comment or empty line
+ if (strCommand.empty() || strCommand[0] == '#')
+ continue;
+
+ // Execute if no error
+ if (bOk)
+ {
+ CMIUtilThreadLock lock(rSessionInfo.GetSessionMutex());
+ bOk = InterpretCommand(strCommand);
+ }
+
+ // Draw the prompt after command will be executed (if enabled)
+ bOk = bOk && CMICmnStreamStdout::WritePrompt();
+
+ // Exit if there is an error
+ if (!bOk)
+ {
+ const bool bForceExit = true;
+ SetExitApplicationFlag(bForceExit);
+ break;
+ }
+
+ // Wait while the handler thread handles incoming events
+ CMICmnLLDBDebugger::Instance().WaitForHandleEvent();
+ }
+
+ // Switch lldb back to initial mode
+ rSessionInfo.GetDebugger().SetAsync(bAsyncSetting);
+
+ return bOk;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Gets called when lldb-mi gets a signal. Stops the process if it was SIGINT.
+//
+// Type: Method.
+// Args: signal that was delivered
+// Return: None.
+// Throws: None.
+//--
+void
+CMIDriver::DeliverSignal(int signal)
+{
+ if (signal == SIGINT && (m_eCurrentDriverState == eDriverState_RunningDebugging))
+ InterpretCommand("-exec-interrupt");
+}
diff --git a/tools/lldb-mi/MIDriver.h b/tools/lldb-mi/MIDriver.h
index dafe1bedcf01..795549e0f4a0 100644
--- a/tools/lldb-mi/MIDriver.h
+++ b/tools/lldb-mi/MIDriver.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIDriver.h
-//
-// Overview: CMIDriver interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers
@@ -51,7 +39,6 @@ class CMICmnStreamStdout;
class CMIDriver : public CMICmnBase,
public CMIDriverMgr::IDriver,
public CMIDriverBase,
- public CMICmnStreamStdin::IStreamStdin,
public MI::ISingleton<CMIDriver>
{
friend class MI::ISingleton<CMIDriver>;
@@ -101,7 +88,6 @@ class CMIDriver : public CMICmnBase,
bool WriteMessageToLog(const CMIUtilString &vMessage);
bool SetEnableFallThru(const bool vbYes);
bool GetEnableFallThru(void) const;
- bool InjectMICommand(const CMIUtilString &vMICmd);
bool HaveExecutableFileNamePathOnCmdLine(void) const;
const CMIUtilString &GetExecutableFileNamePathOnCmdLine(void) const;
@@ -111,7 +97,6 @@ class CMIDriver : public CMICmnBase,
virtual bool DoInitialize(void);
virtual bool DoShutdown(void);
virtual bool DoMainLoop(void);
- virtual void DoResizeWindow(const uint32_t vWindowSizeWsCol);
virtual lldb::SBError DoParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting);
virtual CMIUtilString GetError(void) const;
virtual const CMIUtilString &GetName(void) const;
@@ -128,8 +113,7 @@ class CMIDriver : public CMICmnBase,
virtual FILE *GetStderr(void) const;
virtual const CMIUtilString &GetDriverName(void) const;
virtual const CMIUtilString &GetDriverId(void) const;
- // From CMICmnStreamStdin
- virtual bool ReadLine(const CMIUtilString &vStdInBuffer, bool &vrbYesExit);
+ virtual void DeliverSignal(int signal);
// Typedefs:
private:
@@ -142,18 +126,18 @@ class CMIDriver : public CMICmnBase,
void operator=(const CMIDriver &);
lldb::SBError ParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting);
- bool ReadStdinLineQueue(void);
bool DoAppQuit(void);
bool InterpretCommand(const CMIUtilString &vTextLine);
bool InterpretCommandThisDriver(const CMIUtilString &vTextLine, bool &vwbCmdYesValid);
+ CMIUtilString WrapCLICommandIntoMICommand(const CMIUtilString &vTextLine) const;
bool InterpretCommandFallThruDriver(const CMIUtilString &vTextLine, bool &vwbCmdYesValid);
bool ExecuteCommand(const SMICmdData &vCmdData);
bool StartWorkerThreads(void);
bool StopWorkerThreads(void);
bool InitClientIDEToMIDriver(void) const;
bool InitClientIDEEclipse(void) const;
- bool QueueMICommand(const CMIUtilString &vMICmd);
- bool LocalDebugSessionStartupInjectCommands(void);
+ bool LocalDebugSessionStartupExecuteCommands(void);
+ bool ExecuteCommandFile(const bool vbAsyncMode);
// Overridden:
private:
@@ -168,15 +152,16 @@ class CMIDriver : public CMICmnBase,
//
bool m_bFallThruToOtherDriverEnabled; // True = yes fall through, false = do not pass on command
CMIUtilThreadMutex m_threadMutex;
- QueueStdinLine_t m_queueStdinLine; // Producer = stdin monitor, consumer = *this driver
bool m_bDriverIsExiting; // True = yes, driver told to quit, false = continue working
void *m_handleMainThread; // *this driver is run by the main thread
CMICmnStreamStdin &m_rStdin;
CMICmnLLDBDebugger &m_rLldbDebugger;
CMICmnStreamStdout &m_rStdOut;
DriverState_e m_eCurrentDriverState;
- bool m_bHaveExecutableFileNamePathOnCmdLine; // True = Yes executable given as one of the parameters to the MI Driver, false = not found
+ bool m_bHaveExecutableFileNamePathOnCmdLine; // True = yes, executable given as one of the parameters to the MI Driver, false = not found
CMIUtilString m_strCmdLineArgExecuteableFileNamePath;
- bool m_bDriverDebuggingArgExecutable; // True = The MI Driver (MI mode) is debugging executable passed as argument, false = running via
- // a client i.e Eclipse
+ bool m_bDriverDebuggingArgExecutable; // True = the MI Driver (MI mode) is debugging executable passed as argument,
+ // false = running via a client (e.g. Eclipse)
+ bool m_bHaveCommandFileNamePathOnCmdLine; // True = file with initial commands given as one of the parameters to the MI Driver, false = not found
+ CMIUtilString m_strCmdLineArgCommandFileNamePath;
};
diff --git a/tools/lldb-mi/MIDriverBase.cpp b/tools/lldb-mi/MIDriverBase.cpp
index fd1a0eca5536..e03e7b0abee8 100644
--- a/tools/lldb-mi/MIDriverBase.cpp
+++ b/tools/lldb-mi/MIDriverBase.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIDriverBase.cpp
-//
-// Overview: CMIDriverBase implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third party headers:
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBBroadcaster.h"
diff --git a/tools/lldb-mi/MIDriverBase.h b/tools/lldb-mi/MIDriverBase.h
index 25ac23887282..ad242116b5f0 100644
--- a/tools/lldb-mi/MIDriverBase.h
+++ b/tools/lldb-mi/MIDriverBase.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIDriverBase.h
-//
-// Overview: CMIDriverBase interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
diff --git a/tools/lldb-mi/MIDriverMain.cpp b/tools/lldb-mi/MIDriverMain.cpp
index 5557799d3680..3b7588ba5df0 100644
--- a/tools/lldb-mi/MIDriverMain.cpp
+++ b/tools/lldb-mi/MIDriverMain.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIDriverMain.cpp
-//
// Overview: Defines the entry point for the console application.
// The MI application (project name MI) runs in two modes:
// An LLDB native driver mode where it acts no different from the LLDB driver.
@@ -23,25 +20,7 @@
// MICmdCommands.cpp
// MICmdBase.h / .cpp
// MICmdCmd.h / .cpp
-// Versions: 1.0.0.1 First version from scratch 28/1/2014 to 28/3/2014. MI not complete.
-// 1.0.0.2 First deliverable to client 7/3/2014. MI not complete.
-// 1.0.0.3 Code refactor tidy. Release to community for evaluation 17/5/2014. MI not complete.
-// 1.0.0.4 Post release to the community for evaluation 17/5/2014. MI not complete.
-// 1.0.0.5 Second deliverable to client 16/6/2014.
-// 1.0.0.6 Post release of second deliverable to client 16/6/2014.
-// Released to the community 24/6/2014.
-// 1.0.0.7 Post release to the community.
-// Delivered to client 30/6/2014.
-// 1.0.0.8 Delivered to client 29/7/2014.
-// 1.0.0.9 Post release to client 29/7/2014.
-// See MIreadme.txt for list of MI commands implemented.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadme.txt.
-//
-// Copyright: None.
-//--
+
#if defined(_MSC_VER)
#define _INC_SIGNAL // Stop window's signal.h being included - CODETAG_IOR_SIGNALS
@@ -54,51 +33,17 @@
// In house headers:
#include "MICmnConfig.h"
#include "Platform.h" // Define signals - CODETAG_IOR_SIGNALS
-#include "Driver.h"
#include "MIDriverMgr.h"
#include "MIDriver.h"
#include "MICmnResources.h"
#include "MICmnStreamStdin.h"
#include "MIUtilDebug.h"
-#include "MICmnLog.h"
-#if MICONFIG_COMPILE_MIDRIVER_VERSION
#if defined(_MSC_VER)
#pragma warning(once : 4530) // Warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
#endif // _MSC_VER
-// ToDo: Reevaluate if this function needs to be implemented like the UNIX equivalent
-// CODETAG_IOR_SIGNALS
-//++ ------------------------------------------------------------------------------------
-// Details: The SIGWINCH signal is sent to a process when its controlling terminal
-// changes its size (a window change).
-// Type: Function.
-// Args: vSigno - (R) Signal number.
-// Return: None.
-// Throws: None.
-//--
-void
-sigwinch_handler(int vSigno)
-{
-#ifdef _WIN32 // Restore handler as it is not persistent on Windows
- signal(SIGWINCH, sigwinch_handler);
-#endif
- MIunused(vSigno);
-
- struct winsize window_size;
- if (::isatty(STDIN_FILENO) && ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
- {
- CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
- if (window_size.ws_col > 0)
- {
- rDriverMgr.DriverResizeWindow((uint32_t)window_size.ws_col);
- }
- }
-
- CMICmnLog::Instance().WriteLog(CMIUtilString::Format(MIRSRC(IDS_PROCESS_SIGNAL_RECEIVED), "SIGWINCH", vSigno));
-}
-
// CODETAG_IOR_SIGNALS
//++ ------------------------------------------------------------------------------------
// Details: The SIGINT signal is sent to a process by its controlling terminal when a
@@ -130,74 +75,8 @@ sigint_handler(int vSigno)
}
}
- CMICmnLog::Instance().WriteLog(CMIUtilString::Format(MIRSRC(IDS_PROCESS_SIGNAL_RECEIVED), "SIGINT", vSigno));
-
- // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
- // Signal MI to shutdown or halt a running debug session
- CMICmnStreamStdin::Instance().SetCtrlCHit();
-}
-
-// ToDo: Reevaluate if this function needs to be implemented like the UNIX equivalent
-// CODETAG_IOR_SIGNALS
-//++ ------------------------------------------------------------------------------------
-// Details: The SIGTSTP signal is sent to a process by its controlling terminal to
-// request it to stop temporarily. It is commonly initiated by the user pressing
-// Control-Z. Unlike SIGSTOP, the process can register a signal handler for or
-// ignore the signal.
-// *** The function does not behave ATM like the UNIX equivalent ***
-// Type: Function.
-// Args: vSigno - (R) Signal number.
-// Return: None.
-// Throws: None.
-//--
-void
-sigtstp_handler(int vSigno)
-{
-#ifdef _WIN32 // Restore handler as it is not persistent on Windows
- signal(SIGTSTP, sigtstp_handler);
-#endif
- CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
- lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger();
- if (pDebugger != nullptr)
- {
- pDebugger->SaveInputTerminalState();
- }
-
- CMICmnLog::Instance().WriteLog(CMIUtilString::Format(MIRSRC(IDS_PROCESS_SIGNAL_RECEIVED), "SIGTSTP", vSigno));
-
- // Signal MI to shutdown
- CMICmnStreamStdin::Instance().SetCtrlCHit();
-}
-
-// ToDo: Reevaluate if this function needs to be implemented like the UNIX equivalent
-// CODETAG_IOR_SIGNALS
-//++ ------------------------------------------------------------------------------------
-// Details: The SIGCONT signal instructs the operating system to continue (restart) a
-// process previously paused by the SIGSTOP or SIGTSTP signal. One important use
-// of this signal is in job control in the UNIX shell.
-// *** The function does not behave ATM like the UNIX equivalent ***
-// Type: Function.
-// Args: vSigno - (R) Signal number.
-// Return: None.
-// Throws: None.
-//--
-void
-sigcont_handler(int vSigno)
-{
-#ifdef _WIN32 // Restore handler as it is not persistent on Windows
- signal(SIGCONT, sigcont_handler);
-#endif
- CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
- lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger();
- if (pDebugger != nullptr)
- {
- pDebugger->RestoreInputTerminalState();
- }
-
- CMICmnLog::Instance().WriteLog(CMIUtilString::Format(MIRSRC(IDS_PROCESS_SIGNAL_RECEIVED), "SIGCONT", vSigno));
-
- // Signal MI to shutdown
- CMICmnStreamStdin::Instance().SetCtrlCHit();
+ // Send signal to driver so that it can take suitable action
+ rDriverMgr.DeliverSignal (vSigno);
}
//++ ------------------------------------------------------------------------------------
@@ -213,13 +92,6 @@ bool
DriverSystemInit(void)
{
bool bOk = MIstatus::success;
-
-#if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
- Driver *pDriver = Driver::CreateSelf();
- if (pDriver == nullptr)
- return MIstatus::failure;
-#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
-
CMIDriver &rMIDriver = CMIDriver::Instance();
CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
bOk = rDriverMgr.Initialize();
@@ -248,66 +120,9 @@ DriverSystemShutdown(const bool vbAppExitOk)
// *** Order is important here ***
CMIDriverMgr::Instance().Shutdown();
-
-#if MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
- delete g_driver;
- g_driver = nullptr;
-#endif // MICONFIG_COMPILE_MIDRIVER_WITH_LLDBDRIVER
-
return bOk;
}
-#else
-void
-sigwinch_handler(int signo)
-{
- struct winsize window_size;
- if (isatty(STDIN_FILENO) && ::ioctl(STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
- {
- if ((window_size.ws_col > 0) && g_driver != NULL)
- {
- g_driver->ResizeWindow(window_size.ws_col);
- }
- }
-}
-
-void
-sigint_handler(int signo)
-{
- static bool g_interrupt_sent = false;
- if (g_driver)
- {
- if (!g_interrupt_sent)
- {
- g_interrupt_sent = true;
- g_driver->GetDebugger().DispatchInputInterrupt();
- g_interrupt_sent = false;
- return;
- }
- }
-
- exit(signo);
-}
-
-void
-sigtstp_handler(int signo)
-{
- g_driver->GetDebugger().SaveInputTerminalState();
- signal(signo, SIG_DFL);
- kill(getpid(), signo);
- signal(signo, sigtstp_handler);
-}
-
-void
-sigcont_handler(int signo)
-{
- g_driver->GetDebugger().RestoreInputTerminalState();
- signal(signo, SIG_DFL);
- kill(getpid(), signo);
- signal(signo, sigcont_handler);
-}
-#endif // #if MICONFIG_COMPILE_MIDRIVER_VERSION
-
//++ ------------------------------------------------------------------------------------
// Details: MI's application start point of execution. The applicaton runs in two modes.
// An LLDB native driver mode where it acts no different from the LLDB driver.
@@ -328,7 +143,6 @@ sigcont_handler(int signo)
// -1000 = Program failed did not initailize successfully.
// Throws: None.
//--
-#if MICONFIG_COMPILE_MIDRIVER_VERSION
int
main(int argc, char const *argv[])
{
@@ -349,11 +163,7 @@ main(int argc, char const *argv[])
}
// CODETAG_IOR_SIGNALS
- signal(SIGPIPE, SIG_IGN);
- signal(SIGWINCH, sigwinch_handler);
signal(SIGINT, sigint_handler);
- signal(SIGTSTP, sigtstp_handler);
- signal(SIGCONT, sigcont_handler);
bool bExiting = false;
CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
@@ -370,42 +180,3 @@ main(int argc, char const *argv[])
return appResult;
}
-#else // Operate the lldb Driver only version of the code
-int
-main(int argc, char const *argv[], char *envp[])
-{
- MIunused(envp);
- using namespace lldb;
- SBDebugger::Initialize();
-
- SBHostOS::ThreadCreated("<lldb.driver.main-thread>");
-
- signal(SIGPIPE, SIG_IGN);
- signal(SIGWINCH, sigwinch_handler);
- signal(SIGINT, sigint_handler);
- signal(SIGTSTP, sigtstp_handler);
- signal(SIGCONT, sigcont_handler);
-
- // Create a scope for driver so that the driver object will destroy itself
- // before SBDebugger::Terminate() is called.
- {
- Driver driver;
-
- bool exiting = false;
- SBError error(driver.ParseArgs(argc, argv, stdout, exiting));
- if (error.Fail())
- {
- const char *error_cstr = error.GetCString();
- if (error_cstr)
- ::fprintf(stderr, "error: %s\n", error_cstr);
- }
- else if (!exiting)
- {
- driver.MainLoop();
- }
- }
-
- SBDebugger::Terminate();
- return 0;
-}
-#endif // MICONFIG_COMPILE_MIDRIVER_VERSION
diff --git a/tools/lldb-mi/MIDriverMgr.cpp b/tools/lldb-mi/MIDriverMgr.cpp
index ca900ca6e885..f4987dba90bc 100644
--- a/tools/lldb-mi/MIDriverMgr.cpp
+++ b/tools/lldb-mi/MIDriverMgr.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIDriverMgr.cpp
-//
-// Overview: CMIDriverMgr implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third Party Headers:
#include "lldb/API/SBError.h"
@@ -28,7 +16,6 @@
#include "MICmnLog.h"
#include "MICmnLogMediumFile.h"
#include "MIDriver.h"
-#include "MIUtilTermios.h"
#include "MICmnStreamStdout.h"
#include "MIUtilSingletonHelper.h"
@@ -82,11 +69,6 @@ CMIDriverMgr::Initialize(void)
MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);
- if (bOk)
- {
- MIUtilTermios::StdinTermiosSet();
- }
-
m_bInitialized = bOk;
if (!bOk)
@@ -116,38 +98,11 @@ CMIDriverMgr::Shutdown(void)
// if( --m_clientUsageRefCnt > 0 )
// return MIstatus::success;
- bool vbAppExitOk = true;
-
ClrErrorDescription();
if (!m_bInitialized)
return MIstatus::success;
- if (vbAppExitOk)
- {
-#if _DEBUG
- CMICmnStreamStdout::Instance().Write(MIRSRC(IDE_MI_APP_EXIT_OK)); // Both stdout and Log
-#else
- CMICmnLog::WriteLog(MIRSRC(IDE_MI_APP_EXIT_OK)); // Just to the Log
-#endif // _DEBUG
- }
- else
- {
- CMICmnLog &rAppLog = CMICmnLog::Instance();
- if (rAppLog.GetEnabled())
- {
- const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDE_MI_APP_EXIT_WITH_PROBLEM), CMICmnLogMediumFile::Instance().GetFileName().c_str()));
- CMICmnStreamStdout::Instance().Write(msg);
- }
- else
- {
- const CMIUtilString msg(
- CMIUtilString::Format(MIRSRC(IDE_MI_APP_EXIT_WITH_PROBLEM_NO_LOG), CMICmnLogMediumFile::Instance().GetFileName().c_str()));
- CMICmnStreamStdout::Instance().Write(msg);
- }
- }
-
m_bInitialized = false;
bool bOk = MIstatus::success;
@@ -155,7 +110,6 @@ CMIDriverMgr::Shutdown(void)
// Tidy up
UnregisterDriverAll();
- MIUtilTermios::StdinTermiosReset();
// Note shutdown order is important here
MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
@@ -355,26 +309,6 @@ CMIDriverMgr::DriverMainLoop(void)
}
//++ ------------------------------------------------------------------------------------
-// Details: Call *this driver to resize the console window.
-// Type: Method.
-// Args: vWindowSizeWsCol - (R) New window column size.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-void
-CMIDriverMgr::DriverResizeWindow(const uint32_t vWindowSizeWsCol)
-{
- if (m_pDriverCurrent != nullptr)
- return m_pDriverCurrent->DoResizeWindow(vWindowSizeWsCol);
- else
- {
- const CMIUtilString errMsg(CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_CURRENT_NOT_SET)));
- CMICmnStreamStdout::Instance().Write(errMsg, true);
- }
-}
-
-//++ ------------------------------------------------------------------------------------
// Details: Get the current driver to validate executable command line arguments.
// Type: Method.
// Args: argc - (R) An integer that contains the count of arguments that follow in
@@ -403,7 +337,7 @@ CMIDriverMgr::DriverParseArgs(const int argc, const char *argv[], FILE *vpStdOut
if (!bOk)
{
CMIUtilString errMsg;
- const MIchar *pErrorCstr = error.GetCString();
+ const char *pErrorCstr = error.GetCString();
if (pErrorCstr != nullptr)
errMsg = CMIUtilString::Format(MIRSRC(IDS_DRIVER_ERR_PARSE_ARGS), m_pDriverCurrent->GetName().c_str(), pErrorCstr);
else
@@ -493,6 +427,7 @@ CMIDriverMgr::DriverGetTheDebugger(void)
// --versionLong
// --log
// --executable
+// --log-dir
// The above arguments are not handled by any driver object except for --executable.
// The options --interpreter and --executable in code act very similar. The
// --executable is necessary to differentiate whither the MI Driver is being using
@@ -501,8 +436,9 @@ CMIDriverMgr::DriverGetTheDebugger(void)
// executable if called from the command line. Using --executable tells the MI
// Driver is being called the command line and that the executable argument is indeed
// a specified executable an so actions commands to set up the executable for a
-// debug session. Using --interpreter on the commnd line does not action additional
-// commands to initialise a debug session and so be able to launch the process.
+// debug session. Using --interpreter on the command line does not action additional
+// commands to initialise a debug session and so be able to launch the process. The directory
+// where the log file is created is specified using --log-dir.
// Type: Method.
// Args: argc - (R) An integer that contains the count of arguments that follow in
// argv. The argc parameter is always greater than or equal to 1.
@@ -549,13 +485,11 @@ CMIDriverMgr::ParseArgs(const int argc, const char *argv[], bool &vwbExiting)
bool bHaveArgVersion = false;
bool bHaveArgVersionLong = false;
bool bHaveArgLog = false;
+ bool bHaveArgLogDir = false;
bool bHaveArgHelp = false;
+ CMIUtilString strLogDir;
-// Hardcode the use of the MI driver
-#if MICONFIG_DEFAULT_TO_MI_DRIVER
bHaveArgInterpret = true;
-#endif // MICONFIG_DEFAULT_TO_MI_DRIVER
-
if (bHaveArgs)
{
// CODETAG_MIDRIVE_CMD_LINE_ARG_HANDLING
@@ -582,6 +516,11 @@ CMIDriverMgr::ParseArgs(const int argc, const char *argv[], bool &vwbExiting)
{
bHaveArgLog = true;
}
+ if (0 == strArg.compare(0,10,"--log-dir="))
+ {
+ strLogDir = strArg.substr(10, CMIUtilString::npos);
+ bHaveArgLogDir = true;
+ }
if ((0 == strArg.compare("--help")) || (0 == strArg.compare("-h")))
{
bHaveArgHelp = true;
@@ -594,7 +533,12 @@ CMIDriverMgr::ParseArgs(const int argc, const char *argv[], bool &vwbExiting)
CMICmnLog::Instance().SetEnabled(true);
}
- // Todo: Remove this output when MI is finished. It is temporary to persuade Ecllipse plugin to work.
+ if (bHaveArgLogDir)
+ {
+ bOk = bOk && CMICmnLogMediumFile::Instance().SetDirectory(strLogDir);
+ }
+
+ // Todo: Remove this output when MI is finished. It is temporary to persuade Eclipse plugin to work.
// Eclipse reads this literally and will not work unless it gets this exact version text.
// Handle --version option (ignore the --interpreter option if present)
if (bHaveArgVersion)
@@ -604,7 +548,7 @@ CMIDriverMgr::ParseArgs(const int argc, const char *argv[], bool &vwbExiting)
return bOk;
}
- // Todo: Make this the --version when the the above --version version is removed
+ // Todo: Make this the --version when the above --version version is removed
// Handle --versionlong option (ignore the --interpreter option if present)
if (bHaveArgVersionLong)
{
@@ -613,7 +557,7 @@ CMIDriverMgr::ParseArgs(const int argc, const char *argv[], bool &vwbExiting)
return bOk;
}
- // Both '--help' and '--intepreter' means give help for MI only. Without
+ // Both '--help' and '--interpreter' means give help for MI only. Without
// '--interpreter' help the LLDB driver is working and so help is for that.
if (bHaveArgHelp && bHaveArgInterpret)
{
@@ -623,7 +567,7 @@ CMIDriverMgr::ParseArgs(const int argc, const char *argv[], bool &vwbExiting)
}
// This makes the assumption that there is at least one MI compatible
- // driver registered and one LLDB driver registerd and the CMIDriver
+ // driver registered and one LLDB driver registered and the CMIDriver
// is the first one found.
// ToDo: Implement a better solution that handle any order, any number
// of drivers. Or this 'feature' may be removed if deemed not required.
@@ -682,8 +626,10 @@ CMIDriverMgr::GetHelpOnCmdLineArgOptions(void) const
MIRSRC(IDE_MI_APP_ARG_VERSION),
MIRSRC(IDE_MI_APP_ARG_VERSION_LONG),
MIRSRC(IDE_MI_APP_ARG_INTERPRETER),
+ MIRSRC(IDE_MI_APP_ARG_SOURCE),
MIRSRC(IDE_MI_APP_ARG_EXECUTEABLE),
CMIUtilString::Format(MIRSRC(IDE_MI_APP_ARG_APP_LOG), CMICmnLogMediumFile::Instance().GetFileName().c_str()),
+ MIRSRC(IDE_MI_APP_ARG_APP_LOG_DIR),
MIRSRC(IDE_MI_APP_ARG_EXECUTABLE),
MIRSRC(IDS_CMD_QUIT_HELP),
MIRSRC(IDE_MI_APP_ARG_EXAMPLE)};
@@ -778,3 +724,19 @@ CMIDriverMgr::GetDriver(const CMIUtilString &vrDriverId) const
return pDriver;
}
+
+
+//++ ------------------------------------------------------------------------------------
+// Details: Gets called when lldb-mi gets a signal. Passed signal to current driver.
+//
+// Type: Method.
+// Args: signal that was delivered
+// Return: None.
+// Throws: None.
+//--
+void
+CMIDriverMgr::DeliverSignal(int signal)
+{
+ if (m_pDriverCurrent != nullptr)
+ m_pDriverCurrent->DeliverSignal(signal);
+}
diff --git a/tools/lldb-mi/MIDriverMgr.h b/tools/lldb-mi/MIDriverMgr.h
index 9e1e121405cb..53fc984f3178 100644
--- a/tools/lldb-mi/MIDriverMgr.h
+++ b/tools/lldb-mi/MIDriverMgr.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIDriverMgr.h
-//
-// Overview: CMIImplCmn interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadme.txt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
@@ -71,7 +59,6 @@ class CMIDriverMgr : public CMICmnBase, public MI::ISingleton<CMIDriverMgr>
virtual bool DoInitialize(void) = 0;
virtual bool DoShutdown(void) = 0;
virtual bool DoMainLoop(void) = 0;
- virtual void DoResizeWindow(const uint32_t vWindowSizeWsCol) = 0;
virtual lldb::SBError DoParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting) = 0;
virtual CMIUtilString GetError(void) const = 0;
virtual const CMIUtilString &GetName(void) const = 0;
@@ -79,6 +66,7 @@ class CMIDriverMgr : public CMICmnBase, public MI::ISingleton<CMIDriverMgr>
virtual bool GetDriverIsGDBMICompatibleDriver(void) const = 0;
virtual bool SetId(const CMIUtilString &vId) = 0;
virtual const CMIUtilString &GetId(void) const = 0;
+ virtual void DeliverSignal(int signal) = 0;
// Not part of the interface, ignore
/* dtor */ virtual ~IDriver(void) {}
@@ -101,11 +89,11 @@ class CMIDriverMgr : public CMICmnBase, public MI::ISingleton<CMIDriverMgr>
//
// MI Proxy fn to current specified working driver
bool DriverMainLoop(void);
- void DriverResizeWindow(const uint32_t vWindowSizeWsCol);
bool DriverParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting);
CMIUtilString DriverGetError(void) const;
CMIUtilString DriverGetName(void) const;
lldb::SBDebugger *DriverGetTheDebugger(void);
+ void DeliverSignal(int signal);
// Typedef:
private:
diff --git a/tools/lldb-mi/MIExtensions.txt b/tools/lldb-mi/MIExtensions.txt
new file mode 100644
index 000000000000..966cb2f074c9
--- /dev/null
+++ b/tools/lldb-mi/MIExtensions.txt
@@ -0,0 +1,103 @@
+# -file-exec-and-symbols now takes two new (optional) options:
+
+Synopsis
+
+ -file-exec-and-symbols <file> [-p <platform>] [-r <remote-file>]
+
+Specify the executable file to be debugged. This file is the one from which the symbol table is also read.
+When debugging remote targets specify a remote-file for execution and a file from which symbols are read.
+The optional platform is the name of the platform, e.g., "remote-ios" or "ios-simulator". The remote-file
+is the on-device path to the exe.
+
+# -data-info-line
+
+Synopsis
+
+ -data-info-line *<address>
+ -data-info-line <file>:<line>
+
+Provides information about a source line. The input can be <address> like 0x12345678 or <file>:<line>
+where file is a name of source file and line is the line number. As a result the command returns the following
+fields:
+ start - address of the first instruction which refers to that source line
+ end - address of the last instruction which refers to that source line
+ file - the file name
+ line - the line number
+The last two fields are useful in case you have specified a source line using its address.
+
+Example:
+ -data-info-line *0x100000f80
+ ^done,start="0x0000000100000f80",end="0x0000000100000f94",file="/Users/IliaK/p/hello.cpp",line="15"
+
+ -data-info-line hello.cpp:15
+ ^done,start="0x0000000100000f80",end="0x0000000100000f94",file="/Users/IliaK/p/hello.cpp",line="15"
+
+# -data-read-memory-bytes
+
+Synopsis
+
+ -data-read-memory-bytes [--thread <thread-id>] [--frame <frame-index>] [-o <byte-offset>] <address> <count>
+
+Where:
+
+ `address`
+ An expression specifying the start of the memory range to read.
+ `count`
+ Number of bytes to read.
+ `byte-offset`
+ Relative offset in bytes from `address` where reading should start.
+ `thread-id`
+ Integer identifier of the thread within which the expression should be evaluated,
+ if this option is omitted the currently selected thread will be used.
+ This option is not in the MI specification but is implemented by GDB.
+ `frame-index`
+ Index of the frame within which the expression should be evaluated,
+ if this option is omitted the currently selected frame will be used.
+ This option is not in the MI specification but is implemented by GDB.
+
+Reads a block of memory from the specified range.
+
+Note that currently this command works in an all-or-nothing fashion where it either reads the entire
+block of memory successfully and returns it as a single block, or it returns an error. This doesn't
+quite match up with the MI specification that says that subsets of the specified range may be
+returned as individual blocks if only some of the memory within the specified range is accessible.
+
+The result record for this command may contain one or more tuples representing the blocks of memory
+that were read, where each tuple has the following fields:
+
+ `begin`
+ The start of the address range for this block (in hex notation).
+ `end`
+ The end of the address range for this block (in hex notation).
+ `offset`
+ Offset of this block from `address` (that was passed in as an argument).
+ `contents`
+ The actual data in this block (in hex notation).
+
+Example:
+
+ (gdb)
+ -data-read-memory-bytes &array 4
+ ^done,memory=[{begin="0x00007fffffffeccc",offset="0x0000000000000000",end="0x00007fffffffecd0",contents="01020304"}]
+ (gdb)
+
+# =library-loaded notification
+
+The =library-loaded notification has 3 extra fields:
+ symbols-loaded - indicates that there are symbols for the loaded library
+ symbols-path - if symbols are exist then it contains a path for symbols of the loaded library
+ loaded_addr - contains an address of the loaded library or "-" if address isn't resolved yet
+
+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.
diff --git a/tools/lldb-mi/MIReadMe.txt b/tools/lldb-mi/MIReadMe.txt
index 47d28e395ede..bc3d4a8d5e5c 100644
--- a/tools/lldb-mi/MIReadMe.txt
+++ b/tools/lldb-mi/MIReadMe.txt
@@ -1,261 +1,37 @@
========================================================================
The MI Driver - LLDB Machine Interface V2 (MI) Project Overview
- 24/07/2014
========================================================================
The MI Driver is a stand alone executable that either be used via a
client i.e. Eclipse or directly from the command line.
-All the files in this directory are required to build the MI executable.
-The executable is intended to compile and work on the following platforms:
-
- Windows (Vista or newer) (Compiler: Visual C++ 12)
- LINUX (Compiler: gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1)
- OSX (Not tested)
-
-THe MI Driver has two modes of operation; LLDB and MI. The MI Driver (CMIDriver)
-which operates the MI mode is a driver in its own right to work alongside
-the LLDB driver (driver .h/.cpp). Only one is operatational at a time depending
-on the options entered on the command line. The MI Driver reads MI inputs and
-outputs MI responses to be interpreted by a client i.e. Eclipse.
-Should the MI Driver not understand an instruction it could be passed to the
-LLDB driver for interpretation (MI Driver build configuration dependant). Should
-the LLDB driver mode be chosen then it the MI Driver will behave as the normal
-LLDB driver.
-
For help information on using the MI driver type at the command line:
lldb-mi --interpreter --help
-A blog about the MI Driver is available on CodePlay's website
-http://www.codeplay.com/portal/.
+A blog about the MI Driver is available on CodePlay's website. ALthough it may not be
+completely accurate after the recent changes in lldb-mi.
+http://www.codeplay.com/portal/lldb-mi-driver---part-1-introduction
-The MI Driver produces a MILog.txt file which records the actions of the MI
-Driver when in the MI mode only.
+In MI mode and invoked with --log option, lldb-mi generates lldb-mi-log.txt
+This file keeps a history of the MI Driver's activity for one session. It is
+used to aid the debugging of the MI Driver. It also gives warnings about
+command's which do not support certain argument or options.
Note any command or text sent to the MI Driver in MI mode that is not a command
-registered in the MI Driver's Command Factory will be rejected given an error.
-
-The MILogfile.txt keeps a history of the MI Driver's activity for one session
-only. It is used to aid the debugging of the MI Driver in MI mode only. As well
-as recorded commands that are recognised by the MI Driver it also gives warnings
-about command's which do not support certain argument or options.
+registered in the MI Driver's Command Factory will be rejected and an error messsage
+will be generated.
All the files prefix with MI are specifically for the MI driver code only.
-Non prefixed code is the original LLDB driver which has been left untouched
-as much as possible. This allows the LLDB driver code to develop
-independently and make future integration more straight forward.
-
-File MIDriverMain.cpp contains the executables main() function and some
-common global functions common to the two drivers.
+File MIDriverMain.cpp contains the executables main() function.
=========================================================================
Current limitations:
-1. Commands implemented likely not to have all their arguments supported
-2. The MI Driver has only been tested with Eclipse Juno with an in-house
- plugin
-3. Local target has been implemented but not tested
-4. The MI Driver has been designed primarily to work in a 'remote-target'
- mode only. The MI Driver does not currently except arguments beyond
- those described above.
-5. The MI Driver does not accept as arguments an executable to create a
- target instance.
-6. Not all MI commands have been implemented. See section MI Driver
- commands for those that have been fully or partially implemented (not
- indicated - see command class).
-7. Not necessarily a limitation but the MI Driver is used with Codeplay's
- own Eclipse plugin (not supplied) which has allowed more control over
- the interaction with the MI Driver between Eclipse.
-
-=========================================================================
-Versions:
-1.0.0.1 First version from scratch 28/1/2014 to 28/3/2014.
- MI working alpha. MI framework not complete.
-1.0.0.2 First deliverable to client 7/3/2014.
- MI working beta. MI framework not complete.
-1.0.0.3 Code refactor tidy. Release to community for evaluation
- 7/5/2014.
- MI working beta - code refactored and tidied. MI framework
- complete. Just missing commands (which may still require
- changes).
-1.0.0.4 Post release to community for evaluation 7/5/2014.
- 1. MI command token now optional
- 2. MI command token is now fixed length
- 3. New commands added see section "MI commands implemented are:"
- 4. Able to debug a local target as well as remote target
- 5. MI Driver now sends to the client "(gdb)" + '\n' on
- initialising
- 6. Improve coverage of parsing and fix command argument parsing
- 7. Fix bug with stdin thinking there was no input when there was which
- caused communication between the client and the MI Driver to halt
- due to internal buffering, we now keep track of it ourself.
- 8. Code comment fixes and additions. Code style fixes.
- 9. MI Driver now on receiving Ctrl-C (SIGINT) when the client pauses
- an inferior program does not quit but continues operating.
- 10.Fix commands "var-update", "var-evaluate-expression" to which did
- not send back information to correctly update arrays and structures.
- 11.Commands "Not implemented" are now not registered to the command
- factory except for GDB command "thread". Commands not registered
- with the command factory produce MI error message "...not in
- Command Factory". (Removed from command section in this readme.txt)
-1.0.0.5 Second deliverable to client 16/6/2014.
-1.0.0.6 Post release of second deliverable to client 16/6/2014.
- Released to the community 24/6/2014.
- 1. The MI Driver has a new option --noLog. If present the MI Driver
- does not output progress or status messages to it's log file.
- 2. Moved OS specific handling of the stdin stream to their own class
- implementations so any changes to one handler will not affect
- another OS's handler.
- 3. The session data/information map for sharing data between commands
- now uses a variant object which enables objects of different types
- to be stored instead of previously just text information.
- 4. Debug session var object create, update and retrieve efficiency
- improved by using a map type container.
- 5. Re-enable the MI Driver's command line option --interpreter (see
- --help). Up until now it was implementented but not enforced, it
- was always the MI Driver interpreter.
- 6. Re-enable the compilation of the original LLDB driver code into
- the MI Driver's code. See MICmnConfig.h for build configuration.
-1.0.0.7 Post release to community. Delivered to client 30/6/2014.
- 1. Fix MI Driver's output of "(gdb)" appearing when running in LLDB
- mode (no --interpreter argument)'
- 2. Fix command "interpret-exec" to allow commands to be entered
- directly in the IDE console.
-1.0.0.8 Post release to client. Delivered to client 29/07/2014
- 1. Fix command "break-insert" argument -f not accepting file paths
- as a string. Looked like the MI Driver was not accepting LINUX
- style file paths in the Windows version and vice versa.
- 2. Fix command "stack-list-arguments" handling only the current
- stack frame. Eclipse now shows variables for all frames.
- 3. Fix and improve MI response for sending back information on
- stack local variables, stack arguments and stack frame selection.
- 4. Fix recursive crash when asking to gather information on link
- lists.
- 5. Fix MI Driver's Log date and time field.
- 6. Fix MI response return from event 'StopReason' and 'Breakpoint-
- hit'.
- 7. Fix command "environment-cd" to handle paths with spaces in the
- path.
- 8. Fix not displaying backtrace (stack) variable information when
- choosing frames other than the current frame.
- 9. Fix command "data-evaluate-expression" to be able to handle
- valid SBValue objects but have no value object name. Fix same
- command to handle expressions surround by string format inserted
- quotes.
- 10.Fix command "break-insert" to handle file location that is
- surrounded by quotes.
- 11.For commands "var-create" and "data-evaluate-expression" improve
- variable type handling for quoted expressions.
- 12.Implement command "inferior-tty-set". It just responds with
- "^Done".
- 13.Improve the MI Driver's help description.
- 14.Fix file name paths that contained '.', '-' and '_' in the path
- as being treated as invalid.
- 15.Fix trying to interpret escapse character text as an errorous
- command.
-1.0.0.9 Post release to client.
-
-=========================================================================
-MI Driver Commands
-MI commands below are written to work for Eclipse Juno 7.4. If may be
-one are more commands required by other IDEs are missing or do not
-support all arguments or options. Additionally some commands may handle
-additional arguments or options not documented here
-https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Data-Manipulation.html#GDB_002fMI-Data-Manipulation.
-The implemented commands are:
-CMICmdCmdBreakAfter
-CMICmdCmdBreakCondition
-CMICmdCmdBreakDelete
-CMICmdCmdBreakDisable
-CMICmdCmdBreakEnable
-CMICmdCmdBreakInsert
-CMICmdCmdDataEvaluateExpression
-CMICmdCmdDataDisassemble
-CMICmdCmdDataListRegisterChanged
-CMICmdCmdDataListRegisterNames
-CMICmdCmdDataListRegisterValues
-CMICmdCmdDataReadMemory
-CMICmdCmdDataReadMemoryBytes
-CMICmdCmdDataWriteMemory
-CMICmdCmdEnablePrettyPrinting
-CMICmdCmdEnvironmentCd
-CMICmdCmdExecContinue
-CMICmdCmdExecFinish
-CMICmdCmdExecInterrupt
-CMICmdCmdExecNext
-CMICmdCmdExecNextInstruction
-CMICmdCmdExecRun
-CMICmdCmdExecStep
-CMICmdCmdExecStepInstruction
-CMICmdCmdFileExecAndSymbols
-CMICmdCmdGdbExit
-CMICmdCmdGdbInfo
-CMICmdCmdGdbSet
-CMICmdCmdGdbSet - solib-search-path option
-CMICmdCmdInferiorTtySet (not functionally implemented)
-CMICmdCmdInterpreterExec
-CMICmdCmdListThreadGroups
-CMICmdCmdSource
-CMICmdCmdStackInfoDepth
-CMICmdCmdStackListArguments
-CMICmdCmdStackListFrames
-CMICmdCmdStackListLocals
-CMICmdCmdSupportInfoMiCmdQuery
-CMICmdCmdSupportListFeatures
-CMICmdCmdTargetSelect
-CMICmdCmdThread
-CMICmdCmdThreadInfo
-CMICmdCmdTraceStatus (not functionally implemented)
-CMICmdCmdVarAssign
-CMICmdCmdVarCreate
-CMICmdCmdVarDelete
-CMICmdCmdVarEvaluateExpression
-CMICmdCmdVarInfoPathExpression
-CMICmdCmdVarListChildren
-CMICmdCmdVarSetFormat
-CMICmdCmdVarShowAttributes
-CMICmdCmdVarUpdate
+1. Not all commands and their options have been implemented. Please see
+the source code for details.
+2. LLDB-MI may have additinal arguments not used in GDB MI. Please see
+MIExtesnsions.txt
=========================================================================
The MI Driver build configuration:
-MICmnConfig.h defines various preprocessor build options i.e. enable
-LLDB driver fall through (Driver.h/.cpp) should MI Driver not recognise a
-command (option not fully implemented - may be removed in the future).
-
-=========================================================================
-Code standard, documentation and code style scope:
-The coding style and coding documentation scope covers all MI prefixed
-files and where MI code is implemented in the LLDB driver files. Should
-you wish to make improvements or fixes to the MI code (which is encouraged)
-please DO comment your code in the style already applied. The same applies
-to the coding style. Class names should also follow this lead and ideally
-should be one class per file (.h/.cpp). Class interface files (.h) should
-not contain any implementation code unless there is a performance issue or
-templated functions. You get the idea, look around the existing code and
-follow by example :)
-
-Where code comment or documentation is wrong or can be improved to help
-others then it is strongly encouraged you DO improve the documentation.
-
-=========================================================================
-MI Driver license:
-The MI Driver code is under the University of Illinois Open Source License
-agreement. Submitted by Codeplay Ltd UK.
-
-Source code found at: llvm/tools/lldb/tools/lldb-mi.
-
-=========================================================================
-The MI Driver uses the following libraries:
-Standard Template library
- Thread
- Containers
- String
- File
- Time
-LLDB public API
-OS specific
- OS error reporting windows
- OS error handling OSX (not implemented)
- OS error handling LINUX (not implemented)
-
-
+MICmnConfig.h defines various preprocessor build options.
diff --git a/tools/lldb-mi/MIUtilDateTimeStd.cpp b/tools/lldb-mi/MIUtilDateTimeStd.cpp
index bb9e238843e0..995441fb4dec 100644
--- a/tools/lldb-mi/MIUtilDateTimeStd.cpp
+++ b/tools/lldb-mi/MIUtilDateTimeStd.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilDateTimeStd.cpp
-//
-// Overview: CMIUtilDateTimeStd implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MIUtilDateTimeStd.h"
#include "MICmnResources.h"
@@ -83,3 +71,21 @@ CMIUtilDateTimeStd::GetTime(void)
return strTime;
}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Retrieve system local current date and time in yyyy-MM-dd--HH-mm-ss format for log file names.
+// Type: Method.
+// Args: None.
+// Return: CMIUtilString - Text description.
+// Throws: None.
+//--
+CMIUtilString
+CMIUtilDateTimeStd::GetDateTimeLogFilename(void)
+{
+ std::time(&m_rawTime);
+ const std::tm *pTi = std::localtime(&m_rawTime);
+ const CMIUtilString strTime(CMIUtilString::Format("%d%02d%02d%02d%02d%02d", pTi->tm_year + 1900, pTi->tm_mon,
+ pTi->tm_mday, pTi->tm_hour, pTi->tm_min, pTi->tm_sec));
+
+ return strTime;
+}
diff --git a/tools/lldb-mi/MIUtilDateTimeStd.h b/tools/lldb-mi/MIUtilDateTimeStd.h
index 1d9a1dac7dc6..4bc5e5815959 100644
--- a/tools/lldb-mi/MIUtilDateTimeStd.h
+++ b/tools/lldb-mi/MIUtilDateTimeStd.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilDateTimeStd.h
-//
-// Overview: CMIUtilDateTimeStd interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers
@@ -42,6 +30,7 @@ class CMIUtilDateTimeStd
CMIUtilString GetDate(void);
CMIUtilString GetTime(void);
+ CMIUtilString GetDateTimeLogFilename(void);
// Overrideable:
public:
@@ -51,5 +40,5 @@ class CMIUtilDateTimeStd
// Attributes:
private:
std::time_t m_rawTime;
- MIchar m_pScratch[16];
+ char m_pScratch[16];
};
diff --git a/tools/lldb-mi/MIUtilDebug.cpp b/tools/lldb-mi/MIUtilDebug.cpp
index c78506221b44..f7d461bfcd28 100644
--- a/tools/lldb-mi/MIUtilDebug.cpp
+++ b/tools/lldb-mi/MIUtilDebug.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilDebug.h
-//
-// Overview: Terminal setting termios functions.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third party headers:
#ifdef _WIN32
#include <Windows.h>
diff --git a/tools/lldb-mi/MIUtilDebug.h b/tools/lldb-mi/MIUtilDebug.h
index d643f73ba97e..b309c5dc2871 100644
--- a/tools/lldb-mi/MIUtilDebug.h
+++ b/tools/lldb-mi/MIUtilDebug.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilDebug.h
-//
-// Overview: CMIUtilDebug interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
#define MI_USE_DEBUG_TRACE_FN // Undefine to compile out fn trace code
diff --git a/tools/lldb-mi/MIUtilFileStd.cpp b/tools/lldb-mi/MIUtilFileStd.cpp
index dc5ea6cb32ff..a0fce65880c6 100644
--- a/tools/lldb-mi/MIUtilFileStd.cpp
+++ b/tools/lldb-mi/MIUtilFileStd.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilFileStd.cpp
-//
-// Overview: CMIUtilFileStd implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third party headers
#include <stdio.h>
#include <assert.h>
@@ -159,7 +147,7 @@ CMIUtilFileStd::Write(const CMIUtilString &vData)
// Throws: None.
//--
bool
-CMIUtilFileStd::Write(const MIchar *vpData, const MIuint vCharCnt)
+CMIUtilFileStd::Write(const char *vpData, const MIuint vCharCnt)
{
if (vCharCnt == 0)
return MIstatus::success;
@@ -266,11 +254,11 @@ CMIUtilFileStd::GetLineReturn(void) const
// Throws: None.
//--
CMIUtilString
-CMIUtilFileStd::StripOffFileName(const CMIUtilString &vDirectoryPath) const
+CMIUtilFileStd::StripOffFileName(const CMIUtilString &vDirectoryPath)
{
- const MIint nPos = vDirectoryPath.rfind('\\');
- MIint nPos2 = vDirectoryPath.rfind('/');
- if ((nPos == (MIint)std::string::npos) && (nPos2 == (MIint)std::string::npos))
+ const size_t nPos = vDirectoryPath.rfind('\\');
+ size_t nPos2 = vDirectoryPath.rfind('/');
+ if ((nPos == std::string::npos) && (nPos2 == std::string::npos))
return vDirectoryPath;
if (nPos > nPos2)
@@ -281,14 +269,14 @@ CMIUtilFileStd::StripOffFileName(const CMIUtilString &vDirectoryPath) const
}
//++ ------------------------------------------------------------------------------------
-// Details: Return either backslash or forward slash appropriate to the OS this applilcation
+// Details: Return either backslash or forward slash appropriate to the OS this application
// is running on.
// Type: Static method.
// Args: None.
-// Return: MIchar - '/' or '\' character.
+// Return: char - '/' or '\' character.
// Throws: None.
//--
-MIchar
+char
CMIUtilFileStd::GetSlash(void)
{
#if !defined(_MSC_VER)
diff --git a/tools/lldb-mi/MIUtilFileStd.h b/tools/lldb-mi/MIUtilFileStd.h
index 29537771265e..4b27d2f2faeb 100644
--- a/tools/lldb-mi/MIUtilFileStd.h
+++ b/tools/lldb-mi/MIUtilFileStd.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilFileStd.h
-//
-// Overview: CMIUtilFileStd interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// In-house headers:
@@ -35,7 +23,7 @@ class CMIUtilFileStd : public CMICmnBase
{
// Static:
public:
- static MIchar GetSlash(void);
+ static char GetSlash(void);
// Methods:
public:
@@ -43,12 +31,12 @@ class CMIUtilFileStd : public CMICmnBase
//
bool CreateWrite(const CMIUtilString &vFileNamePath, bool &vwrbNewCreated);
bool Write(const CMIUtilString &vData);
- bool Write(const MIchar *vpData, const MIuint vCharCnt);
+ bool Write(const char *vpData, const MIuint vCharCnt);
void Close(void);
bool IsOk(void) const;
bool IsFileExist(const CMIUtilString &vFileNamePath) const;
const CMIUtilString &GetLineReturn(void) const;
- CMIUtilString StripOffFileName(const CMIUtilString &vDirectoryPath) const;
+ static CMIUtilString StripOffFileName(const CMIUtilString &vDirectoryPath);
// Overridden:
public:
diff --git a/tools/lldb-mi/MIUtilMapIdToVariant.cpp b/tools/lldb-mi/MIUtilMapIdToVariant.cpp
index 413677268bed..debac2081b8b 100644
--- a/tools/lldb-mi/MIUtilMapIdToVariant.cpp
+++ b/tools/lldb-mi/MIUtilMapIdToVariant.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilMapIdToVariant.cpp
-//
-// Overview: CMIUtilMapIdToVariant implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// In-house headers:
#include "MIUtilMapIdToVariant.h"
diff --git a/tools/lldb-mi/MIUtilMapIdToVariant.h b/tools/lldb-mi/MIUtilMapIdToVariant.h
index 6a7765d6022c..1b9c6a102ef0 100644
--- a/tools/lldb-mi/MIUtilMapIdToVariant.h
+++ b/tools/lldb-mi/MIUtilMapIdToVariant.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilMapIdToVariant.h
-//
-// Overview: CMIUtilMapIdToVariant interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
diff --git a/tools/lldb-mi/MIUtilSingletonBase.h b/tools/lldb-mi/MIUtilSingletonBase.h
index 44ad6cd9972c..c6d7f55b159c 100644
--- a/tools/lldb-mi/MIUtilSingletonBase.h
+++ b/tools/lldb-mi/MIUtilSingletonBase.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilSingletonBase.h
-//
-// Overview: MI::ISingleton interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
namespace MI
diff --git a/tools/lldb-mi/MIUtilSingletonHelper.h b/tools/lldb-mi/MIUtilSingletonHelper.h
index a06a74296d03..5bd879e1aa9f 100644
--- a/tools/lldb-mi/MIUtilSingletonHelper.h
+++ b/tools/lldb-mi/MIUtilSingletonHelper.h
@@ -6,18 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilSingletonHelper.h
-//
-// Overview: Contains template functions to aid the initialisation and
-// shutdown of MI modules. MI modules (or components) can
-// use other MI modules to help them achieve their one task
-// (Modules only do one task).
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
diff --git a/tools/lldb-mi/MIUtilString.cpp b/tools/lldb-mi/MIUtilString.cpp
index 0464eadccbff..fc7717749da8 100644
--- a/tools/lldb-mi/MIUtilString.cpp
+++ b/tools/lldb-mi/MIUtilString.cpp
@@ -7,24 +7,13 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilString.h
-//
-// Overview: CMIUtilString implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
// Third party headers
-#include <memory> // std::unique_ptr
-#include <stdarg.h> // va_list, va_start, var_end
-#include <sstream> // std::stringstream
-#include <string.h> // for strcpy
-#include <limits.h> // for ULONG_MAX
+#include <inttypes.h> // for PRIx8
+#include <limits.h> // for ULONG_MAX
+#include <memory> // std::unique_ptr
+#include <sstream> // std::stringstream
+#include <stdarg.h> // va_list, va_start, var_end
+#include <string.h> // for strncmp
// In-house headers:
#include "MIUtilString.h"
@@ -48,7 +37,7 @@ CMIUtilString::CMIUtilString(void)
// Return: None.
// Throws: None.
//--
-CMIUtilString::CMIUtilString(const MIchar *vpData)
+CMIUtilString::CMIUtilString(const char *vpData)
: std::string(vpData)
{
}
@@ -60,19 +49,19 @@ CMIUtilString::CMIUtilString(const MIchar *vpData)
// Return: None.
// Throws: None.
//--
-CMIUtilString::CMIUtilString(const MIchar *const *vpData)
+CMIUtilString::CMIUtilString(const char *const *vpData)
: std::string((const char *)vpData)
{
}
//++ ------------------------------------------------------------------------------------
-// Details: CMIUtilString assigment operator.
+// Details: CMIUtilString assignment operator.
// Type: Method.
// Args: vpRhs - Pointer to UTF8 text data.
// Return: CMIUtilString & - *this string.
// Throws: None.
//--
-CMIUtilString &CMIUtilString::operator=(const MIchar *vpRhs)
+CMIUtilString &CMIUtilString::operator=(const char *vpRhs)
{
if (*this == vpRhs)
return *this;
@@ -86,7 +75,7 @@ CMIUtilString &CMIUtilString::operator=(const MIchar *vpRhs)
}
//++ ------------------------------------------------------------------------------------
-// Details: CMIUtilString assigment operator.
+// Details: CMIUtilString assignment operator.
// Type: Method.
// Args: vrRhs - The other string to copy from.
// Return: CMIUtilString & - *this string.
@@ -213,10 +202,10 @@ CMIUtilString::FormatValist(const CMIUtilString &vrFormating, va_list vArgs)
// Args: vData - (R) String data to be split up.
// vDelimiter - (R) Delimiter char or text.
// vwVecSplits - (W) Container of splits found in string data.
-// Return: MIuint - Number of splits found in the string data.
+// Return: size_t - Number of splits found in the string data.
// Throws: None.
//--
-MIuint
+size_t
CMIUtilString::Split(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const
{
vwVecSplits.clear();
@@ -224,40 +213,30 @@ CMIUtilString::Split(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits)
if (this->empty() || vDelimiter.empty())
return 0;
- MIint nPos = find(vDelimiter);
- if (nPos == (MIint)std::string::npos)
+ const size_t nLen(length());
+ size_t nOffset(0);
+ do
{
- vwVecSplits.push_back(*this);
- return 1;
- }
- const MIint strLen(length());
- if (nPos == strLen)
- {
- vwVecSplits.push_back(*this);
- return 1;
- }
+ // Find first occurrence which doesn't match to the delimiter
+ const size_t nSectionPos(FindFirstNot(vDelimiter, nOffset));
+ if (nSectionPos == std::string::npos)
+ break;
- MIuint nAdd1(1);
- if ((nPos > 0) && (substr(0, nPos) != vDelimiter))
- {
- nPos = 0;
- nAdd1 = 0;
- }
- MIint nPos2 = find(vDelimiter, nPos + 1);
- while (nPos2 != (MIint)std::string::npos)
- {
- const MIuint len(nPos2 - nPos - nAdd1);
- const std::string strSection(substr(nPos + nAdd1, len));
- if (strSection != vDelimiter)
- vwVecSplits.push_back(strSection.c_str());
- nPos += len + 1;
- nPos2 = find(vDelimiter, nPos + 1);
- nAdd1 = 0;
- }
- const std::string strSection(substr(nPos, strLen - nPos));
- if ((strSection.length() != 0) && (strSection != vDelimiter))
+ // Find next occurrence of the delimiter after section
+ size_t nNextDelimiterPos(FindFirst(vDelimiter, nSectionPos));
+ if (nNextDelimiterPos == std::string::npos)
+ nNextDelimiterPos = nLen;
+
+ // Extract string between delimiters
+ const size_t nSectionLen(nNextDelimiterPos - nSectionPos);
+ const std::string strSection(substr(nSectionPos, nSectionLen));
vwVecSplits.push_back(strSection.c_str());
+ // Next
+ nOffset = nNextDelimiterPos + 1;
+ }
+ while (nOffset < nLen);
+
return vwVecSplits.size();
}
@@ -265,17 +244,17 @@ CMIUtilString::Split(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits)
// Details: Splits string into array of strings using delimiter. However the string is
// also considered for text surrounded by quotes. Text with quotes including the
// delimiter is treated as a whole. If multiple delimiter are found in sequence
-// then they are not added to the list of splits. Quotes that are embedded in the
+// then they are not added to the list of splits. Quotes that are embedded in
// the string as string formatted quotes are ignored (proceeded by a '\\') i.e.
// "\"MI GDB local C++.cpp\":88".
// Type: Method.
// Args: vData - (R) String data to be split up.
// vDelimiter - (R) Delimiter char or text.
// vwVecSplits - (W) Container of splits found in string data.
-// Return: MIuint - Number of splits found in the string data.
+// Return: size_t - Number of splits found in the string data.
// Throws: None.
//--
-MIuint
+size_t
CMIUtilString::SplitConsiderQuotes(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const
{
vwVecSplits.clear();
@@ -283,85 +262,54 @@ CMIUtilString::SplitConsiderQuotes(const CMIUtilString &vDelimiter, VecString_t
if (this->empty() || vDelimiter.empty())
return 0;
- MIint nPos = find(vDelimiter);
- if (nPos == (MIint)std::string::npos)
+ const size_t nLen(length());
+ size_t nOffset(0);
+ do
{
- vwVecSplits.push_back(*this);
- return 1;
- }
- const MIint strLen(length());
- if (nPos == strLen)
- {
- vwVecSplits.push_back(*this);
- return 1;
- }
+ // Find first occurrence which doesn't match to the delimiter
+ const size_t nSectionPos(FindFirstNot(vDelimiter, nOffset));
+ if (nSectionPos == std::string::npos)
+ break;
- // Look for more quotes
- bool bHaveQuotes = false;
- const MIchar cBckSlash = '\\';
- const MIchar cQuote = '"';
- MIint nPosQ = find(cQuote);
- MIint nPosQ2 = (MIint)std::string::npos;
- if (nPosQ != (MIint)std::string::npos)
- {
- nPosQ2 = nPosQ + 1;
- while (nPosQ2 < strLen)
+ // Find next occurrence of the delimiter after (quoted) section
+ const bool bSkipQuotedText(true);
+ bool bUnmatchedQuote(false);
+ size_t nNextDelimiterPos(FindFirst(vDelimiter, bSkipQuotedText, bUnmatchedQuote, nSectionPos));
+ if (bUnmatchedQuote)
{
- nPosQ2 = find(cQuote, nPosQ2);
- if ((nPosQ2 == (MIint)std::string::npos) || (at(nPosQ2 - 1) != cBckSlash))
- break;
- nPosQ2++;
+ vwVecSplits.clear();
+ return 0;
}
- bHaveQuotes = (nPosQ2 != (MIint)std::string::npos);
- }
+ if (nNextDelimiterPos == std::string::npos)
+ nNextDelimiterPos = nLen;
- MIuint nAdd1(1);
- if ((nPos > 0) && (substr(0, nPos) != vDelimiter))
- {
- nPos = 0;
- nAdd1 = 0;
- }
- MIint nPos2 = find(vDelimiter, nPos + 1);
- while (nPos2 != (MIint)std::string::npos)
- {
- if (!bHaveQuotes || (bHaveQuotes && ((nPos2 > nPosQ2) || (nPos2 < nPosQ))))
- {
- // Extract text or quoted text
- const MIuint len(nPos2 - nPos - nAdd1);
- const std::string strSection(substr(nPos + nAdd1, len));
- if (strSection != vDelimiter)
- vwVecSplits.push_back(strSection.c_str());
- nPos += len + 1;
- nPos2 = find(vDelimiter, nPos + 1);
- nAdd1 = 0;
-
- if (bHaveQuotes && (nPos2 > nPosQ2))
- {
- // Reset, look for more quotes
- bHaveQuotes = false;
- nPosQ = find(cQuote, nPos);
- nPosQ2 = (MIint)std::string::npos;
- if (nPosQ != (MIint)std::string::npos)
- {
- nPosQ2 = find(cQuote, nPosQ + 1);
- bHaveQuotes = (nPosQ2 != (MIint)std::string::npos);
- }
- }
- }
- else
- {
- // Skip passed text in quotes
- nPos2 = find(vDelimiter, nPosQ2 + 1);
- }
- }
- const std::string strSection(substr(nPos, strLen - nPos));
- if ((strSection.length() != 0) && (strSection != vDelimiter))
+ // Extract string between delimiters
+ const size_t nSectionLen(nNextDelimiterPos - nSectionPos);
+ const std::string strSection(substr(nSectionPos, nSectionLen));
vwVecSplits.push_back(strSection.c_str());
+ // Next
+ nOffset = nNextDelimiterPos + 1;
+ }
+ while (nOffset < nLen);
+
return vwVecSplits.size();
}
//++ ------------------------------------------------------------------------------------
+// Details: Split string into lines using \n and return an array of strings.
+// Type: Method.
+// Args: vwVecSplits - (W) Container of splits found in string data.
+// Return: size_t - Number of splits found in the string data.
+// Throws: None.
+//--
+size_t
+CMIUtilString::SplitLines(VecString_t &vwVecSplits) const
+{
+ return Split("\n", vwVecSplits);
+}
+
+//++ ------------------------------------------------------------------------------------
// Details: Remove '\n' from the end of string if found. It does not alter
// *this string.
// Type: Method.
@@ -372,8 +320,8 @@ CMIUtilString::SplitConsiderQuotes(const CMIUtilString &vDelimiter, VecString_t
CMIUtilString
CMIUtilString::StripCREndOfLine(void) const
{
- const MIint nPos = rfind('\n');
- if (nPos == (MIint)std::string::npos)
+ const size_t nPos = rfind('\n');
+ if (nPos == std::string::npos)
return *this;
const CMIUtilString strNew(substr(0, nPos).c_str());
@@ -410,12 +358,12 @@ CMIUtilString::FindAndReplace(const CMIUtilString &vFind, const CMIUtilString &v
if (vFind.empty() || this->empty())
return *this;
- MIint nPos = find(vFind);
- if (nPos == (MIint)std::string::npos)
+ size_t nPos = find(vFind);
+ if (nPos == std::string::npos)
return *this;
CMIUtilString strNew(*this);
- while (nPos != (MIint)std::string::npos)
+ while (nPos != std::string::npos)
{
strNew.replace(nPos, vFind.length(), vReplaceWith);
nPos += vReplaceWith.length();
@@ -441,8 +389,30 @@ CMIUtilString::IsNumber(void) const
if ((at(0) == '-') && (length() == 1))
return false;
- const MIint nPos = find_first_not_of("-.0123456789");
- if (nPos != (MIint)std::string::npos)
+ const size_t nPos = find_first_not_of("-.0123456789");
+ if (nPos != std::string::npos)
+ return false;
+
+ return true;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Check if *this string is a hexadecimal number.
+// Type: Method.
+// Args: None.
+// Return: bool - True = yes number, false not a number.
+// Throws: None.
+//--
+bool
+CMIUtilString::IsHexadecimalNumber(void) const
+{
+ // Compare '0x..' prefix
+ if ((strncmp(c_str(), "0x", 2) != 0) && (strncmp(c_str(), "0X", 2) != 0))
+ return false;
+
+ // Skip '0x..' prefix
+ const size_t nPos = find_first_not_of("01234567890ABCDEFabcedf", 2);
+ if (nPos != std::string::npos)
return false;
return true;
@@ -452,7 +422,7 @@ CMIUtilString::IsNumber(void) const
// Details: Extract the number from the string. The number can be either a hexadecimal or
// natural number. It cannot contain other non-numeric characters.
// Type: Method.
-// Args: vwrNumber - (W) Number exracted from the string.
+// Args: vwrNumber - (W) Number extracted from the string.
// Return: bool - True = yes number, false not a number.
// Throws: None.
//--
@@ -478,7 +448,7 @@ CMIUtilString::ExtractNumber(MIint64 &vwrNumber) const
//++ ------------------------------------------------------------------------------------
// Details: Extract the number from the hexadecimal string..
// Type: Method.
-// Args: vwrNumber - (W) Number exracted from the string.
+// Args: vwrNumber - (W) Number extracted from the string.
// Return: bool - True = yes number, false not a number.
// Throws: None.
//--
@@ -487,16 +457,16 @@ CMIUtilString::ExtractNumberFromHexadecimal(MIint64 &vwrNumber) const
{
vwrNumber = 0;
- const MIint nPos = find_first_not_of("x01234567890ABCDEFabcedf");
- if (nPos != (MIint)std::string::npos)
+ const size_t nPos = find_first_not_of("xX01234567890ABCDEFabcedf");
+ if (nPos != std::string::npos)
return false;
- const MIint64 nNum = ::strtoul(this->c_str(), nullptr, 16);
- if (nNum != LONG_MAX)
- {
- vwrNumber = nNum;
- return true;
- }
+ errno = 0;
+ const MIuint64 nNum = ::strtoull(this->c_str(), nullptr, 16);
+ if (errno == ERANGE)
+ return false;
+
+ vwrNumber = static_cast<MIint64>(nNum);
return true;
}
@@ -505,21 +475,20 @@ CMIUtilString::ExtractNumberFromHexadecimal(MIint64 &vwrNumber) const
// Details: Determine if the text is all valid alpha numeric characters. Letters can be
// either upper or lower case.
// Type: Static method.
-// Args: vrText - (R) The text data to examine.
+// Args: vpText - (R) The text data to examine.
// Return: bool - True = yes all alpha, false = one or more chars is non alpha.
// Throws: None.
//--
bool
-CMIUtilString::IsAllValidAlphaAndNumeric(const MIchar &vrText)
+CMIUtilString::IsAllValidAlphaAndNumeric(const char *vpText)
{
- const MIuint len = ::strlen(&vrText);
+ const size_t len = ::strlen(vpText);
if (len == 0)
return false;
- MIchar *pPtr = const_cast<MIchar *>(&vrText);
- for (MIuint i = 0; i < len; i++, pPtr++)
+ for (size_t i = 0; i < len; i++, vpText++)
{
- const MIchar c = *pPtr;
+ const char c = *vpText;
if (::isalnum((int)c) == 0)
return false;
}
@@ -556,14 +525,14 @@ CMIUtilString
CMIUtilString::Trim(void) const
{
CMIUtilString strNew(*this);
- const MIchar *pWhiteSpace = " \t\n\v\f\r";
- const MIint nPos = find_last_not_of(pWhiteSpace);
- if (nPos != (MIint)std::string::npos)
+ const char *pWhiteSpace = " \t\n\v\f\r";
+ const size_t nPos = find_last_not_of(pWhiteSpace);
+ if (nPos != std::string::npos)
{
strNew = substr(0, nPos + 1).c_str();
}
- const MIint nPos2 = strNew.find_first_not_of(pWhiteSpace);
- if (nPos2 != (MIint)std::string::npos)
+ const size_t nPos2 = strNew.find_first_not_of(pWhiteSpace);
+ if (nPos2 != std::string::npos)
{
strNew = strNew.substr(nPos2).c_str();
}
@@ -579,10 +548,10 @@ CMIUtilString::Trim(void) const
// Throws: None.
//--
CMIUtilString
-CMIUtilString::Trim(const MIchar vChar) const
+CMIUtilString::Trim(const char vChar) const
{
CMIUtilString strNew(*this);
- const MIint nLen = strNew.length();
+ const size_t nLen = strNew.length();
if (nLen > 1)
{
if ((strNew[0] == vChar) && (strNew[nLen - 1] == vChar))
@@ -615,7 +584,7 @@ CMIUtilString::FormatBinary(const MIuint64 vnDecimal)
nNum = nNum >> 1;
nLen++;
}
- MIchar pN[nConstBits + 1];
+ char pN[nConstBits + 1];
MIuint j = 0;
for (i = nLen; i > 0; --i, j++)
{
@@ -637,7 +606,7 @@ CMIUtilString::FormatBinary(const MIuint64 vnDecimal)
// Throws: None.
//--
CMIUtilString
-CMIUtilString::RemoveRepeatedCharacters(const MIchar vChar)
+CMIUtilString::RemoveRepeatedCharacters(const char vChar)
{
return RemoveRepeatedCharacters(0, vChar);
}
@@ -648,22 +617,22 @@ CMIUtilString::RemoveRepeatedCharacters(const MIchar vChar)
// character.
// Type: Method.
// Args: vChar - (R) The character to search for and remove adjacent duplicates.
-// vnPos - (R) Character position in the string.
+// vnPos - Character position in the string.
// Return: CMIUtilString - New version of the string.
// Throws: None.
//--
CMIUtilString
-CMIUtilString::RemoveRepeatedCharacters(const MIint vnPos, const MIchar vChar)
+CMIUtilString::RemoveRepeatedCharacters(size_t vnPos, const char vChar)
{
- const MIchar cQuote = '"';
+ const char cQuote = '"';
// Look for first quote of two
- MIint nPos = find(cQuote, vnPos);
- if (nPos == (MIint)std::string::npos)
+ const size_t nPos = find(cQuote, vnPos);
+ if (nPos == std::string::npos)
return *this;
- const MIint nPosNext = nPos + 1;
- if (nPosNext > (MIint)length())
+ const size_t nPosNext = nPos + 1;
+ if (nPosNext > length())
return *this;
if (at(nPosNext) == cQuote)
@@ -685,14 +654,296 @@ CMIUtilString::RemoveRepeatedCharacters(const MIint vnPos, const MIchar vChar)
bool
CMIUtilString::IsQuoted(void) const
{
- const MIchar cQuote = '"';
+ const char cQuote = '"';
if (at(0) != cQuote)
return false;
- const MIint nLen = length();
+ const size_t nLen = length();
if ((nLen > 0) && (at(nLen - 1) != cQuote))
return false;
return true;
}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Find first occurrence in *this string which matches the pattern.
+// Type: Method.
+// Args: vrPattern - (R) The pattern to search for.
+// vnPos - The starting position at which to start searching. (Dflt = 0)
+// Return: size_t - The position of the first substring that match.
+// Throws: None.
+//--
+size_t
+CMIUtilString::FindFirst(const CMIUtilString &vrPattern, size_t vnPos /* = 0 */) const
+{
+ return find(vrPattern, vnPos);
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Find first occurrence in *this string which matches the pattern and isn't surrounded by quotes.
+// Type: Method.
+// Args: vrPattern - (R) The pattern to search for.
+// vbSkipQuotedText - (R) True = don't look at quoted text, false = otherwise.
+// vrwbNotFoundClosedQuote - (W) True = parsing error: unmatched quote, false = otherwise.
+// vnPos - Position of the first character in the string to be considered in the search. (Dflt = 0)
+// Return: size_t - The position of the first substring that matches and isn't quoted.
+// Throws: None.
+//--
+size_t
+CMIUtilString::FindFirst(const CMIUtilString &vrPattern, const bool vbSkipQuotedText, bool &vrwbNotFoundClosedQuote,
+ size_t vnPos /* = 0 */) const
+{
+ vrwbNotFoundClosedQuote = false;
+
+ if (!vbSkipQuotedText)
+ return FindFirst(vrPattern, vnPos);
+
+ const size_t nLen(length());
+
+ size_t nPos = vnPos;
+ do
+ {
+ const size_t nQuotePos(FindFirstQuote(nPos));
+ const size_t nPatternPos(FindFirst(vrPattern, nPos));
+ if (nQuotePos == std::string::npos)
+ return nPatternPos;
+
+ const size_t nQuoteClosedPos = FindFirstQuote(nQuotePos + 1);
+ if (nQuoteClosedPos == std::string::npos)
+ {
+ vrwbNotFoundClosedQuote = true;
+ return std::string::npos;
+ }
+
+ if ((nPatternPos == std::string::npos) || (nPatternPos < nQuotePos))
+ return nPatternPos;
+
+ nPos = nQuoteClosedPos + 1;
+ }
+ while (nPos < nLen);
+
+ return std::string::npos;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Find first occurrence in *this string which doesn't match the pattern.
+// Type: Method.
+// Args: vrPattern - (R) The pattern to search for.
+// vnPos - Position of the first character in the string to be considered in the search. (Dflt = 0)
+// Return: size_t - The position of the first character that doesn't match.
+// Throws: None.
+//--
+size_t
+CMIUtilString::FindFirstNot(const CMIUtilString &vrPattern, size_t vnPos /* = 0 */) const
+{
+ const size_t nLen(length());
+ const size_t nPatternLen(vrPattern.length());
+
+ size_t nPatternPos(vnPos);
+ do
+ {
+ const bool bMatchPattern(compare(nPatternPos, nPatternLen, vrPattern) == 0);
+ if (!bMatchPattern)
+ return nPatternPos;
+ nPatternPos += nPatternLen;
+ }
+ while (nPatternPos < nLen);
+
+ return std::string::npos;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Find first occurrence of not escaped quotation mark in *this string.
+// Type: Method.
+// Args: vnPos - Position of the first character in the string to be considered in the search.
+// Return: size_t - The position of the quotation mark.
+// Throws: None.
+//--
+size_t
+CMIUtilString::FindFirstQuote(size_t vnPos) const
+{
+ const char cBckSlash('\\');
+ const char cQuote('"');
+ const size_t nLen(length());
+
+ size_t nPos = vnPos;
+ do
+ {
+ const size_t nBckSlashPos(find(cBckSlash, nPos));
+ const size_t nQuotePos(find(cQuote, nPos));
+ if ((nBckSlashPos == std::string::npos) || (nQuotePos == std::string::npos))
+ return nQuotePos;
+
+ if (nQuotePos < nBckSlashPos)
+ return nQuotePos;
+
+ // Skip 2 characters: First is '\', second is that which is escaped by '\'
+ nPos = nBckSlashPos + 2;
+ }
+ while (nPos < nLen);
+
+ return std::string::npos;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Get escaped string from *this string.
+// Type: Method.
+// Args: None.
+// Return: CMIUtilString - The escaped version of the initial string.
+// Throws: None.
+//--
+CMIUtilString
+CMIUtilString::Escape(bool vbEscapeQuotes /* = false */) const
+{
+ const size_t nLen(length());
+ CMIUtilString strNew;
+ strNew.reserve(nLen);
+ for (size_t nIndex(0); nIndex < nLen; ++nIndex)
+ {
+ const char cUnescapedChar((*this)[nIndex]);
+ if (cUnescapedChar == '"' && vbEscapeQuotes)
+ strNew.append("\\\"");
+ else
+ strNew.append(ConvertToPrintableASCII((char)cUnescapedChar));
+ }
+ return strNew;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Get string with backslashes in front of double quote '"' and backslash '\\'
+// characters.
+// Type: Method.
+// Args: None.
+// Return: CMIUtilString - The wrapped version of the initial string.
+// Throws: None.
+//--
+CMIUtilString
+CMIUtilString::AddSlashes(void) const
+{
+ const char cBckSlash('\\');
+ const size_t nLen(length());
+ CMIUtilString strNew;
+ strNew.reserve(nLen);
+
+ size_t nOffset(0);
+ while (nOffset < nLen)
+ {
+ const size_t nUnescapedCharPos(find_first_of("\"\\", nOffset));
+ const bool bUnescapedCharNotFound(nUnescapedCharPos == std::string::npos);
+ if (bUnescapedCharNotFound)
+ {
+ const size_t nAppendAll(std::string::npos);
+ strNew.append(*this, nOffset, nAppendAll);
+ break;
+ }
+ const size_t nAppendLen(nUnescapedCharPos - nOffset);
+ strNew.append(*this, nOffset, nAppendLen);
+ strNew.push_back(cBckSlash);
+ const char cUnescapedChar((*this)[nUnescapedCharPos]);
+ strNew.push_back(cUnescapedChar);
+ nOffset = nUnescapedCharPos + 1;
+ }
+
+ return strNew;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Remove backslashes added by CMIUtilString::AddSlashes.
+// Type: Method.
+// Args: None.
+// Return: CMIUtilString - The initial version of wrapped string.
+// Throws: None.
+//--
+CMIUtilString
+CMIUtilString::StripSlashes(void) const
+{
+ const char cBckSlash('\\');
+ const size_t nLen(length());
+ CMIUtilString strNew;
+ strNew.reserve(nLen);
+
+ size_t nOffset(0);
+ while (nOffset < nLen)
+ {
+ const size_t nBckSlashPos(find(cBckSlash, nOffset));
+ const bool bBckSlashNotFound(nBckSlashPos == std::string::npos);
+ if (bBckSlashNotFound)
+ {
+ const size_t nAppendAll(std::string::npos);
+ strNew.append(*this, nOffset, nAppendAll);
+ break;
+ }
+ const size_t nAppendLen(nBckSlashPos - nOffset);
+ strNew.append(*this, nOffset, nAppendLen);
+ const bool bBckSlashIsLast(nBckSlashPos == nLen);
+ if (bBckSlashIsLast)
+ {
+ strNew.push_back(cBckSlash);
+ break;
+ }
+ const char cEscapedChar((*this)[nBckSlashPos + 1]);
+ const size_t nEscapedCharPos(std::string("\"\\").find(cEscapedChar));
+ const bool bEscapedCharNotFound(nEscapedCharPos == std::string::npos);
+ if (bEscapedCharNotFound)
+ strNew.push_back(cBckSlash);
+ strNew.push_back(cEscapedChar);
+ nOffset = nBckSlashPos + 2;
+ }
+
+ return strNew;
+}
+
+CMIUtilString
+CMIUtilString::ConvertToPrintableASCII(const char vChar)
+{
+ switch (vChar)
+ {
+ case '\a':
+ return "\\a";
+ case '\b':
+ return "\\b";
+ case '\t':
+ return "\\t";
+ case '\n':
+ return "\\n";
+ case '\v':
+ return "\\v";
+ case '\f':
+ return "\\f";
+ case '\r':
+ return "\\r";
+ case '\033':
+ return "\\e";
+ case '\\':
+ return "\\\\";
+ default:
+ if (::isprint(vChar))
+ return Format("%c", vChar);
+ else
+ return Format("\\x%02" PRIx8, vChar);
+ }
+}
+
+CMIUtilString
+CMIUtilString::ConvertToPrintableASCII(const char16_t vChar16)
+{
+ if (vChar16 == (char16_t)(char)vChar16 && ::isprint(vChar16))
+ // Convert char16_t to char (if possible)
+ return Format("%c", vChar16);
+ else
+ return Format("\\u%02" PRIx8 "%02" PRIx8,
+ (vChar16 >> 8) & 0xff, vChar16 & 0xff);
+}
+
+CMIUtilString
+CMIUtilString::ConvertToPrintableASCII(const char32_t vChar32)
+{
+ if (vChar32 == (char32_t)(char)vChar32 && ::isprint(vChar32))
+ // Convert char32_t to char (if possible)
+ return Format("%c", vChar32);
+ else
+ return Format("\\U%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8,
+ (vChar32 >> 24) & 0xff, (vChar32 >> 16) & 0xff,
+ (vChar32 >> 8) & 0xff, vChar32 & 0xff);
+}
diff --git a/tools/lldb-mi/MIUtilString.h b/tools/lldb-mi/MIUtilString.h
index 162dcbf68852..eac0746e7d0d 100644
--- a/tools/lldb-mi/MIUtilString.h
+++ b/tools/lldb-mi/MIUtilString.h
@@ -7,23 +7,12 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilString.h
-//
-// Overview: CMIUtilString interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
// Third party headers:
#include <string>
#include <vector>
+#include <cinttypes>
// In-house headers:
#include "MIDataTypes.h"
@@ -46,28 +35,40 @@ class CMIUtilString : public std::string
static CMIUtilString Format(const CMIUtilString vFormating, ...);
static CMIUtilString FormatBinary(const MIuint64 vnDecimal);
static CMIUtilString FormatValist(const CMIUtilString &vrFormating, va_list vArgs);
- static bool IsAllValidAlphaAndNumeric(const MIchar &vrText);
+ static bool IsAllValidAlphaAndNumeric(const char *vpText);
static bool Compare(const CMIUtilString &vrLhs, const CMIUtilString &vrRhs);
+ static CMIUtilString ConvertToPrintableASCII(const char vChar);
+ static CMIUtilString ConvertToPrintableASCII(const char16_t vChar16);
+ static CMIUtilString ConvertToPrintableASCII(const char32_t vChar32);
// Methods:
public:
/* ctor */ CMIUtilString(void);
- /* ctor */ CMIUtilString(const MIchar *vpData);
- /* ctor */ CMIUtilString(const MIchar *const *vpData);
+ /* ctor */ CMIUtilString(const char *vpData);
+ /* ctor */ CMIUtilString(const char *const *vpData);
//
bool ExtractNumber(MIint64 &vwrNumber) const;
CMIUtilString FindAndReplace(const CMIUtilString &vFind, const CMIUtilString &vReplaceWith) const;
bool IsNumber(void) const;
+ bool IsHexadecimalNumber(void) const;
bool IsQuoted(void) const;
- CMIUtilString RemoveRepeatedCharacters(const MIchar vChar);
- MIuint Split(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const;
- MIuint SplitConsiderQuotes(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const;
+ CMIUtilString RemoveRepeatedCharacters(const char vChar);
+ size_t Split(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const;
+ size_t SplitConsiderQuotes(const CMIUtilString &vDelimiter, VecString_t &vwVecSplits) const;
+ size_t SplitLines(VecString_t &vwVecSplits) const;
CMIUtilString StripCREndOfLine(void) const;
CMIUtilString StripCRAll(void) const;
CMIUtilString Trim(void) const;
- CMIUtilString Trim(const MIchar vChar) const;
+ CMIUtilString Trim(const char vChar) const;
+ size_t FindFirst(const CMIUtilString &vrPattern, size_t vnPos = 0) const;
+ size_t FindFirst(const CMIUtilString &vrPattern, bool vbSkipQuotedText, bool &vrwbNotFoundClosedQuote,
+ size_t vnPos = 0) const;
+ size_t FindFirstNot(const CMIUtilString &vrPattern, size_t vnPos = 0) const;
+ CMIUtilString Escape(bool vbEscapeQuotes = false) const;
+ CMIUtilString AddSlashes(void) const;
+ CMIUtilString StripSlashes(void) const;
//
- CMIUtilString &operator=(const MIchar *vpRhs);
+ CMIUtilString &operator=(const char *vpRhs);
CMIUtilString &operator=(const std::string &vrRhs);
// Overrideable:
@@ -81,5 +82,6 @@ class CMIUtilString : public std::string
// Methods:
private:
bool ExtractNumberFromHexadecimal(MIint64 &vwrNumber) const;
- CMIUtilString RemoveRepeatedCharacters(const MIint vnPos, const MIchar vChar);
+ CMIUtilString RemoveRepeatedCharacters(size_t vnPos, const char vChar);
+ size_t FindFirstQuote(size_t vnPos) const;
};
diff --git a/tools/lldb-mi/MIUtilSystemLinux.cpp b/tools/lldb-mi/MIUtilSystemLinux.cpp
index 8227302356c5..a4ae327657f7 100644
--- a/tools/lldb-mi/MIUtilSystemLinux.cpp
+++ b/tools/lldb-mi/MIUtilSystemLinux.cpp
@@ -7,19 +7,7 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilSystemLinux.cpp
-//
-// Overview: CMIUtilSystemLinux implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
-#if defined(__FreeBSD__) || defined(__linux__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__linux__)
// In-house headers:
#include "MIUtilSystemLinux.h"
diff --git a/tools/lldb-mi/MIUtilSystemLinux.h b/tools/lldb-mi/MIUtilSystemLinux.h
index 451b887e209a..975714bd6f47 100644
--- a/tools/lldb-mi/MIUtilSystemLinux.h
+++ b/tools/lldb-mi/MIUtilSystemLinux.h
@@ -7,21 +7,9 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: CMIUtilSystemLinux.h
-//
-// Overview: CMIUtilSystemLinux interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
-#if defined(__FreeBSD__) || defined(__linux__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__linux__)
// In-house headers:
#include "MIUtilString.h"
diff --git a/tools/lldb-mi/MIUtilSystemOsx.cpp b/tools/lldb-mi/MIUtilSystemOsx.cpp
index f095c6212eb4..1834651d40b0 100644
--- a/tools/lldb-mi/MIUtilSystemOsx.cpp
+++ b/tools/lldb-mi/MIUtilSystemOsx.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilSystemOsx.cpp
-//
-// Overview: CMIUtilSystemOsx implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#if defined(__APPLE__)
// In-house headers:
diff --git a/tools/lldb-mi/MIUtilSystemOsx.h b/tools/lldb-mi/MIUtilSystemOsx.h
index 182b0c950cd7..b30e258626bd 100644
--- a/tools/lldb-mi/MIUtilSystemOsx.h
+++ b/tools/lldb-mi/MIUtilSystemOsx.h
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: CMIUtilSystemOsx.h
-//
-// Overview: CMIUtilSystemOsx interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#pragma once
#if defined(__APPLE__)
diff --git a/tools/lldb-mi/MIUtilSystemWindows.cpp b/tools/lldb-mi/MIUtilSystemWindows.cpp
index f03fa225cd90..19c6e9eb979f 100644
--- a/tools/lldb-mi/MIUtilSystemWindows.cpp
+++ b/tools/lldb-mi/MIUtilSystemWindows.cpp
@@ -7,18 +7,6 @@
//
//===----------------------------------------------------------------------===//
-//++
-// File: MIUtilSystemWindows.cpp
-//
-// Overview: CMIUtilSystemWindows implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
#if defined(_MSC_VER)
// Third party headers
@@ -29,6 +17,7 @@
// In-house headers:
#include "MIUtilSystemWindows.h"
#include "MICmnResources.h"
+#include "MIUtilFileStd.h"
//++ ------------------------------------------------------------------------------------
// Details: CMIUtilSystemWindows constructor.
@@ -122,15 +111,13 @@ CMIUtilSystemWindows::GetExecutablesPath(CMIUtilString &vrwFileNamePath) const
bool bOk = MIstatus::success;
HMODULE hModule = ::GetModuleHandle(nullptr);
char pPath[MAX_PATH];
- const DWORD nLen = ::GetModuleFileName(hModule, &pPath[0], MAX_PATH);
- const CMIUtilString strLastErr(GetOSLastError());
- if ((nLen != 0) && (strLastErr == "Unknown OS error"))
- vrwFileNamePath = &pPath[0];
- else
+ if (!::GetModuleFileName(hModule, &pPath[0], MAX_PATH))
{
bOk = MIstatus::failure;
- vrwFileNamePath = strLastErr;
+ vrwFileNamePath = GetOSLastError();
}
+ else
+ vrwFileNamePath = &pPath[0];
return bOk;
}
@@ -147,7 +134,8 @@ CMIUtilSystemWindows::GetExecutablesPath(CMIUtilString &vrwFileNamePath) const
bool
CMIUtilSystemWindows::GetLogFilesPath(CMIUtilString &vrwFileNamePath) const
{
- return GetExecutablesPath(vrwFileNamePath);
+ vrwFileNamePath = CMIUtilString(".");
+ return MIstatus::success;
}
#endif // #if defined( _MSC_VER )
diff --git a/tools/lldb-mi/MIUtilSystemWindows.h b/tools/lldb-mi/MIUtilSystemWindows.h
index 59e2de02df53..696c2b286dfc 100644
--- a/tools/lldb-mi/MIUtilSystemWindows.h
+++ b/tools/lldb-mi/MIUtilSystemWindows.h
@@ -6,18 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilSystemWindows.h
-//
-// Overview: CMIUtilSystemWindows interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
#pragma once
#if defined(_MSC_VER)
diff --git a/tools/lldb-mi/MIUtilTermios.cpp b/tools/lldb-mi/MIUtilTermios.cpp
deleted file mode 100644
index fb71a67c8541..000000000000
--- a/tools/lldb-mi/MIUtilTermios.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-//===-- MIUtilTermios.cpp ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilTermios.cpp
-//
-// Overview: Terminal setting termios functions.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
-// Third party headers:
-#include <stdlib.h>
-
-// In-house headers:
-#include "MIUtilTermios.h"
-#include "Platform.h"
-
-namespace MIUtilTermios
-{
-// Instantiations:
-static bool g_bOldStdinTermiosIsValid = false; // True = yes valid, false = no valid
-static struct termios g_sOldStdinTermios;
-
-//++ ------------------------------------------------------------------------------------
-// Details: Reset the terminal settings. This function is added as an ::atexit handler
-// to make sure we clean up. See StdinTerminosSet().
-// Type: Global function.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void
-StdinTermiosReset(void)
-{
- if (g_bOldStdinTermiosIsValid)
- {
- g_bOldStdinTermiosIsValid = false;
- ::tcsetattr(STDIN_FILENO, TCSANOW, &g_sOldStdinTermios);
- }
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Set the terminal settings function. StdinTermiosReset() is called when to
-// reset to this to before and application exit.
-// Type: Global function.
-// Args: None.
-// Return: None.
-// Throws: None.
-//--
-void
-StdinTermiosSet(void)
-{
- if (::tcgetattr(STDIN_FILENO, &g_sOldStdinTermios) == 0)
- {
- g_bOldStdinTermiosIsValid = true;
- ::atexit(StdinTermiosReset);
- }
-}
-
-} // namespace MIUtilTermios
diff --git a/tools/lldb-mi/MIUtilTermios.h b/tools/lldb-mi/MIUtilTermios.h
deleted file mode 100644
index f1983d64f005..000000000000
--- a/tools/lldb-mi/MIUtilTermios.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===-- MIUtilTermios.h -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilTermios.h
-//
-// Overview: Terminal setting termios functions.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Copyright: None.
-//--
-
-#pragma once
-
-namespace MIUtilTermios
-{
-
-extern void StdinTermiosReset(void);
-extern void StdinTermiosSet(void);
-
-} // MIUtilTermios
diff --git a/tools/lldb-mi/MIUtilThreadBaseStd.cpp b/tools/lldb-mi/MIUtilThreadBaseStd.cpp
index 1cf04fa5b2ae..2dc6d3d28dde 100644
--- a/tools/lldb-mi/MIUtilThreadBaseStd.cpp
+++ b/tools/lldb-mi/MIUtilThreadBaseStd.cpp
@@ -6,18 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilThreadBaseStd.cpp
-//
-// Overview: CMIUtilThread implementation.
-// CMIUtilThreadActiveObjBase implementation.
-// CMIUtilThreadMutex implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
// Copyright: None.
//--
@@ -217,6 +205,8 @@ CMIUtilThreadActiveObjBase::ThreadManage(void)
// Execute the finish routine just before we die
// to give the object a chance to clean up
ThreadFinish();
+
+ m_thread.Finish();
}
//---------------------------------------------------------------------------------------
@@ -226,6 +216,7 @@ CMIUtilThreadActiveObjBase::ThreadManage(void)
//
CMIUtilThread::CMIUtilThread(void)
: m_pThread(nullptr)
+ , m_bIsActive(false)
{
}
@@ -278,12 +269,24 @@ CMIUtilThread::Join(void)
bool
CMIUtilThread::IsActive(void)
{
- // Lock while we access the thread pointer
+ // Lock while we access the thread status
+ CMIUtilThreadLock _lock(m_mutex);
+ return m_bIsActive;
+}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Finish this thread
+// Type: Method.
+// Args: None.
+// Return: None.
+// Throws: None.
+//--
+void
+CMIUtilThread::Finish(void)
+{
+ // Lock while we access the thread status
CMIUtilThreadLock _lock(m_mutex);
- if (m_pThread == nullptr)
- return false;
- else
- return true;
+ m_bIsActive = false;
}
//++ ------------------------------------------------------------------------------------
@@ -298,8 +301,12 @@ CMIUtilThread::IsActive(void)
bool
CMIUtilThread::Start(FnThreadProc vpFn, void *vpArg)
{
- // Create the std thread, which starts immediately
+ // Lock while we access the thread pointer and status
+ CMIUtilThreadLock _lock(m_mutex);
+
+ // Create the std thread, which starts immediately and update its status
m_pThread = new std::thread(vpFn, vpArg);
+ m_bIsActive = true;
// We expect to always be able to create one
assert(m_pThread != nullptr);
diff --git a/tools/lldb-mi/MIUtilThreadBaseStd.h b/tools/lldb-mi/MIUtilThreadBaseStd.h
index e3cf5083011d..504d8303de1d 100644
--- a/tools/lldb-mi/MIUtilThreadBaseStd.h
+++ b/tools/lldb-mi/MIUtilThreadBaseStd.h
@@ -6,18 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilThreadBaseStd.h
-//
-// Overview: CMIUtilThread interface.
-// CMIUtilThreadActiveObjBase interface.
-// CMIUtilThreadMutex interface.
-// CMIUtilThreadLock interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
//
// Copyright: None.
//--
@@ -87,6 +75,8 @@ class CMIUtilThread
Join(void); // Wait for this thread to stop
bool
IsActive(void); // Returns true if this thread is running
+ void
+ Finish(void); // Finish this thread
// Overrideable:
public:
@@ -96,6 +86,7 @@ class CMIUtilThread
private:
CMIUtilThreadMutex m_mutex;
std::thread *m_pThread;
+ bool m_bIsActive;
};
//++ ============================================================================
diff --git a/tools/lldb-mi/MIUtilVariant.cpp b/tools/lldb-mi/MIUtilVariant.cpp
index fcf1ca8868a9..dff8072aa105 100644
--- a/tools/lldb-mi/MIUtilVariant.cpp
+++ b/tools/lldb-mi/MIUtilVariant.cpp
@@ -6,18 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilVariant.cpp
-//
-// Overview: CMIUtilVariant implementation.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Gotchas: See CMIUtilVariant class description.
-//
// Copyright: None.
//--
diff --git a/tools/lldb-mi/MIUtilVariant.h b/tools/lldb-mi/MIUtilVariant.h
index aa1604ab6ff9..8e7ac7b8573a 100644
--- a/tools/lldb-mi/MIUtilVariant.h
+++ b/tools/lldb-mi/MIUtilVariant.h
@@ -6,18 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-
-//++
-// File: MIUtilVariant.h
-//
-// Overview: CMIUtilVariant interface.
-//
-// Environment: Compilers: Visual C++ 12.
-// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
-// Libraries: See MIReadmetxt.
-//
-// Gotchas: See CMIUtilVariant class description.
-//
// Copyright: None.
//--
diff --git a/tools/lldb-mi/Platform.cpp b/tools/lldb-mi/Platform.cpp
index 6ff998d2265f..7e2eabf51b42 100644
--- a/tools/lldb-mi/Platform.cpp
+++ b/tools/lldb-mi/Platform.cpp
@@ -23,65 +23,12 @@ BOOL WINAPI CtrlHandler(DWORD ctrlType)
{
if (_ctrlHandler != NULL)
{
- _ctrlHandler(0);
+ _ctrlHandler(SIGINT);
return TRUE;
}
return FALSE;
}
-int
-ioctl(int d, int request, ...)
-{
- switch (request)
- {
- // request the console windows size
- case (TIOCGWINSZ):
- {
- va_list vl;
- va_start(vl, request);
- // locate the window size structure on stack
- winsize *ws = va_arg(vl, winsize *);
- // get screen buffer information
- CONSOLE_SCREEN_BUFFER_INFO info;
- if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info) == TRUE)
- // fill in the columns
- ws->ws_col = info.dwMaximumWindowSize.X;
- va_end(vl);
- return 0;
- }
- break;
- default:
- assert(!"Not implemented!");
- }
- return -1;
-}
-
-int
-kill(pid_t pid, int sig)
-{
- // is the app trying to kill itself
- if (pid == getpid())
- exit(sig);
- //
- assert(!"Not implemented!");
- return -1;
-}
-
-int
-tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
-{
- assert(!"Not implemented!");
- return -1;
-}
-
-int
-tcgetattr(int fildes, struct termios *termios_p)
-{
- // assert( !"Not implemented!" );
- // error return value (0=success)
- return -1;
-}
-
sighandler_t
signal(int sig, sighandler_t sigFunc)
{
@@ -93,12 +40,6 @@ signal(int sig, sighandler_t sigFunc)
SetConsoleCtrlHandler(CtrlHandler, TRUE);
}
break;
- case (SIGPIPE):
- case (SIGWINCH):
- case (SIGTSTP):
- case (SIGCONT):
- // ignore these for now
- break;
default:
assert(!"Not implemented!");
}
diff --git a/tools/lldb-mi/Platform.h b/tools/lldb-mi/Platform.h
index 7c351310b255..093ceac0fb9d 100644
--- a/tools/lldb-mi/Platform.h
+++ b/tools/lldb-mi/Platform.h
@@ -89,6 +89,7 @@ extern sighandler_t signal(int sig, sighandler_t);
#else
#include <inttypes.h>
+#include <limits.h>
#include <getopt.h>
#include <libgen.h>
@@ -96,14 +97,7 @@ extern sighandler_t signal(int sig, sighandler_t);
#include <termios.h>
#include <unistd.h>
-#include <histedit.h>
#include <pthread.h>
#include <sys/time.h>
-#if defined(__FreeBSD__)
-#include <readline/readline.h>
-#else
-#include <editline/readline.h>
-#endif
-
#endif
diff --git a/tools/lldb-server/LLDBServerUtilities.cpp b/tools/lldb-server/LLDBServerUtilities.cpp
new file mode 100644
index 000000000000..8df4875e5d1d
--- /dev/null
+++ b/tools/lldb-server/LLDBServerUtilities.cpp
@@ -0,0 +1,67 @@
+//===-- LLDBServerUtilities.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LLDBServerUtilities.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Interpreter/Args.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+using namespace lldb;
+using namespace lldb_private::lldb_server;
+using namespace llvm;
+
+bool
+LLDBServerUtilities::SetupLogging(const std::string& log_file,
+ const StringRef& log_channels,
+ uint32_t log_options)
+{
+ lldb::StreamSP log_stream_sp;
+ if (log_file.empty())
+ {
+ log_stream_sp.reset(new StreamFile(stdout, false));
+ }
+ else
+ {
+ uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate |
+ File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
+ if (!(log_options & LLDB_LOG_OPTION_APPEND))
+ options |= File::eOpenOptionTruncate;
+
+ log_stream_sp.reset(new StreamFile(log_file.c_str(), options));
+ }
+
+ SmallVector<StringRef, 32> channel_array;
+ log_channels.split(channel_array, ":");
+ for (auto channel_with_categories : channel_array)
+ {
+ StreamString error_stream;
+ Args channel_then_categories(channel_with_categories);
+ std::string channel(channel_then_categories.GetArgumentAtIndex(0));
+ channel_then_categories.Shift (); // Shift off the channel
+
+ bool success = Log::EnableLogChannel(log_stream_sp,
+ log_options,
+ channel.c_str(),
+ channel_then_categories.GetConstArgumentVector(),
+ error_stream);
+ if (!success)
+ {
+ fprintf(stderr, "Unable to open log file '%s' for channel \"%s\"\n",
+ log_file.c_str(),
+ channel_with_categories.str().c_str());
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/tools/lldb-server/LLDBServerUtilities.h b/tools/lldb-server/LLDBServerUtilities.h
new file mode 100644
index 000000000000..cab892a5edc6
--- /dev/null
+++ b/tools/lldb-server/LLDBServerUtilities.h
@@ -0,0 +1,25 @@
+//===-- LLDBServerUtilities.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+
+#include <string>
+
+namespace lldb_private {
+namespace lldb_server {
+
+class LLDBServerUtilities
+{
+public:
+ static bool
+ SetupLogging(const std::string& log_file, const llvm::StringRef& log_channels, uint32_t log_options);
+};
+
+}
+}
diff --git a/tools/lldb-server/exports b/tools/lldb-server/exports
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/lldb-server/exports
diff --git a/tools/lldb-server/lldb-gdbserver.cpp b/tools/lldb-server/lldb-gdbserver.cpp
new file mode 100644
index 000000000000..a286e3df0de4
--- /dev/null
+++ b/tools/lldb-server/lldb-gdbserver.cpp
@@ -0,0 +1,698 @@
+//===-- lldb-gdbserver.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <errno.h>
+#include <getopt.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <signal.h>
+#include <unistd.h>
+#endif
+
+// C++ Includes
+
+// Other libraries and framework includes
+#include "llvm/ADT/StringRef.h"
+
+#include "lldb/Core/ConnectionMachPort.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Host/Pipe.h"
+#include "lldb/Host/Socket.h"
+#include "lldb/Host/StringConvert.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Target/Platform.h"
+#include "LLDBServerUtilities.h"
+#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h"
+#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
+
+#ifndef LLGS_PROGRAM_NAME
+#define LLGS_PROGRAM_NAME "lldb-server"
+#endif
+
+#ifndef LLGS_VERSION_STR
+#define LLGS_VERSION_STR "local_build"
+#endif
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::lldb_server;
+using namespace lldb_private::process_gdb_remote;
+
+// lldb-gdbserver state
+
+namespace
+{
+HostThread s_listen_thread;
+ std::unique_ptr<ConnectionFileDescriptor> s_listen_connection_up;
+ std::string s_listen_url;
+}
+
+//----------------------------------------------------------------------
+// option descriptors for getopt_long_only()
+//----------------------------------------------------------------------
+
+static int g_debug = 0;
+static int g_verbose = 0;
+
+static struct option g_long_options[] =
+{
+ { "debug", no_argument, &g_debug, 1 },
+ { "platform", required_argument, NULL, 'p' },
+ { "verbose", no_argument, &g_verbose, 1 },
+ { "log-file", required_argument, NULL, 'l' },
+ { "log-channels", required_argument, NULL, 'c' },
+ { "attach", required_argument, NULL, 'a' },
+ { "named-pipe", required_argument, NULL, 'N' },
+ { "pipe", required_argument, NULL, 'U' },
+ { "native-regs", no_argument, NULL, 'r' }, // Specify to use the native registers instead of the gdb defaults for the architecture. NOTE: this is a do-nothing arg as it's behavior is default now. FIXME remove call from lldb-platform.
+ { "reverse-connect", no_argument, NULL, 'R' }, // Specifies that llgs attaches to the client address:port rather than llgs listening for a connection from address on port.
+ { "setsid", no_argument, NULL, 'S' }, // Call setsid() to make llgs run in its own session.
+ { NULL, 0, NULL, 0 }
+};
+
+
+//----------------------------------------------------------------------
+// Watch for signals
+//----------------------------------------------------------------------
+static int g_sigpipe_received = 0;
+static int g_sighup_received_count = 0;
+
+#ifndef _WIN32
+
+static void
+signal_handler(int signo)
+{
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ fprintf (stderr, "lldb-server:%s received signal %d\n", __FUNCTION__, signo);
+ if (log)
+ log->Printf ("lldb-server:%s received signal %d", __FUNCTION__, signo);
+
+ switch (signo)
+ {
+ case SIGPIPE:
+ g_sigpipe_received = 1;
+ break;
+ case SIGHUP:
+ ++g_sighup_received_count;
+
+ // For now, swallow SIGHUP.
+ if (log)
+ log->Printf ("lldb-server:%s swallowing SIGHUP (receive count=%d)", __FUNCTION__, g_sighup_received_count);
+ signal (SIGHUP, signal_handler);
+ break;
+ }
+}
+#endif // #ifndef _WIN32
+
+static void
+display_usage (const char *progname, const char* subcommand)
+{
+ fprintf(stderr, "Usage:\n %s %s "
+ "[--log-file log-file-name] "
+ "[--log-channels log-channel-list] "
+ "[--platform platform_name] "
+ "[--setsid] "
+ "[--named-pipe named-pipe-path] "
+ "[--native-regs] "
+ "[--attach pid] "
+ "[[HOST]:PORT] "
+ "[-- PROGRAM ARG1 ARG2 ...]\n", progname, subcommand);
+ exit(0);
+}
+
+static void
+dump_available_platforms (FILE *output_file)
+{
+ fprintf (output_file, "Available platform plugins:\n");
+ for (int i = 0; ; ++i)
+ {
+ const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (i);
+ const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (i);
+
+ if (!plugin_name || !plugin_desc)
+ break;
+
+ fprintf (output_file, "%s\t%s\n", plugin_name, plugin_desc);
+ }
+
+ if ( Platform::GetHostPlatform () )
+ {
+ // add this since the default platform doesn't necessarily get registered by
+ // the plugin name (e.g. 'host' doesn't show up as a
+ // registered platform plugin even though it's the default).
+ fprintf (output_file, "%s\tDefault platform for this host.\n", Platform::GetHostPlatform ()->GetPluginName ().AsCString ());
+ }
+}
+
+static lldb::PlatformSP
+setup_platform (const std::string &platform_name)
+{
+ lldb::PlatformSP platform_sp;
+
+ if (platform_name.empty())
+ {
+ printf ("using the default platform: ");
+ platform_sp = Platform::GetHostPlatform ();
+ printf ("%s\n", platform_sp->GetPluginName ().AsCString ());
+ return platform_sp;
+ }
+
+ Error error;
+ platform_sp = Platform::Create (lldb_private::ConstString(platform_name), error);
+ if (error.Fail ())
+ {
+ // the host platform isn't registered with that name (at
+ // least, not always. Check if the given name matches
+ // the default platform name. If so, use it.
+ if ( Platform::GetHostPlatform () && ( Platform::GetHostPlatform ()->GetPluginName () == ConstString (platform_name.c_str()) ) )
+ {
+ platform_sp = Platform::GetHostPlatform ();
+ }
+ else
+ {
+ fprintf (stderr, "error: failed to create platform with name '%s'\n", platform_name.c_str());
+ dump_available_platforms (stderr);
+ exit (1);
+ }
+ }
+ printf ("using platform: %s\n", platform_name.c_str ());
+
+ return platform_sp;
+}
+
+void
+handle_attach_to_pid (GDBRemoteCommunicationServerLLGS &gdb_server, lldb::pid_t pid)
+{
+ Error error = gdb_server.AttachToProcess (pid);
+ if (error.Fail ())
+ {
+ fprintf (stderr, "error: failed to attach to pid %" PRIu64 ": %s\n", pid, error.AsCString());
+ exit(1);
+ }
+}
+
+void
+handle_attach_to_process_name (GDBRemoteCommunicationServerLLGS &gdb_server, const std::string &process_name)
+{
+ // FIXME implement.
+}
+
+void
+handle_attach (GDBRemoteCommunicationServerLLGS &gdb_server, const std::string &attach_target)
+{
+ assert (!attach_target.empty () && "attach_target cannot be empty");
+
+ // First check if the attach_target is convertible to a long. If so, we'll use it as a pid.
+ char *end_p = nullptr;
+ const long int pid = strtol (attach_target.c_str (), &end_p, 10);
+
+ // We'll call it a match if the entire argument is consumed.
+ if (end_p && static_cast<size_t> (end_p - attach_target.c_str ()) == attach_target.size ())
+ handle_attach_to_pid (gdb_server, static_cast<lldb::pid_t> (pid));
+ else
+ handle_attach_to_process_name (gdb_server, attach_target);
+}
+
+void
+handle_launch (GDBRemoteCommunicationServerLLGS &gdb_server, int argc, const char *const argv[])
+{
+ Error error;
+ error = gdb_server.SetLaunchArguments (argv, argc);
+ if (error.Fail ())
+ {
+ fprintf (stderr, "error: failed to set launch args for '%s': %s\n", argv[0], error.AsCString());
+ exit(1);
+ }
+
+ unsigned int launch_flags = eLaunchFlagStopAtEntry | eLaunchFlagDebug;
+
+ error = gdb_server.SetLaunchFlags (launch_flags);
+ if (error.Fail ())
+ {
+ fprintf (stderr, "error: failed to set launch flags for '%s': %s\n", argv[0], error.AsCString());
+ exit(1);
+ }
+
+ error = gdb_server.LaunchProcess ();
+ if (error.Fail ())
+ {
+ fprintf (stderr, "error: failed to launch '%s': %s\n", argv[0], error.AsCString());
+ exit(1);
+ }
+}
+
+static lldb::thread_result_t
+ListenThread (lldb::thread_arg_t /* arg */)
+{
+ Error error;
+
+ if (s_listen_connection_up)
+ {
+ // Do the listen on another thread so we can continue on...
+ if (s_listen_connection_up->Connect(s_listen_url.c_str(), &error) != eConnectionStatusSuccess)
+ s_listen_connection_up.reset();
+ }
+ return nullptr;
+}
+
+static Error
+StartListenThread (const char *hostname, uint16_t port)
+{
+ Error error;
+ if (s_listen_thread.IsJoinable())
+ {
+ error.SetErrorString("listen thread already running");
+ }
+ else
+ {
+ char listen_url[512];
+ if (hostname && hostname[0])
+ snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port);
+ else
+ snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
+
+ s_listen_url = listen_url;
+ s_listen_connection_up.reset (new ConnectionFileDescriptor ());
+ s_listen_thread = ThreadLauncher::LaunchThread(listen_url, ListenThread, nullptr, &error);
+ }
+ return error;
+}
+
+static bool
+JoinListenThread ()
+{
+ if (s_listen_thread.IsJoinable())
+ s_listen_thread.Join(nullptr);
+ return true;
+}
+
+Error
+WritePortToPipe(Pipe &port_pipe, const uint16_t port)
+{
+ char port_str[64];
+ const auto port_str_len = ::snprintf(port_str, sizeof(port_str), "%u", port);
+
+ size_t bytes_written = 0;
+ // Write the port number as a C string with the NULL terminator.
+ return port_pipe.Write(port_str, port_str_len + 1, bytes_written);
+}
+
+Error
+writePortToPipe(const char *const named_pipe_path, const uint16_t port)
+{
+ Pipe port_name_pipe;
+ // Wait for 10 seconds for pipe to be opened.
+ auto error = port_name_pipe.OpenAsWriterWithTimeout(named_pipe_path, false,
+ std::chrono::seconds{10});
+ if (error.Fail())
+ return error;
+ return WritePortToPipe(port_name_pipe, port);
+}
+
+Error
+writePortToPipe(int unnamed_pipe_fd, const uint16_t port)
+{
+#if defined(_WIN32)
+ return Error("Unnamed pipes are not supported on Windows.");
+#else
+ Pipe port_pipe{Pipe::kInvalidDescriptor, unnamed_pipe_fd};
+ return WritePortToPipe(port_pipe, port);
+#endif
+}
+
+void
+ConnectToRemote(GDBRemoteCommunicationServerLLGS &gdb_server,
+ bool reverse_connect, const char *const host_and_port,
+ const char *const progname, const char *const subcommand,
+ const char *const named_pipe_path, int unnamed_pipe_fd)
+{
+ Error error;
+
+ if (host_and_port && host_and_port[0])
+ {
+ // Parse out host and port.
+ std::string final_host_and_port;
+ std::string connection_host;
+ std::string connection_port;
+ uint32_t connection_portno = 0;
+
+ // If host_and_port starts with ':', default the host to be "localhost" and expect the remainder to be the port.
+ if (host_and_port[0] == ':')
+ final_host_and_port.append ("localhost");
+ final_host_and_port.append (host_and_port);
+
+ const std::string::size_type colon_pos = final_host_and_port.find (':');
+ if (colon_pos != std::string::npos)
+ {
+ connection_host = final_host_and_port.substr (0, colon_pos);
+ connection_port = final_host_and_port.substr (colon_pos + 1);
+ connection_portno = StringConvert::ToUInt32 (connection_port.c_str (), 0);
+ }
+ else
+ {
+ fprintf (stderr, "failed to parse host and port from connection string '%s'\n", final_host_and_port.c_str ());
+ display_usage (progname, subcommand);
+ exit (1);
+ }
+
+ if (reverse_connect)
+ {
+ // llgs will connect to the gdb-remote client.
+
+ // Ensure we have a port number for the connection.
+ if (connection_portno == 0)
+ {
+ fprintf (stderr, "error: port number must be specified on when using reverse connect");
+ exit (1);
+ }
+
+ // Build the connection string.
+ char connection_url[512];
+ snprintf(connection_url, sizeof(connection_url), "connect://%s", final_host_and_port.c_str ());
+
+ // Create the connection.
+ std::unique_ptr<ConnectionFileDescriptor> connection_up (new ConnectionFileDescriptor ());
+ connection_up.reset (new ConnectionFileDescriptor ());
+ auto connection_result = connection_up->Connect (connection_url, &error);
+ if (connection_result != eConnectionStatusSuccess)
+ {
+ fprintf (stderr, "error: failed to connect to client at '%s' (connection status: %d)", connection_url, static_cast<int> (connection_result));
+ exit (-1);
+ }
+ if (error.Fail ())
+ {
+ fprintf (stderr, "error: failed to connect to client at '%s': %s", connection_url, error.AsCString ());
+ exit (-1);
+ }
+
+ // We're connected.
+ printf ("Connection established.\n");
+ gdb_server.SetConnection (connection_up.release());
+ }
+ else
+ {
+ // llgs will listen for connections on the given port from the given address.
+ // Start the listener on a new thread. We need to do this so we can resolve the
+ // bound listener port.
+ StartListenThread(connection_host.c_str (), static_cast<uint16_t> (connection_portno));
+ printf ("Listening to port %s for a connection from %s...\n", connection_port.c_str (), connection_host.c_str ());
+
+ // If we have a named pipe to write the port number back to, do that now.
+ if (named_pipe_path && named_pipe_path[0] && connection_portno == 0)
+ {
+ const uint16_t bound_port = s_listen_connection_up->GetListeningPort (10);
+ if (bound_port > 0)
+ {
+ error = writePortToPipe (named_pipe_path, bound_port);
+ if (error.Fail ())
+ {
+ fprintf (stderr, "failed to write to the named pipe \'%s\': %s", named_pipe_path, error.AsCString());
+ }
+ }
+ else
+ {
+ fprintf (stderr, "unable to get the bound port for the listening connection\n");
+ }
+ }
+
+ // If we have an unnamed pipe to write the port number back to, do that now.
+ if (unnamed_pipe_fd >= 0 && connection_portno == 0)
+ {
+ const uint16_t bound_port = s_listen_connection_up->GetListeningPort(10);
+ if (bound_port > 0)
+ {
+ error = writePortToPipe(unnamed_pipe_fd, bound_port);
+ if (error.Fail())
+ {
+ fprintf(stderr, "failed to write to the unnamed pipe: %s",
+ error.AsCString());
+ }
+ }
+ else
+ {
+ fprintf(stderr, "unable to get the bound port for the listening connection\n");
+ }
+ }
+
+ // Join the listener thread.
+ if (!JoinListenThread ())
+ {
+ fprintf (stderr, "failed to join the listener thread\n");
+ display_usage (progname, subcommand);
+ exit (1);
+ }
+
+ // Ensure we connected.
+ if (s_listen_connection_up)
+ {
+ printf ("Connection established '%s'\n", s_listen_connection_up->GetURI().c_str());
+ gdb_server.SetConnection (s_listen_connection_up.release());
+ }
+ else
+ {
+ fprintf (stderr, "failed to connect to '%s': %s\n", final_host_and_port.c_str (), error.AsCString ());
+ display_usage (progname, subcommand);
+ exit (1);
+ }
+ }
+ }
+
+ if (gdb_server.IsConnected())
+ {
+ // After we connected, we need to get an initial ack from...
+ if (gdb_server.HandshakeWithClient(&error))
+ {
+ // We'll use a half a second timeout interval so that an exit conditions can
+ // be checked that often.
+ const uint32_t TIMEOUT_USEC = 500000;
+
+ bool interrupt = false;
+ bool done = false;
+ while (!interrupt && !done && (g_sighup_received_count < 2))
+ {
+ const GDBRemoteCommunication::PacketResult result = gdb_server.GetPacketAndSendResponse (TIMEOUT_USEC, error, interrupt, done);
+ if ((result != GDBRemoteCommunication::PacketResult::Success) &&
+ (result != GDBRemoteCommunication::PacketResult::ErrorReplyTimeout))
+ {
+ // We're bailing out - we only support successful handling and timeouts.
+ fprintf(stderr, "leaving packet loop due to PacketResult %d\n", result);
+ break;
+ }
+ }
+
+ if (error.Fail())
+ {
+ fprintf(stderr, "error: %s\n", error.AsCString());
+ }
+ }
+ else
+ {
+ fprintf(stderr, "error: handshake with client failed\n");
+ }
+ }
+ else
+ {
+ fprintf (stderr, "no connection information provided, unable to run\n");
+ display_usage (progname, subcommand);
+ exit (1);
+ }
+}
+
+//----------------------------------------------------------------------
+// main
+//----------------------------------------------------------------------
+int
+main_gdbserver (int argc, char *argv[])
+{
+#ifndef _WIN32
+ // Setup signal handlers first thing.
+ signal (SIGPIPE, signal_handler);
+ signal (SIGHUP, signal_handler);
+#endif
+#ifdef __linux__
+ // Block delivery of SIGCHLD on linux. NativeProcessLinux will read it using signalfd.
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, SIGCHLD);
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
+#endif
+
+ const char *progname = argv[0];
+ const char *subcommand = argv[1];
+ argc--;
+ argv++;
+ int long_option_index = 0;
+ Error error;
+ int ch;
+ std::string platform_name;
+ std::string attach_target;
+ std::string named_pipe_path;
+ std::string log_file;
+ StringRef log_channels; // e.g. "lldb process threads:gdb-remote default:linux all"
+ int unnamed_pipe_fd = -1;
+ bool reverse_connect = false;
+
+ // ProcessLaunchInfo launch_info;
+ ProcessAttachInfo attach_info;
+
+ bool show_usage = false;
+ int option_error = 0;
+#if __GLIBC__
+ optind = 0;
+#else
+ optreset = 1;
+ optind = 1;
+#endif
+
+ std::string short_options(OptionParser::GetShortOptionString(g_long_options));
+
+ while ((ch = getopt_long_only(argc, argv, short_options.c_str(), g_long_options, &long_option_index)) != -1)
+ {
+ switch (ch)
+ {
+ case 0: // Any optional that auto set themselves will return 0
+ break;
+
+ case 'l': // Set Log File
+ if (optarg && optarg[0])
+ log_file.assign(optarg);
+ break;
+
+ case 'c': // Log Channels
+ if (optarg && optarg[0])
+ log_channels = StringRef(optarg);
+ break;
+
+ case 'p': // platform name
+ if (optarg && optarg[0])
+ platform_name = optarg;
+ break;
+
+ case 'N': // named pipe
+ if (optarg && optarg[0])
+ named_pipe_path = optarg;
+ break;
+
+ case 'U': // unnamed pipe
+ if (optarg && optarg[0])
+ unnamed_pipe_fd = StringConvert::ToUInt32(optarg, -1);
+
+ case 'r':
+ // Do nothing, native regs is the default these days
+ break;
+
+ case 'R':
+ reverse_connect = true;
+ break;
+
+#ifndef _WIN32
+ case 'S':
+ // Put llgs into a new session. Terminals group processes
+ // into sessions and when a special terminal key sequences
+ // (like control+c) are typed they can cause signals to go out to
+ // all processes in a session. Using this --setsid (-S) option
+ // will cause debugserver to run in its own sessions and be free
+ // from such issues.
+ //
+ // This is useful when llgs is spawned from a command
+ // line application that uses llgs to do the debugging,
+ // yet that application doesn't want llgs receiving the
+ // signals sent to the session (i.e. dying when anyone hits ^C).
+ {
+ const ::pid_t new_sid = setsid();
+ if (new_sid == -1)
+ {
+ const char *errno_str = strerror(errno);
+ fprintf (stderr, "failed to set new session id for %s (%s)\n", LLGS_PROGRAM_NAME, errno_str ? errno_str : "<no error string>");
+ }
+ }
+ break;
+#endif
+
+ case 'a': // attach {pid|process_name}
+ if (optarg && optarg[0])
+ attach_target = optarg;
+ break;
+
+ case 'h': /* fall-through is intentional */
+ case '?':
+ show_usage = true;
+ break;
+ }
+ }
+
+ if (show_usage || option_error)
+ {
+ display_usage(progname, subcommand);
+ exit(option_error);
+ }
+
+ if (!LLDBServerUtilities::SetupLogging(log_file, log_channels, 0))
+ return -1;
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_VERBOSE));
+ if (log)
+ {
+ log->Printf ("lldb-server launch");
+ for (int i = 0; i < argc; i++)
+ {
+ log->Printf ("argv[%i] = '%s'", i, argv[i]);
+ }
+ }
+
+ // Skip any options we consumed with getopt_long_only.
+ argc -= optind;
+ argv += optind;
+
+ if (argc == 0)
+ {
+ display_usage(progname, subcommand);
+ exit(255);
+ }
+
+ // Setup the platform that GDBRemoteCommunicationServerLLGS will use.
+ lldb::PlatformSP platform_sp = setup_platform (platform_name);
+
+ GDBRemoteCommunicationServerLLGS gdb_server (platform_sp);
+
+ const char *const host_and_port = argv[0];
+ argc -= 1;
+ argv += 1;
+
+ // Any arguments left over are for the program that we need to launch. If there
+ // are no arguments, then the GDB server will start up and wait for an 'A' packet
+ // to launch a program, or a vAttach packet to attach to an existing process, unless
+ // explicitly asked to attach with the --attach={pid|program_name} form.
+ if (!attach_target.empty ())
+ handle_attach (gdb_server, attach_target);
+ else if (argc > 0)
+ handle_launch (gdb_server, argc, argv);
+
+ // Print version info.
+ printf("%s-%s", LLGS_PROGRAM_NAME, LLGS_VERSION_STR);
+
+ ConnectToRemote(gdb_server, reverse_connect,
+ host_and_port, progname, subcommand,
+ named_pipe_path.c_str(), unnamed_pipe_fd);
+
+ fprintf(stderr, "lldb-server exiting...\n");
+
+ return 0;
+}
diff --git a/tools/lldb-platform/lldb-platform.cpp b/tools/lldb-server/lldb-platform.cpp
index f1c1a982850a..33ba1ad1ef98 100644
--- a/tools/lldb-platform/lldb-platform.cpp
+++ b/tools/lldb-server/lldb-platform.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/lldb-python.h"
-
// C Includes
#include <errno.h>
#if defined(__APPLE__)
@@ -19,44 +17,46 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/wait.h>
// C++ Includes
// Other libraries and framework includes
-#include "lldb/lldb-private-log.h"
#include "lldb/Core/Error.h"
-#include "lldb/Core/ConnectionMachPort.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/StreamFile.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/HostGetOpt.h"
#include "lldb/Host/OptionParser.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
+#include "lldb/Host/Socket.h"
+#include "LLDBServerUtilities.h"
+#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
+
using namespace lldb;
using namespace lldb_private;
+using namespace lldb_private::lldb_server;
+using namespace lldb_private::process_gdb_remote;
+using namespace llvm;
//----------------------------------------------------------------------
// option descriptors for getopt_long_only()
//----------------------------------------------------------------------
-int g_debug = 0;
-int g_verbose = 0;
-int g_stay_alive = 0;
+static int g_debug = 0;
+static int g_verbose = 0;
+static int g_server = 0;
static struct option g_long_options[] =
{
{ "debug", no_argument, &g_debug, 1 },
{ "verbose", no_argument, &g_verbose, 1 },
- { "stay-alive", no_argument, &g_stay_alive, 1 },
+ { "log-file", required_argument, NULL, 'l' },
+ { "log-channels", required_argument, NULL, 'c' },
{ "listen", required_argument, NULL, 'L' },
{ "port-offset", required_argument, NULL, 'p' },
{ "gdbserver-port", required_argument, NULL, 'P' },
{ "min-gdbserver-port", required_argument, NULL, 'm' },
{ "max-gdbserver-port", required_argument, NULL, 'M' },
- { "lldb-command", required_argument, NULL, 'c' },
+ { "server", no_argument, &g_server, 1 },
{ NULL, 0, NULL, 0 }
};
@@ -68,11 +68,10 @@ static struct option g_long_options[] =
#define HIGH_PORT (49151u)
#endif
-
//----------------------------------------------------------------------
// Watch for signals
//----------------------------------------------------------------------
-void
+static void
signal_handler(int signo)
{
switch (signo)
@@ -81,16 +80,16 @@ signal_handler(int signo)
// Use SIGINT first, if that does not work, use SIGHUP as a last resort.
// And we should not call exit() here because it results in the global destructors
// to be invoked and wreaking havoc on the threads still running.
- Host::SystemLog(Host::eSystemLogWarning, "SIGHUP received, exiting lldb-platform...\n");
+ Host::SystemLog(Host::eSystemLogWarning, "SIGHUP received, exiting lldb-server...\n");
abort();
break;
}
}
static void
-display_usage (const char *progname)
+display_usage (const char *progname, const char *subcommand)
{
- fprintf(stderr, "Usage:\n %s [--log-file log-file-path] [--log-flags flags] --listen port\n", progname);
+ fprintf(stderr, "Usage:\n %s %s [--log-file log-file-name] [--log-channels log-channel-list] --server --listen port\n", progname, subcommand);
exit(0);
}
@@ -98,31 +97,30 @@ display_usage (const char *progname)
// main
//----------------------------------------------------------------------
int
-main (int argc, char *argv[])
+main_platform (int argc, char *argv[])
{
const char *progname = argv[0];
+ const char *subcommand = argv[1];
+ argc--;
+ argv++;
signal (SIGPIPE, SIG_IGN);
signal (SIGHUP, signal_handler);
int long_option_index = 0;
Error error;
std::string listen_host_port;
int ch;
- Debugger::Initialize(NULL);
-
- lldb::DebuggerSP debugger_sp = Debugger::CreateInstance ();
- debugger_sp->SetInputFileHandle(stdin, false);
- debugger_sp->SetOutputFileHandle(stdout, false);
- debugger_sp->SetErrorFileHandle(stderr, false);
-
- GDBRemoteCommunicationServer::PortMap gdbserver_portmap;
+ std::string log_file;
+ StringRef log_channels; // e.g. "lldb process threads:gdb-remote default:linux all"
+
+ GDBRemoteCommunicationServerPlatform::PortMap gdbserver_portmap;
int min_gdbserver_port = 0;
int max_gdbserver_port = 0;
uint16_t port_offset = 0;
- std::vector<std::string> lldb_commands;
bool show_usage = false;
int option_error = 0;
+ int socket_error = -1;
std::string short_options(OptionParser::GetShortOptionString(g_long_options));
@@ -144,6 +142,16 @@ main (int argc, char *argv[])
listen_host_port.append (optarg);
break;
+ case 'l': // Set Log File
+ if (optarg && optarg[0])
+ log_file.assign(optarg);
+ break;
+
+ case 'c': // Log Channels
+ if (optarg && optarg[0])
+ log_channels = StringRef(optarg);
+ break;
+
case 'p':
{
char *end = NULL;
@@ -198,10 +206,6 @@ main (int argc, char *argv[])
}
}
break;
-
- case 'c':
- lldb_commands.push_back(optarg);
- break;
case 'h': /* fall-through is intentional */
case '?':
@@ -210,6 +214,9 @@ main (int argc, char *argv[])
}
}
+ if (!LLDBServerUtilities::SetupLogging(log_file, log_channels, 0))
+ return -1;
+
// Make a port map for a port range that was specified.
if (min_gdbserver_port < max_gdbserver_port)
{
@@ -220,7 +227,6 @@ main (int argc, char *argv[])
{
fprintf (stderr, "error: --min-gdbserver-port (%u) is greater than --max-gdbserver-port (%u)\n", min_gdbserver_port, max_gdbserver_port);
option_error = 3;
-
}
// Print usage and exit if no listening port is specified.
@@ -229,82 +235,102 @@ main (int argc, char *argv[])
if (show_usage || option_error)
{
- display_usage(progname);
+ display_usage(progname, subcommand);
exit(option_error);
}
- // Execute any LLDB commands that we were asked to evaluate.
- for (const auto &lldb_command : lldb_commands)
+ std::unique_ptr<Socket> listening_socket_up;
+ Socket *socket = nullptr;
+ const bool children_inherit_listen_socket = false;
+
+ // the test suite makes many connections in parallel, let's not miss any.
+ // The highest this should get reasonably is a function of the number
+ // of target CPUs. For now, let's just use 100
+ const int backlog = 100;
+ error = Socket::TcpListen(listen_host_port.c_str(), children_inherit_listen_socket, socket, NULL, backlog);
+ if (error.Fail())
{
- lldb_private::CommandReturnObject result;
- printf("(lldb) %s\n", lldb_command.c_str());
- debugger_sp->GetCommandInterpreter().HandleCommand(lldb_command.c_str(), eLazyBoolNo, result);
- const char *output = result.GetOutputData();
- if (output && output[0])
- puts(output);
+ printf("error: %s\n", error.AsCString());
+ exit(socket_error);
}
-
+ listening_socket_up.reset(socket);
+ printf ("Listening for a connection from %u...\n", listening_socket_up->GetLocalPortNumber());
do {
- GDBRemoteCommunicationServer gdb_server (true);
+ GDBRemoteCommunicationServerPlatform platform;
if (port_offset > 0)
- gdb_server.SetPortOffset(port_offset);
+ platform.SetPortOffset(port_offset);
if (!gdbserver_portmap.empty())
{
- gdb_server.SetPortMap(std::move(gdbserver_portmap));
+ platform.SetPortMap(std::move(gdbserver_portmap));
}
- if (!listen_host_port.empty())
+ const bool children_inherit_accept_socket = true;
+ socket = nullptr;
+ error = listening_socket_up->BlockingAccept(listen_host_port.c_str(), children_inherit_accept_socket, socket);
+ if (error.Fail())
{
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
- if (conn_ap.get())
+ printf ("error: %s\n", error.AsCString());
+ exit(socket_error);
+ }
+ printf ("Connection established.\n");
+ if (g_server)
+ {
+ // Collect child zombie processes.
+ while (waitpid(-1, nullptr, WNOHANG) > 0);
+ if (fork())
{
- std::string connect_url ("listen://");
- connect_url.append(listen_host_port.c_str());
+ // Parent doesn't need a connection to the lldb client
+ delete socket;
+ socket = nullptr;
- printf ("Listening for a connection from %s...\n", listen_host_port.c_str());
- if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)
- {
- printf ("Connection established.\n");
- gdb_server.SetConnection (conn_ap.release());
- }
- else
- {
- printf ("error: %s\n", error.AsCString());
- }
+ // Parent will continue to listen for new connections.
+ continue;
+ }
+ else
+ {
+ // Child process will handle the connection and exit.
+ g_server = 0;
+ // Listening socket is owned by parent process.
+ listening_socket_up.release();
}
+ }
+ else
+ {
+ // If not running as a server, this process will not accept
+ // connections while a connection is active.
+ listening_socket_up.reset();
+ }
+ platform.SetConnection (new ConnectionFileDescriptor(socket));
- if (gdb_server.IsConnected())
+ if (platform.IsConnected())
+ {
+ // After we connected, we need to get an initial ack from...
+ if (platform.HandshakeWithClient(&error))
{
- // After we connected, we need to get an initial ack from...
- if (gdb_server.HandshakeWithClient(&error))
+ bool interrupt = false;
+ bool done = false;
+ while (!interrupt && !done)
{
- bool interrupt = false;
- bool done = false;
- while (!interrupt && !done)
- {
- if (gdb_server.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success)
- break;
- }
-
- if (error.Fail())
- {
- fprintf(stderr, "error: %s\n", error.AsCString());
- }
+ if (platform.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success)
+ break;
}
- else
+
+ if (error.Fail())
{
- fprintf(stderr, "error: handshake with client failed\n");
+ fprintf(stderr, "error: %s\n", error.AsCString());
}
}
+ else
+ {
+ fprintf(stderr, "error: handshake with client failed\n");
+ }
}
- } while (g_stay_alive);
-
- Debugger::Terminate();
+ } while (g_server);
- fprintf(stderr, "lldb-platform exiting...\n");
+ fprintf(stderr, "lldb-server exiting...\n");
return 0;
}
diff --git a/tools/lldb-server/lldb-server.cpp b/tools/lldb-server/lldb-server.cpp
new file mode 100644
index 000000000000..ec92b094f485
--- /dev/null
+++ b/tools/lldb-server/lldb-server.cpp
@@ -0,0 +1,76 @@
+//===-- lldb-server.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/Initialization/SystemLifetimeManager.h"
+#include "lldb/Initialization/SystemInitializerCommon.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ManagedStatic.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static llvm::ManagedStatic<lldb_private::SystemLifetimeManager> g_debugger_lifetime;
+
+static void
+display_usage (const char *progname)
+{
+ fprintf(stderr, "Usage:\n"
+ " %s g[dbserver] [options]\n"
+ " %s p[latform] [options]\n"
+ "Invoke subcommand for additional help\n", progname, progname);
+ exit(0);
+}
+
+// Forward declarations of subcommand main methods.
+int main_gdbserver (int argc, char *argv[]);
+int main_platform (int argc, char *argv[]);
+
+static void
+initialize ()
+{
+ g_debugger_lifetime->Initialize(llvm::make_unique<lldb_private::SystemInitializerCommon>(), nullptr);
+}
+
+static void
+terminate ()
+{
+ g_debugger_lifetime->Terminate();
+}
+
+//----------------------------------------------------------------------
+// main
+//----------------------------------------------------------------------
+int
+main (int argc, char *argv[])
+{
+ int option_error = 0;
+ const char *progname = argv[0];
+ if (argc < 2)
+ {
+ display_usage(progname);
+ exit(option_error);
+ }
+ else if (argv[1][0] == 'g')
+ {
+ initialize();
+ main_gdbserver(argc, argv);
+ terminate();
+ }
+ else if (argv[1][0] == 'p')
+ {
+ initialize();
+ main_platform(argc, argv);
+ terminate();
+ }
+ else {
+ display_usage(progname);
+ exit(option_error);
+ }
+}