diff options
author | Ed Maste <emaste@FreeBSD.org> | 2015-07-03 16:57:06 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2015-07-03 16:57:06 +0000 |
commit | 5e95aa85bb660d45e9905ef1d7180b2678280660 (patch) | |
tree | 3c2e41c3be19b7fc7666ed45a5f91ec3b6e35f2a /tools/lldb-mi | |
parent | 12bd4897ff0678fa663e09d78ebc22dd255ceb86 (diff) |
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/lldb-mi')
167 files changed, 5317 insertions, 7276 deletions
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 |