aboutsummaryrefslogtreecommitdiff
path: root/source/Commands
diff options
context:
space:
mode:
Diffstat (limited to 'source/Commands')
-rw-r--r--source/Commands/CommandCompletions.cpp1063
-rw-r--r--source/Commands/CommandObjectApropos.cpp158
-rw-r--r--source/Commands/CommandObjectApropos.h15
-rw-r--r--source/Commands/CommandObjectArgs.cpp388
-rw-r--r--source/Commands/CommandObjectArgs.h70
-rw-r--r--source/Commands/CommandObjectBreakpoint.cpp4301
-rw-r--r--source/Commands/CommandObjectBreakpoint.h34
-rw-r--r--source/Commands/CommandObjectBreakpointCommand.cpp1204
-rw-r--r--source/Commands/CommandObjectBreakpointCommand.h13
-rw-r--r--source/Commands/CommandObjectBugreport.cpp176
-rw-r--r--source/Commands/CommandObjectBugreport.h7
-rw-r--r--source/Commands/CommandObjectCommands.cpp3631
-rw-r--r--source/Commands/CommandObjectCommands.h13
-rw-r--r--source/Commands/CommandObjectDisassemble.cpp1026
-rw-r--r--source/Commands/CommandObjectDisassemble.h120
-rw-r--r--source/Commands/CommandObjectExpression.cpp1092
-rw-r--r--source/Commands/CommandObjectExpression.h145
-rw-r--r--source/Commands/CommandObjectFrame.cpp1119
-rw-r--r--source/Commands/CommandObjectFrame.h10
-rw-r--r--source/Commands/CommandObjectGUI.cpp65
-rw-r--r--source/Commands/CommandObjectGUI.h12
-rw-r--r--source/Commands/CommandObjectHelp.cpp428
-rw-r--r--source/Commands/CommandObjectHelp.h157
-rw-r--r--source/Commands/CommandObjectLanguage.cpp14
-rw-r--r--source/Commands/CommandObjectLanguage.h22
-rw-r--r--source/Commands/CommandObjectLog.cpp705
-rw-r--r--source/Commands/CommandObjectLog.h21
-rw-r--r--source/Commands/CommandObjectMemory.cpp3199
-rw-r--r--source/Commands/CommandObjectMemory.h7
-rw-r--r--source/Commands/CommandObjectMultiword.cpp755
-rw-r--r--source/Commands/CommandObjectPlatform.cpp3536
-rw-r--r--source/Commands/CommandObjectPlatform.h9
-rw-r--r--source/Commands/CommandObjectPlugin.cpp139
-rw-r--r--source/Commands/CommandObjectPlugin.h19
-rw-r--r--source/Commands/CommandObjectProcess.cpp2962
-rw-r--r--source/Commands/CommandObjectProcess.h7
-rw-r--r--source/Commands/CommandObjectQuit.cpp111
-rw-r--r--source/Commands/CommandObjectQuit.h17
-rw-r--r--source/Commands/CommandObjectRegister.cpp739
-rw-r--r--source/Commands/CommandObjectRegister.h21
-rw-r--r--source/Commands/CommandObjectSettings.cpp1898
-rw-r--r--source/Commands/CommandObjectSettings.h9
-rw-r--r--source/Commands/CommandObjectSource.cpp2565
-rw-r--r--source/Commands/CommandObjectSource.h13
-rw-r--r--source/Commands/CommandObjectSyntax.cpp157
-rw-r--r--source/Commands/CommandObjectSyntax.h12
-rw-r--r--source/Commands/CommandObjectTarget.cpp8942
-rw-r--r--source/Commands/CommandObjectTarget.h10
-rw-r--r--source/Commands/CommandObjectThread.cpp3649
-rw-r--r--source/Commands/CommandObjectThread.h8
-rw-r--r--source/Commands/CommandObjectType.cpp5806
-rw-r--r--source/Commands/CommandObjectType.h9
-rw-r--r--source/Commands/CommandObjectVersion.cpp39
-rw-r--r--source/Commands/CommandObjectVersion.h12
-rw-r--r--source/Commands/CommandObjectWatchpoint.cpp2122
-rw-r--r--source/Commands/CommandObjectWatchpoint.h13
-rw-r--r--source/Commands/CommandObjectWatchpointCommand.cpp1037
-rw-r--r--source/Commands/CommandObjectWatchpointCommand.h12
58 files changed, 25194 insertions, 28649 deletions
diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp
index dd0ecb4b82e9..10c1a2429bbe 100644
--- a/source/Commands/CommandCompletions.cpp
+++ b/source/Commands/CommandCompletions.cpp
@@ -37,447 +37,366 @@
using namespace lldb_private;
CommandCompletions::CommonCompletionElement
-CommandCompletions::g_common_completions[] =
-{
- {eCustomCompletion, nullptr},
- {eSourceFileCompletion, CommandCompletions::SourceFiles},
- {eDiskFileCompletion, CommandCompletions::DiskFiles},
- {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories},
- {eSymbolCompletion, CommandCompletions::Symbols},
- {eModuleCompletion, CommandCompletions::Modules},
- {eSettingsNameCompletion, CommandCompletions::SettingsNames},
- {ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames},
- {eArchitectureCompletion, CommandCompletions::ArchitectureNames},
- {eVariablePathCompletion, CommandCompletions::VariablePath},
- {eNoCompletion, nullptr} // This one has to be last in the list.
+ CommandCompletions::g_common_completions[] = {
+ {eCustomCompletion, nullptr},
+ {eSourceFileCompletion, CommandCompletions::SourceFiles},
+ {eDiskFileCompletion, CommandCompletions::DiskFiles},
+ {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories},
+ {eSymbolCompletion, CommandCompletions::Symbols},
+ {eModuleCompletion, CommandCompletions::Modules},
+ {eSettingsNameCompletion, CommandCompletions::SettingsNames},
+ {ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames},
+ {eArchitectureCompletion, CommandCompletions::ArchitectureNames},
+ {eVariablePathCompletion, CommandCompletions::VariablePath},
+ {eNoCompletion, nullptr} // This one has to be last in the list.
};
-bool
-CommandCompletions::InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter,
- uint32_t completion_mask,
- const char *completion_str,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches)
-{
- bool handled = false;
-
- if (completion_mask & eCustomCompletion)
- return false;
-
- for (int i = 0; ; i++)
- {
- if (g_common_completions[i].type == eNoCompletion)
- break;
- else if ((g_common_completions[i].type & completion_mask) == g_common_completions[i].type
- && g_common_completions[i].callback != nullptr)
- {
- handled = true;
- g_common_completions[i].callback (interpreter,
- completion_str,
- match_start_point,
- max_return_elements,
- searcher,
- word_complete,
- matches);
- }
+bool CommandCompletions::InvokeCommonCompletionCallbacks(
+ CommandInterpreter &interpreter, uint32_t completion_mask,
+ llvm::StringRef completion_str, int match_start_point,
+ int max_return_elements, SearchFilter *searcher, bool &word_complete,
+ StringList &matches) {
+ bool handled = false;
+
+ if (completion_mask & eCustomCompletion)
+ return false;
+
+ for (int i = 0;; i++) {
+ if (g_common_completions[i].type == eNoCompletion)
+ break;
+ else if ((g_common_completions[i].type & completion_mask) ==
+ g_common_completions[i].type &&
+ g_common_completions[i].callback != nullptr) {
+ handled = true;
+ g_common_completions[i].callback(interpreter, completion_str,
+ match_start_point, max_return_elements,
+ searcher, word_complete, matches);
}
- return handled;
+ }
+ return handled;
}
-int
-CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
- const char *partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches)
-{
- word_complete = true;
- // Find some way to switch "include support files..."
- SourceFileCompleter completer (interpreter,
- false,
- partial_file_name,
- match_start_point,
- max_return_elements,
- matches);
-
- if (searcher == nullptr)
- {
- lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
- SearchFilterForUnconstrainedSearches null_searcher (target_sp);
- completer.DoCompletion (&null_searcher);
- }
- else
- {
- completer.DoCompletion (searcher);
- }
- return matches.GetSize();
+int CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
+ llvm::StringRef partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher, bool &word_complete,
+ StringList &matches) {
+ word_complete = true;
+ // Find some way to switch "include support files..."
+ SourceFileCompleter completer(interpreter, false, partial_file_name,
+ match_start_point, max_return_elements,
+ matches);
+
+ if (searcher == nullptr) {
+ lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
+ SearchFilterForUnconstrainedSearches null_searcher(target_sp);
+ completer.DoCompletion(&null_searcher);
+ } else {
+ completer.DoCompletion(searcher);
+ }
+ return matches.GetSize();
}
-typedef struct DiskFilesOrDirectoriesBaton
-{
- const char *remainder;
- char *partial_name_copy;
- bool only_directories;
- bool *saw_directory;
- StringList *matches;
- char *end_ptr;
- size_t baselen;
+typedef struct DiskFilesOrDirectoriesBaton {
+ const char *remainder;
+ char *partial_name_copy;
+ bool only_directories;
+ bool *saw_directory;
+ StringList *matches;
+ char *end_ptr;
+ size_t baselen;
} DiskFilesOrDirectoriesBaton;
-FileSpec::EnumerateDirectoryResult DiskFilesOrDirectoriesCallback(void *baton, FileSpec::FileType file_type, const FileSpec &spec)
-{
- const char *name = spec.GetFilename().AsCString();
-
- const DiskFilesOrDirectoriesBaton *parameters = (DiskFilesOrDirectoriesBaton*)baton;
- char *end_ptr = parameters->end_ptr;
- char *partial_name_copy = parameters->partial_name_copy;
- const char *remainder = parameters->remainder;
-
- // Omit ".", ".." and any . files if the match string doesn't start with .
- if (name[0] == '.')
- {
- if (name[1] == '\0')
- return FileSpec::eEnumerateDirectoryResultNext;
- else if (name[1] == '.' && name[2] == '\0')
- return FileSpec::eEnumerateDirectoryResultNext;
- else if (remainder[0] != '.')
- return FileSpec::eEnumerateDirectoryResultNext;
+FileSpec::EnumerateDirectoryResult
+DiskFilesOrDirectoriesCallback(void *baton, FileSpec::FileType file_type,
+ const FileSpec &spec) {
+ const char *name = spec.GetFilename().AsCString();
+
+ const DiskFilesOrDirectoriesBaton *parameters =
+ (DiskFilesOrDirectoriesBaton *)baton;
+ char *end_ptr = parameters->end_ptr;
+ char *partial_name_copy = parameters->partial_name_copy;
+ const char *remainder = parameters->remainder;
+
+ // Omit ".", ".." and any . files if the match string doesn't start with .
+ if (name[0] == '.') {
+ if (name[1] == '\0')
+ return FileSpec::eEnumerateDirectoryResultNext;
+ else if (name[1] == '.' && name[2] == '\0')
+ return FileSpec::eEnumerateDirectoryResultNext;
+ else if (remainder[0] != '.')
+ return FileSpec::eEnumerateDirectoryResultNext;
+ }
+
+ // If we found a directory, we put a "/" at the end of the name.
+
+ if (remainder[0] == '\0' || strstr(name, remainder) == name) {
+ if (strlen(name) + parameters->baselen >= PATH_MAX)
+ return FileSpec::eEnumerateDirectoryResultNext;
+
+ strcpy(end_ptr, name);
+
+ bool isa_directory = false;
+ if (file_type == FileSpec::eFileTypeDirectory)
+ isa_directory = true;
+ else if (file_type == FileSpec::eFileTypeSymbolicLink) {
+ if (FileSpec(partial_name_copy, false).IsDirectory())
+ isa_directory = true;
}
- // If we found a directory, we put a "/" at the end of the name.
-
- if (remainder[0] == '\0' || strstr(name, remainder) == name)
- {
- if (strlen(name) + parameters->baselen >= PATH_MAX)
- return FileSpec::eEnumerateDirectoryResultNext;
+ if (isa_directory) {
+ *parameters->saw_directory = true;
+ size_t len = strlen(parameters->partial_name_copy);
+ partial_name_copy[len] = '/';
+ partial_name_copy[len + 1] = '\0';
+ }
+ if (parameters->only_directories && !isa_directory)
+ return FileSpec::eEnumerateDirectoryResultNext;
+ parameters->matches->AppendString(partial_name_copy);
+ }
- strcpy(end_ptr, name);
+ return FileSpec::eEnumerateDirectoryResultNext;
+}
- bool isa_directory = false;
- if (file_type == FileSpec::eFileTypeDirectory)
- isa_directory = true;
- else if (file_type == FileSpec::eFileTypeSymbolicLink)
- {
- if (FileSpec(partial_name_copy, false).IsDirectory())
- isa_directory = true;
- }
+static int DiskFilesOrDirectories(llvm::StringRef partial_file_name,
+ bool only_directories, bool &saw_directory,
+ StringList &matches) {
+ // I'm going to use the "glob" function with GLOB_TILDE for user directory
+ // expansion.
+ // If it is not defined on your host system, you'll need to implement it
+ // yourself...
- if (isa_directory)
- {
- *parameters->saw_directory = true;
- size_t len = strlen(parameters->partial_name_copy);
- partial_name_copy[len] = '/';
- partial_name_copy[len + 1] = '\0';
- }
- if (parameters->only_directories && !isa_directory)
- return FileSpec::eEnumerateDirectoryResultNext;
- parameters->matches->AppendString(partial_name_copy);
- }
+ size_t partial_name_len = partial_file_name.size();
- return FileSpec::eEnumerateDirectoryResultNext;
-}
+ if (partial_name_len >= PATH_MAX)
+ return matches.GetSize();
-static int
-DiskFilesOrDirectories(const char *partial_file_name,
- bool only_directories,
- bool &saw_directory,
- StringList &matches)
-{
- // I'm going to use the "glob" function with GLOB_TILDE for user directory expansion.
- // If it is not defined on your host system, you'll need to implement it yourself...
-
- size_t partial_name_len = strlen(partial_file_name);
-
- if (partial_name_len >= PATH_MAX)
+ // This copy of the string will be cut up into the directory part, and the
+ // remainder. end_ptr below will point to the place of the remainder in this
+ // string. Then when we've resolved the containing directory, and opened it,
+ // we'll read the directory contents and overwrite the partial_name_copy
+ // starting from end_ptr with each of the matches. Thus we will preserve the
+ // form the user originally typed.
+
+ char partial_name_copy[PATH_MAX];
+ memcpy(partial_name_copy, partial_file_name.data(), partial_name_len);
+ partial_name_copy[partial_name_len] = '\0';
+
+ // We'll need to save a copy of the remainder for comparison, which we do
+ // here.
+ char remainder[PATH_MAX];
+
+ // end_ptr will point past the last / in partial_name_copy, or if there is no
+ // slash to the beginning of the string.
+ char *end_ptr;
+
+ end_ptr = strrchr(partial_name_copy, '/');
+
+ // This will store the resolved form of the containing directory
+ llvm::SmallString<64> containing_part;
+
+ if (end_ptr == nullptr) {
+ // There's no directory. If the thing begins with a "~" then this is a bare
+ // user name.
+ if (*partial_name_copy == '~') {
+ // Nothing here but the user name. We could just put a slash on the end,
+ // but for completeness sake we'll resolve the user name and only put a
+ // slash
+ // on the end if it exists.
+ llvm::SmallString<64> resolved_username(partial_name_copy);
+ FileSpec::ResolveUsername(resolved_username);
+
+ // Not sure how this would happen, a username longer than PATH_MAX?
+ // Still...
+ if (resolved_username.size() == 0) {
+ // The user name didn't resolve, let's look in the password database for
+ // matches.
+ // The user name database contains duplicates, and is not in
+ // alphabetical order, so
+ // we'll use a set to manage that for us.
+ FileSpec::ResolvePartialUsername(partial_name_copy, matches);
+ if (matches.GetSize() > 0)
+ saw_directory = true;
return matches.GetSize();
-
- // This copy of the string will be cut up into the directory part, and the remainder. end_ptr
- // below will point to the place of the remainder in this string. Then when we've resolved the
- // containing directory, and opened it, we'll read the directory contents and overwrite the
- // partial_name_copy starting from end_ptr with each of the matches. Thus we will preserve
- // the form the user originally typed.
-
- char partial_name_copy[PATH_MAX];
- memcpy(partial_name_copy, partial_file_name, partial_name_len);
- partial_name_copy[partial_name_len] = '\0';
-
- // We'll need to save a copy of the remainder for comparison, which we do here.
- char remainder[PATH_MAX];
-
- // end_ptr will point past the last / in partial_name_copy, or if there is no slash to the beginning of the string.
- char *end_ptr;
-
- end_ptr = strrchr(partial_name_copy, '/');
-
- // This will store the resolved form of the containing directory
- llvm::SmallString<64> containing_part;
-
- if (end_ptr == nullptr)
- {
- // There's no directory. If the thing begins with a "~" then this is a bare
- // user name.
- if (*partial_name_copy == '~')
- {
- // Nothing here but the user name. We could just put a slash on the end,
- // but for completeness sake we'll resolve the user name and only put a slash
- // on the end if it exists.
- llvm::SmallString<64> resolved_username(partial_name_copy);
- FileSpec::ResolveUsername (resolved_username);
-
- // Not sure how this would happen, a username longer than PATH_MAX? Still...
- if (resolved_username.size() == 0)
- {
- // The user name didn't resolve, let's look in the password database for matches.
- // The user name database contains duplicates, and is not in alphabetical order, so
- // we'll use a set to manage that for us.
- FileSpec::ResolvePartialUsername (partial_name_copy, matches);
- if (matches.GetSize() > 0)
- saw_directory = true;
- return matches.GetSize();
- }
- else
- {
- //The thing exists, put a '/' on the end, and return it...
- // FIXME: complete user names here:
- partial_name_copy[partial_name_len] = '/';
- partial_name_copy[partial_name_len+1] = '\0';
- matches.AppendString(partial_name_copy);
- saw_directory = true;
- return matches.GetSize();
- }
- }
- else
- {
- // The containing part is the CWD, and the whole string is the remainder.
- containing_part = ".";
- strcpy(remainder, partial_name_copy);
- end_ptr = partial_name_copy;
- }
- }
- else
- {
- if (end_ptr == partial_name_copy)
- {
- // We're completing a file or directory in the root volume.
- containing_part = "/";
- }
- else
- {
- containing_part.append(partial_name_copy, end_ptr);
- }
- // Push end_ptr past the final "/" and set remainder.
- end_ptr++;
- strcpy(remainder, end_ptr);
+ } else {
+ // The thing exists, put a '/' on the end, and return it...
+ // FIXME: complete user names here:
+ partial_name_copy[partial_name_len] = '/';
+ partial_name_copy[partial_name_len + 1] = '\0';
+ matches.AppendString(partial_name_copy);
+ saw_directory = true;
+ return matches.GetSize();
+ }
+ } else {
+ // The containing part is the CWD, and the whole string is the remainder.
+ containing_part = ".";
+ strcpy(remainder, partial_name_copy);
+ end_ptr = partial_name_copy;
}
-
- // Look for a user name in the containing part, and if it's there, resolve it and stick the
- // result back into the containing_part:
-
- if (*partial_name_copy == '~')
- {
- FileSpec::ResolveUsername(containing_part);
- // User name doesn't exist, we're not getting any further...
- if (containing_part.empty())
- return matches.GetSize();
+ } else {
+ if (end_ptr == partial_name_copy) {
+ // We're completing a file or directory in the root volume.
+ containing_part = "/";
+ } else {
+ containing_part.append(partial_name_copy, end_ptr);
}
-
- // Okay, containing_part is now the directory we want to open and look for files:
-
- size_t baselen = end_ptr - partial_name_copy;
-
- DiskFilesOrDirectoriesBaton parameters;
- parameters.remainder = remainder;
- parameters.partial_name_copy = partial_name_copy;
- parameters.only_directories = only_directories;
- parameters.saw_directory = &saw_directory;
- parameters.matches = &matches;
- parameters.end_ptr = end_ptr;
- parameters.baselen = baselen;
-
- FileSpec::EnumerateDirectory(containing_part.c_str(), true, true, true, DiskFilesOrDirectoriesCallback, &parameters);
-
- return matches.GetSize();
+ // Push end_ptr past the final "/" and set remainder.
+ end_ptr++;
+ strcpy(remainder, end_ptr);
+ }
+
+ // Look for a user name in the containing part, and if it's there, resolve it
+ // and stick the
+ // result back into the containing_part:
+
+ if (*partial_name_copy == '~') {
+ FileSpec::ResolveUsername(containing_part);
+ // User name doesn't exist, we're not getting any further...
+ if (containing_part.empty())
+ return matches.GetSize();
+ }
+
+ // Okay, containing_part is now the directory we want to open and look for
+ // files:
+
+ size_t baselen = end_ptr - partial_name_copy;
+
+ DiskFilesOrDirectoriesBaton parameters;
+ parameters.remainder = remainder;
+ parameters.partial_name_copy = partial_name_copy;
+ parameters.only_directories = only_directories;
+ parameters.saw_directory = &saw_directory;
+ parameters.matches = &matches;
+ parameters.end_ptr = end_ptr;
+ parameters.baselen = baselen;
+
+ FileSpec::EnumerateDirectory(containing_part.c_str(), true, true, true,
+ DiskFilesOrDirectoriesCallback, &parameters);
+
+ return matches.GetSize();
}
-int
-CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
- const char *partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches)
-{
- int ret_val = DiskFilesOrDirectories (partial_file_name,
- false,
- word_complete,
- matches);
- word_complete = !word_complete;
- return ret_val;
+int CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
+ llvm::StringRef partial_file_name,
+ int match_start_point,
+ int max_return_elements,
+ SearchFilter *searcher, bool &word_complete,
+ StringList &matches) {
+ int ret_val =
+ DiskFilesOrDirectories(partial_file_name, false, word_complete, matches);
+ word_complete = !word_complete;
+ return ret_val;
}
-int
-CommandCompletions::DiskDirectories(CommandInterpreter &interpreter,
- const char *partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches)
-{
- int ret_val = DiskFilesOrDirectories (partial_file_name,
- true,
- word_complete,
- matches);
- word_complete = false;
- return ret_val;
+int CommandCompletions::DiskDirectories(
+ CommandInterpreter &interpreter, llvm::StringRef partial_file_name,
+ int match_start_point, int max_return_elements, SearchFilter *searcher,
+ bool &word_complete, StringList &matches) {
+ int ret_val =
+ DiskFilesOrDirectories(partial_file_name, true, word_complete, matches);
+ word_complete = false;
+ return ret_val;
}
-int
-CommandCompletions::Modules(CommandInterpreter &interpreter,
- const char *partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches)
-{
- word_complete = true;
- ModuleCompleter completer (interpreter,
- partial_file_name,
- match_start_point,
- max_return_elements,
- matches);
-
- if (searcher == nullptr)
- {
- lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
- SearchFilterForUnconstrainedSearches null_searcher (target_sp);
- completer.DoCompletion (&null_searcher);
- }
- else
- {
- completer.DoCompletion (searcher);
- }
- return matches.GetSize();
+int CommandCompletions::Modules(CommandInterpreter &interpreter,
+ llvm::StringRef partial_file_name,
+ int match_start_point, int max_return_elements,
+ SearchFilter *searcher, bool &word_complete,
+ StringList &matches) {
+ word_complete = true;
+ ModuleCompleter completer(interpreter, partial_file_name, match_start_point,
+ max_return_elements, matches);
+
+ if (searcher == nullptr) {
+ lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
+ SearchFilterForUnconstrainedSearches null_searcher(target_sp);
+ completer.DoCompletion(&null_searcher);
+ } else {
+ completer.DoCompletion(searcher);
+ }
+ return matches.GetSize();
}
-int
-CommandCompletions::Symbols(CommandInterpreter &interpreter,
- const char *partial_file_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches)
-{
- word_complete = true;
- SymbolCompleter completer (interpreter,
- partial_file_name,
- match_start_point,
- max_return_elements,
- matches);
-
- if (searcher == nullptr)
- {
- lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
- SearchFilterForUnconstrainedSearches null_searcher (target_sp);
- completer.DoCompletion (&null_searcher);
- }
- else
- {
- completer.DoCompletion (searcher);
- }
- return matches.GetSize();
+int CommandCompletions::Symbols(CommandInterpreter &interpreter,
+ llvm::StringRef partial_file_name,
+ int match_start_point, int max_return_elements,
+ SearchFilter *searcher, bool &word_complete,
+ StringList &matches) {
+ word_complete = true;
+ SymbolCompleter completer(interpreter, partial_file_name, match_start_point,
+ max_return_elements, matches);
+
+ if (searcher == nullptr) {
+ lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget();
+ SearchFilterForUnconstrainedSearches null_searcher(target_sp);
+ completer.DoCompletion(&null_searcher);
+ } else {
+ completer.DoCompletion(searcher);
+ }
+ return matches.GetSize();
}
-int
-CommandCompletions::SettingsNames (CommandInterpreter &interpreter,
- const char *partial_setting_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- StringList &matches)
-{
- // Cache the full setting name list
- static StringList g_property_names;
- if (g_property_names.GetSize() == 0)
- {
- // Generate the full setting name list on demand
- lldb::OptionValuePropertiesSP properties_sp (interpreter.GetDebugger().GetValueProperties());
- if (properties_sp)
- {
- StreamString strm;
- properties_sp->DumpValue(nullptr, strm, OptionValue::eDumpOptionName);
- const std::string &str = strm.GetString();
- g_property_names.SplitIntoLines(str.c_str(), str.size());
- }
+int CommandCompletions::SettingsNames(
+ CommandInterpreter &interpreter, llvm::StringRef partial_setting_name,
+ int match_start_point, int max_return_elements, SearchFilter *searcher,
+ bool &word_complete, StringList &matches) {
+ // Cache the full setting name list
+ static StringList g_property_names;
+ if (g_property_names.GetSize() == 0) {
+ // Generate the full setting name list on demand
+ lldb::OptionValuePropertiesSP properties_sp(
+ interpreter.GetDebugger().GetValueProperties());
+ if (properties_sp) {
+ StreamString strm;
+ properties_sp->DumpValue(nullptr, strm, OptionValue::eDumpOptionName);
+ const std::string &str = strm.GetString();
+ g_property_names.SplitIntoLines(str.c_str(), str.size());
}
-
- size_t exact_matches_idx = SIZE_MAX;
- const size_t num_matches = g_property_names.AutoComplete (partial_setting_name, matches, exact_matches_idx);
- word_complete = exact_matches_idx != SIZE_MAX;
- return num_matches;
+ }
+
+ size_t exact_matches_idx = SIZE_MAX;
+ const size_t num_matches = g_property_names.AutoComplete(
+ partial_setting_name, matches, exact_matches_idx);
+ word_complete = exact_matches_idx != SIZE_MAX;
+ return num_matches;
}
-int
-CommandCompletions::PlatformPluginNames (CommandInterpreter &interpreter,
- const char *partial_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- lldb_private::StringList &matches)
-{
- const uint32_t num_matches = PluginManager::AutoCompletePlatformName(partial_name, matches);
- word_complete = num_matches == 1;
- return num_matches;
+int CommandCompletions::PlatformPluginNames(
+ CommandInterpreter &interpreter, llvm::StringRef partial_name,
+ int match_start_point, int max_return_elements, SearchFilter *searcher,
+ bool &word_complete, lldb_private::StringList &matches) {
+ const uint32_t num_matches =
+ PluginManager::AutoCompletePlatformName(partial_name, matches);
+ word_complete = num_matches == 1;
+ return num_matches;
}
-int
-CommandCompletions::ArchitectureNames (CommandInterpreter &interpreter,
- const char *partial_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- lldb_private::StringList &matches)
-{
- const uint32_t num_matches = ArchSpec::AutoComplete (partial_name, matches);
- word_complete = num_matches == 1;
- return num_matches;
+int CommandCompletions::ArchitectureNames(
+ CommandInterpreter &interpreter, llvm::StringRef partial_name,
+ int match_start_point, int max_return_elements, SearchFilter *searcher,
+ bool &word_complete, lldb_private::StringList &matches) {
+ const uint32_t num_matches = ArchSpec::AutoComplete(partial_name, matches);
+ word_complete = num_matches == 1;
+ return num_matches;
}
-int
-CommandCompletions::VariablePath (CommandInterpreter &interpreter,
- const char *partial_name,
- int match_start_point,
- int max_return_elements,
- SearchFilter *searcher,
- bool &word_complete,
- lldb_private::StringList &matches)
-{
- return Variable::AutoComplete (interpreter.GetExecutionContext(), partial_name, matches, word_complete);
+int CommandCompletions::VariablePath(
+ CommandInterpreter &interpreter, llvm::StringRef partial_name,
+ int match_start_point, int max_return_elements, SearchFilter *searcher,
+ bool &word_complete, lldb_private::StringList &matches) {
+ return Variable::AutoComplete(interpreter.GetExecutionContext(), partial_name,
+ matches, word_complete);
}
CommandCompletions::Completer::Completer(CommandInterpreter &interpreter,
- const char *completion_str,
+ llvm::StringRef completion_str,
int match_start_point,
int max_return_elements,
- StringList &matches) :
- m_interpreter (interpreter),
- m_completion_str (completion_str),
- m_match_start_point (match_start_point),
- m_max_return_elements (max_return_elements),
- m_matches (matches)
-{
-}
+ StringList &matches)
+ : m_interpreter(interpreter), m_completion_str(completion_str),
+ m_match_start_point(match_start_point),
+ m_max_return_elements(max_return_elements), m_matches(matches) {}
CommandCompletions::Completer::~Completer() = default;
@@ -485,237 +404,195 @@ CommandCompletions::Completer::~Completer() = default;
// SourceFileCompleter
//----------------------------------------------------------------------
-CommandCompletions::SourceFileCompleter::SourceFileCompleter(CommandInterpreter &interpreter,
- bool include_support_files,
- const char *completion_str,
- int match_start_point,
- int max_return_elements,
- StringList &matches) :
- CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches),
- m_include_support_files (include_support_files),
- m_matching_files()
-{
- FileSpec partial_spec (m_completion_str.c_str(), false);
- m_file_name = partial_spec.GetFilename().GetCString();
- m_dir_name = partial_spec.GetDirectory().GetCString();
+CommandCompletions::SourceFileCompleter::SourceFileCompleter(
+ CommandInterpreter &interpreter, bool include_support_files,
+ llvm::StringRef completion_str, int match_start_point,
+ int max_return_elements, StringList &matches)
+ : CommandCompletions::Completer(interpreter, completion_str,
+ match_start_point, max_return_elements,
+ matches),
+ m_include_support_files(include_support_files), m_matching_files() {
+ FileSpec partial_spec(m_completion_str, false);
+ m_file_name = partial_spec.GetFilename().GetCString();
+ m_dir_name = partial_spec.GetDirectory().GetCString();
}
-Searcher::Depth
-CommandCompletions::SourceFileCompleter::GetDepth()
-{
- return eDepthCompUnit;
+Searcher::Depth CommandCompletions::SourceFileCompleter::GetDepth() {
+ return eDepthCompUnit;
}
Searcher::CallbackReturn
CommandCompletions::SourceFileCompleter::SearchCallback(SearchFilter &filter,
SymbolContext &context,
Address *addr,
- bool complete)
-{
- if (context.comp_unit != nullptr)
- {
- if (m_include_support_files)
- {
- FileSpecList supporting_files = context.comp_unit->GetSupportFiles();
- for (size_t sfiles = 0; sfiles < supporting_files.GetSize(); sfiles++)
- {
- const FileSpec &sfile_spec = supporting_files.GetFileSpecAtIndex(sfiles);
- const char *sfile_file_name = sfile_spec.GetFilename().GetCString();
- const char *sfile_dir_name = sfile_spec.GetFilename().GetCString();
- bool match = false;
- if (m_file_name && sfile_file_name
- && strstr (sfile_file_name, m_file_name) == sfile_file_name)
- match = true;
- if (match && m_dir_name && sfile_dir_name
- && strstr (sfile_dir_name, m_dir_name) != sfile_dir_name)
- match = false;
-
- if (match)
- {
- m_matching_files.AppendIfUnique(sfile_spec);
- }
- }
- }
- else
- {
- const char *cur_file_name = context.comp_unit->GetFilename().GetCString();
- const char *cur_dir_name = context.comp_unit->GetDirectory().GetCString();
-
- bool match = false;
- if (m_file_name && cur_file_name
- && strstr (cur_file_name, m_file_name) == cur_file_name)
- match = true;
-
- if (match && m_dir_name && cur_dir_name
- && strstr (cur_dir_name, m_dir_name) != cur_dir_name)
- match = false;
-
- if (match)
- {
- m_matching_files.AppendIfUnique(context.comp_unit);
- }
+ bool complete) {
+ if (context.comp_unit != nullptr) {
+ if (m_include_support_files) {
+ FileSpecList supporting_files = context.comp_unit->GetSupportFiles();
+ for (size_t sfiles = 0; sfiles < supporting_files.GetSize(); sfiles++) {
+ const FileSpec &sfile_spec =
+ supporting_files.GetFileSpecAtIndex(sfiles);
+ const char *sfile_file_name = sfile_spec.GetFilename().GetCString();
+ const char *sfile_dir_name = sfile_spec.GetFilename().GetCString();
+ bool match = false;
+ if (m_file_name && sfile_file_name &&
+ strstr(sfile_file_name, m_file_name) == sfile_file_name)
+ match = true;
+ if (match && m_dir_name && sfile_dir_name &&
+ strstr(sfile_dir_name, m_dir_name) != sfile_dir_name)
+ match = false;
+
+ if (match) {
+ m_matching_files.AppendIfUnique(sfile_spec);
}
+ }
+ } else {
+ const char *cur_file_name = context.comp_unit->GetFilename().GetCString();
+ const char *cur_dir_name = context.comp_unit->GetDirectory().GetCString();
+
+ bool match = false;
+ if (m_file_name && cur_file_name &&
+ strstr(cur_file_name, m_file_name) == cur_file_name)
+ match = true;
+
+ if (match && m_dir_name && cur_dir_name &&
+ strstr(cur_dir_name, m_dir_name) != cur_dir_name)
+ match = false;
+
+ if (match) {
+ m_matching_files.AppendIfUnique(context.comp_unit);
+ }
}
- return Searcher::eCallbackReturnContinue;
+ }
+ return Searcher::eCallbackReturnContinue;
}
size_t
-CommandCompletions::SourceFileCompleter::DoCompletion (SearchFilter *filter)
-{
- filter->Search (*this);
- // Now convert the filelist to completions:
- for (size_t i = 0; i < m_matching_files.GetSize(); i++)
- {
- m_matches.AppendString (m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
- }
- return m_matches.GetSize();
+CommandCompletions::SourceFileCompleter::DoCompletion(SearchFilter *filter) {
+ filter->Search(*this);
+ // Now convert the filelist to completions:
+ for (size_t i = 0; i < m_matching_files.GetSize(); i++) {
+ m_matches.AppendString(
+ m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString());
+ }
+ return m_matches.GetSize();
}
//----------------------------------------------------------------------
// SymbolCompleter
//----------------------------------------------------------------------
-static bool
-regex_chars (const char comp)
-{
- return (comp == '[' || comp == ']' ||
- comp == '(' || comp == ')' ||
- comp == '{' || comp == '}' ||
- comp == '+' ||
- comp == '.' ||
- comp == '*' ||
- comp == '|' ||
- comp == '^' ||
- comp == '$' ||
- comp == '\\' ||
- comp == '?');
+static bool regex_chars(const char comp) {
+ return (comp == '[' || comp == ']' || comp == '(' || comp == ')' ||
+ comp == '{' || comp == '}' || comp == '+' || comp == '.' ||
+ comp == '*' || comp == '|' || comp == '^' || comp == '$' ||
+ comp == '\\' || comp == '?');
}
-CommandCompletions::SymbolCompleter::SymbolCompleter(CommandInterpreter &interpreter,
- const char *completion_str,
- int match_start_point,
- int max_return_elements,
- StringList &matches) :
- CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches)
-{
- std::string regex_str;
- if (completion_str && completion_str[0])
- {
- regex_str.append("^");
- regex_str.append(completion_str);
- }
- else
- {
- // Match anything since the completion string is empty
- regex_str.append(".");
- }
- std::string::iterator pos = find_if(regex_str.begin() + 1, regex_str.end(), regex_chars);
- while (pos < regex_str.end())
- {
- pos = regex_str.insert(pos, '\\');
- pos = find_if(pos + 2, regex_str.end(), regex_chars);
- }
- m_regex.Compile(regex_str.c_str());
+CommandCompletions::SymbolCompleter::SymbolCompleter(
+ CommandInterpreter &interpreter, llvm::StringRef completion_str,
+ int match_start_point, int max_return_elements, StringList &matches)
+ : CommandCompletions::Completer(interpreter, completion_str,
+ match_start_point, max_return_elements,
+ matches) {
+ std::string regex_str;
+ if (!completion_str.empty()) {
+ regex_str.append("^");
+ regex_str.append(completion_str);
+ } else {
+ // Match anything since the completion string is empty
+ regex_str.append(".");
+ }
+ std::string::iterator pos =
+ find_if(regex_str.begin() + 1, regex_str.end(), regex_chars);
+ while (pos < regex_str.end()) {
+ pos = regex_str.insert(pos, '\\');
+ pos = find_if(pos + 2, regex_str.end(), regex_chars);
+ }
+ m_regex.Compile(regex_str);
}
-Searcher::Depth
-CommandCompletions::SymbolCompleter::GetDepth()
-{
- return eDepthModule;
+Searcher::Depth CommandCompletions::SymbolCompleter::GetDepth() {
+ return eDepthModule;
}
-Searcher::CallbackReturn
-CommandCompletions::SymbolCompleter::SearchCallback(SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool complete)
-{
- if (context.module_sp)
- {
- SymbolContextList sc_list;
- const bool include_symbols = true;
- const bool include_inlines = true;
- const bool append = true;
- context.module_sp->FindFunctions (m_regex, include_symbols, include_inlines, append, sc_list);
-
- SymbolContext sc;
- // Now add the functions & symbols to the list - only add if unique:
- for (uint32_t i = 0; i < sc_list.GetSize(); i++)
- {
- if (sc_list.GetContextAtIndex(i, sc))
- {
- ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled);
- if (!func_name.IsEmpty())
- m_match_set.insert (func_name);
- }
- }
+Searcher::CallbackReturn CommandCompletions::SymbolCompleter::SearchCallback(
+ SearchFilter &filter, SymbolContext &context, Address *addr,
+ bool complete) {
+ if (context.module_sp) {
+ SymbolContextList sc_list;
+ const bool include_symbols = true;
+ const bool include_inlines = true;
+ const bool append = true;
+ context.module_sp->FindFunctions(m_regex, include_symbols, include_inlines,
+ append, sc_list);
+
+ SymbolContext sc;
+ // Now add the functions & symbols to the list - only add if unique:
+ for (uint32_t i = 0; i < sc_list.GetSize(); i++) {
+ if (sc_list.GetContextAtIndex(i, sc)) {
+ ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled);
+ if (!func_name.IsEmpty())
+ m_match_set.insert(func_name);
+ }
}
- return Searcher::eCallbackReturnContinue;
+ }
+ return Searcher::eCallbackReturnContinue;
}
-size_t
-CommandCompletions::SymbolCompleter::DoCompletion (SearchFilter *filter)
-{
- filter->Search (*this);
- collection::iterator pos = m_match_set.begin(), end = m_match_set.end();
- for (pos = m_match_set.begin(); pos != end; pos++)
- m_matches.AppendString((*pos).GetCString());
-
- return m_matches.GetSize();
+size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) {
+ filter->Search(*this);
+ collection::iterator pos = m_match_set.begin(), end = m_match_set.end();
+ for (pos = m_match_set.begin(); pos != end; pos++)
+ m_matches.AppendString((*pos).GetCString());
+
+ return m_matches.GetSize();
}
//----------------------------------------------------------------------
// ModuleCompleter
//----------------------------------------------------------------------
-CommandCompletions::ModuleCompleter::ModuleCompleter(CommandInterpreter &interpreter,
- const char *completion_str,
- int match_start_point,
- int max_return_elements,
- StringList &matches) :
- CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches)
-{
- FileSpec partial_spec (m_completion_str.c_str(), false);
- m_file_name = partial_spec.GetFilename().GetCString();
- m_dir_name = partial_spec.GetDirectory().GetCString();
+CommandCompletions::ModuleCompleter::ModuleCompleter(
+ CommandInterpreter &interpreter, llvm::StringRef completion_str,
+ int match_start_point, int max_return_elements, StringList &matches)
+ : CommandCompletions::Completer(interpreter, completion_str,
+ match_start_point, max_return_elements,
+ matches) {
+ FileSpec partial_spec(m_completion_str, false);
+ m_file_name = partial_spec.GetFilename().GetCString();
+ m_dir_name = partial_spec.GetDirectory().GetCString();
}
-Searcher::Depth
-CommandCompletions::ModuleCompleter::GetDepth()
-{
- return eDepthModule;
+Searcher::Depth CommandCompletions::ModuleCompleter::GetDepth() {
+ return eDepthModule;
}
-Searcher::CallbackReturn
-CommandCompletions::ModuleCompleter::SearchCallback(SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool complete)
-{
- if (context.module_sp)
- {
- const char *cur_file_name = context.module_sp->GetFileSpec().GetFilename().GetCString();
- const char *cur_dir_name = context.module_sp->GetFileSpec().GetDirectory().GetCString();
-
- bool match = false;
- if (m_file_name && cur_file_name
- && strstr (cur_file_name, m_file_name) == cur_file_name)
- match = true;
-
- if (match && m_dir_name && cur_dir_name
- && strstr (cur_dir_name, m_dir_name) != cur_dir_name)
- match = false;
-
- if (match)
- {
- m_matches.AppendString (cur_file_name);
- }
+Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback(
+ SearchFilter &filter, SymbolContext &context, Address *addr,
+ bool complete) {
+ if (context.module_sp) {
+ const char *cur_file_name =
+ context.module_sp->GetFileSpec().GetFilename().GetCString();
+ const char *cur_dir_name =
+ context.module_sp->GetFileSpec().GetDirectory().GetCString();
+
+ bool match = false;
+ if (m_file_name && cur_file_name &&
+ strstr(cur_file_name, m_file_name) == cur_file_name)
+ match = true;
+
+ if (match && m_dir_name && cur_dir_name &&
+ strstr(cur_dir_name, m_dir_name) != cur_dir_name)
+ match = false;
+
+ if (match) {
+ m_matches.AppendString(cur_file_name);
}
- return Searcher::eCallbackReturnContinue;
+ }
+ return Searcher::eCallbackReturnContinue;
}
-size_t
-CommandCompletions::ModuleCompleter::DoCompletion (SearchFilter *filter)
-{
- filter->Search (*this);
- return m_matches.GetSize();
+size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) {
+ filter->Search(*this);
+ return m_matches.GetSize();
}
diff --git a/source/Commands/CommandObjectApropos.cpp b/source/Commands/CommandObjectApropos.cpp
index 29e1f14e3b28..1114a511aa07 100644
--- a/source/Commands/CommandObjectApropos.cpp
+++ b/source/Commands/CommandObjectApropos.cpp
@@ -1,4 +1,5 @@
-//===-- CommandObjectApropos.cpp ---------------------------------*- C++ -*-===//
+//===-- CommandObjectApropos.cpp ---------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,10 +14,10 @@
// Project includes
#include "CommandObjectApropos.h"
#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/Options.h"
-#include "lldb/Interpreter/Property.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/Property.h"
using namespace lldb;
using namespace lldb_private;
@@ -26,93 +27,86 @@ using namespace lldb_private;
//-------------------------------------------------------------------------
CommandObjectApropos::CommandObjectApropos(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "apropos", "List debugger commands related to a word or subject.", nullptr)
-{
- CommandArgumentEntry arg;
- CommandArgumentData search_word_arg;
+ : CommandObjectParsed(
+ interpreter, "apropos",
+ "List debugger commands related to a word or subject.", nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData search_word_arg;
- // Define the first (and only) variant of this arg.
- search_word_arg.arg_type = eArgTypeSearchWord;
- search_word_arg.arg_repetition = eArgRepeatPlain;
+ // Define the first (and only) variant of this arg.
+ search_word_arg.arg_type = eArgTypeSearchWord;
+ search_word_arg.arg_repetition = eArgRepeatPlain;
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (search_word_arg);
+ // There is only one variant this argument could be; put it into the argument
+ // entry.
+ arg.push_back(search_word_arg);
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
}
CommandObjectApropos::~CommandObjectApropos() = default;
-bool
-CommandObjectApropos::DoExecute (Args& args, CommandReturnObject &result)
-{
- const size_t argc = args.GetArgumentCount ();
-
- if (argc == 1)
- {
- const char *search_word = args.GetArgumentAtIndex(0);
- if ((search_word != nullptr)
- && (strlen (search_word) > 0))
- {
- // The bulk of the work must be done inside the Command Interpreter, since the command dictionary
- // is private.
- StringList commands_found;
- StringList commands_help;
-
- m_interpreter.FindCommandsForApropos (search_word, commands_found, commands_help, true, true, true);
-
- if (commands_found.GetSize() == 0)
- {
- result.AppendMessageWithFormat ("No commands found pertaining to '%s'. Try 'help' to see a complete list of debugger commands.\n", search_word);
- }
- else
- {
- if (commands_found.GetSize() > 0)
- {
- result.AppendMessageWithFormat ("The following commands may relate to '%s':\n", search_word);
- size_t max_len = 0;
-
- for (size_t i = 0; i < commands_found.GetSize(); ++i)
- {
- size_t len = strlen (commands_found.GetStringAtIndex (i));
- if (len > max_len)
- max_len = len;
- }
-
- for (size_t i = 0; i < commands_found.GetSize(); ++i)
- m_interpreter.OutputFormattedHelpText (result.GetOutputStream(),
- commands_found.GetStringAtIndex(i),
- "--",
- commands_help.GetStringAtIndex(i),
- max_len);
- }
- }
-
- std::vector<const Property *> properties;
- const size_t num_properties = m_interpreter.GetDebugger().Apropos(search_word, properties);
- if (num_properties)
- {
- const bool dump_qualified_name = true;
- result.AppendMessageWithFormat ("\nThe following settings variables may relate to '%s': \n\n", search_word);
- for (size_t i=0; i<num_properties; ++i)
- properties[i]->DumpDescription (m_interpreter, result.GetOutputStream(), 0, dump_qualified_name);
-
- }
-
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError ("'' is not a valid search word.\n");
- result.SetStatus (eReturnStatusFailed);
+bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) {
+ const size_t argc = args.GetArgumentCount();
+
+ if (argc == 1) {
+ auto search_word = args[0].ref;
+ if (!search_word.empty()) {
+ // The bulk of the work must be done inside the Command Interpreter, since
+ // the command dictionary is private.
+ StringList commands_found;
+ StringList commands_help;
+
+ m_interpreter.FindCommandsForApropos(search_word, commands_found,
+ commands_help, true, true, true);
+
+ if (commands_found.GetSize() == 0) {
+ result.AppendMessageWithFormat("No commands found pertaining to '%s'. "
+ "Try 'help' to see a complete list of "
+ "debugger commands.\n",
+ args[0].c_str());
+ } else {
+ if (commands_found.GetSize() > 0) {
+ result.AppendMessageWithFormat(
+ "The following commands may relate to '%s':\n", args[0].c_str());
+ size_t max_len = 0;
+
+ for (size_t i = 0; i < commands_found.GetSize(); ++i) {
+ size_t len = strlen(commands_found.GetStringAtIndex(i));
+ if (len > max_len)
+ max_len = len;
+ }
+
+ for (size_t i = 0; i < commands_found.GetSize(); ++i)
+ m_interpreter.OutputFormattedHelpText(
+ result.GetOutputStream(), commands_found.GetStringAtIndex(i),
+ "--", commands_help.GetStringAtIndex(i), max_len);
}
+ }
+
+ std::vector<const Property *> properties;
+ const size_t num_properties =
+ m_interpreter.GetDebugger().Apropos(search_word, properties);
+ if (num_properties) {
+ const bool dump_qualified_name = true;
+ result.AppendMessageWithFormatv(
+ "\nThe following settings variables may relate to '{0}': \n\n",
+ args[0].ref);
+ for (size_t i = 0; i < num_properties; ++i)
+ properties[i]->DumpDescription(
+ m_interpreter, result.GetOutputStream(), 0, dump_qualified_name);
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("'' is not a valid search word.\n");
+ result.SetStatus(eReturnStatusFailed);
}
- else
- {
- result.AppendError ("'apropos' must be called with exactly one argument.\n");
- result.SetStatus (eReturnStatusFailed);
- }
+ } else {
+ result.AppendError("'apropos' must be called with exactly one argument.\n");
+ result.SetStatus(eReturnStatusFailed);
+ }
- return result.Succeeded();
+ return result.Succeeded();
}
diff --git a/source/Commands/CommandObjectApropos.h b/source/Commands/CommandObjectApropos.h
index d04620bc5f2d..5cad40d5c62d 100644
--- a/source/Commands/CommandObjectApropos.h
+++ b/source/Commands/CommandObjectApropos.h
@@ -1,4 +1,5 @@
-//===-- CommandObjectApropos.h -----------------------------------*- C++ -*-===//
+//===-- CommandObjectApropos.h -----------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -22,18 +23,14 @@ namespace lldb_private {
// CommandObjectApropos
//-------------------------------------------------------------------------
-class CommandObjectApropos : public CommandObjectParsed
-{
+class CommandObjectApropos : public CommandObjectParsed {
public:
+ CommandObjectApropos(CommandInterpreter &interpreter);
- CommandObjectApropos (CommandInterpreter &interpreter);
-
- ~CommandObjectApropos() override;
+ ~CommandObjectApropos() override;
protected:
- bool
- DoExecute(Args& command,
- CommandReturnObject &result) override;
+ bool DoExecute(Args &command, CommandReturnObject &result) override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectArgs.cpp b/source/Commands/CommandObjectArgs.cpp
index 206a26f45e4d..d98a246e9684 100644
--- a/source/Commands/CommandObjectArgs.cpp
+++ b/source/Commands/CommandObjectArgs.cpp
@@ -12,12 +12,12 @@
// Other libraries and framework includes
// Project includes
#include "CommandObjectArgs.h"
-#include "lldb/Interpreter/Args.h"
+#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
-#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
#include "lldb/Host/Host.h"
+#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -25,237 +25,209 @@
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Target/StackFrame.h"
+
+#include "llvm/ADT/StringSwitch.h"
using namespace lldb;
using namespace lldb_private;
-// This command is a toy. I'm just using it to have a way to construct the arguments to
+// This command is a toy. I'm just using it to have a way to construct the
+// arguments to
// calling functions.
//
-CommandObjectArgs::CommandOptions::CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
-{
- // Keep only one place to reset the values to their defaults
- OptionParsingStarting();
+static OptionDefinition g_arg_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation." },
+ // clang-format on
+};
+
+CommandObjectArgs::CommandOptions::CommandOptions(
+ CommandInterpreter &interpreter)
+ : Options() {
+ // Keep only one place to reset the values to their defaults
+ OptionParsingStarting(nullptr);
}
CommandObjectArgs::CommandOptions::~CommandOptions() = default;
-Error
-CommandObjectArgs::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
-{
- Error error;
-
- const int short_option = m_getopt_table[option_idx].val;
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
-
- return error;
-}
+Error CommandObjectArgs::CommandOptions::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Error error;
-void
-CommandObjectArgs::CommandOptions::OptionParsingStarting ()
-{
-}
+ const int short_option = m_getopt_table[option_idx].val;
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
-const OptionDefinition*
-CommandObjectArgs::CommandOptions::GetDefinitions ()
-{
- return g_option_table;
+ return error;
}
-CommandObjectArgs::CommandObjectArgs (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "args",
- "When stopped at the start of a function, reads function arguments of type (u?)int(8|16|32|64)_t, (void|char)*",
- "args"),
- m_options (interpreter)
-{
-}
+void CommandObjectArgs::CommandOptions::OptionParsingStarting(
+ ExecutionContext *execution_context) {}
-CommandObjectArgs::~CommandObjectArgs() = default;
-
-Options *
-CommandObjectArgs::GetOptions ()
-{
- return &m_options;
+llvm::ArrayRef<OptionDefinition>
+CommandObjectArgs::CommandOptions::GetDefinitions() {
+ return llvm::makeArrayRef(g_arg_options);
}
-bool
-CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result)
-{
- ConstString target_triple;
+CommandObjectArgs::CommandObjectArgs(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "args",
+ "When stopped at the start of a function, reads "
+ "function arguments of type (u?)int(8|16|32|64)_t, "
+ "(void|char)*",
+ "args"),
+ m_options(interpreter) {}
- Process *process = m_exe_ctx.GetProcessPtr();
- if (!process)
- {
- result.AppendError ("Args found no process.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- const ABI *abi = process->GetABI().get();
- if (!abi)
- {
- result.AppendError ("The current process has no ABI.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- const size_t num_args = args.GetArgumentCount ();
- size_t arg_index;
-
- if (!num_args)
- {
- result.AppendError ("args requires at least one argument");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- Thread *thread = m_exe_ctx.GetThreadPtr();
-
- if (!thread)
- {
- result.AppendError ("args found no thread.");
- result.SetStatus (eReturnStatusFailed);
+CommandObjectArgs::~CommandObjectArgs() = default;
+
+Options *CommandObjectArgs::GetOptions() { return &m_options; }
+
+bool CommandObjectArgs::DoExecute(Args &args, CommandReturnObject &result) {
+ ConstString target_triple;
+
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (!process) {
+ result.AppendError("Args found no process.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const ABI *abi = process->GetABI().get();
+ if (!abi) {
+ result.AppendError("The current process has no ABI.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (args.empty()) {
+ result.AppendError("args requires at least one argument");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+
+ if (!thread) {
+ result.AppendError("args found no thread.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame();
+ if (!thread_cur_frame) {
+ result.AppendError("The current thread has no current frame.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ModuleSP thread_module_sp(
+ thread_cur_frame->GetFrameCodeAddress().GetModule());
+ if (!thread_module_sp) {
+ result.AppendError("The PC has no associated module.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ TypeSystem *type_system =
+ thread_module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
+ if (type_system == nullptr) {
+ result.AppendError("Unable to create C type system.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ValueList value_list;
+
+ for (auto &arg_entry : args.entries()) {
+ llvm::StringRef arg_type = arg_entry.ref;
+ Value value;
+ value.SetValueType(Value::eValueTypeScalar);
+ CompilerType compiler_type;
+
+ std::size_t int_pos = arg_type.find("int");
+ if (int_pos != llvm::StringRef::npos) {
+ Encoding encoding = eEncodingSint;
+
+ int width = 0;
+
+ if (int_pos > 1) {
+ result.AppendErrorWithFormat("Invalid format: %s.\n",
+ arg_entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
return false;
- }
-
- lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame ();
- if (!thread_cur_frame)
- {
- result.AppendError ("The current thread has no current frame.");
- result.SetStatus (eReturnStatusFailed);
+ }
+ if (int_pos == 1 && arg_type[0] != 'u') {
+ result.AppendErrorWithFormat("Invalid format: %s.\n",
+ arg_entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
return false;
- }
-
- ModuleSP thread_module_sp (thread_cur_frame->GetFrameCodeAddress ().GetModule());
- if (!thread_module_sp)
- {
- result.AppendError ("The PC has no associated module.");
- result.SetStatus (eReturnStatusFailed);
+ }
+ if (arg_type[0] == 'u') {
+ encoding = eEncodingUint;
+ }
+
+ llvm::StringRef width_spec = arg_type.drop_front(int_pos + 3);
+
+ auto exp_result = llvm::StringSwitch<llvm::Optional<int>>(width_spec)
+ .Case("8_t", 8)
+ .Case("16_t", 16)
+ .Case("32_t", 32)
+ .Case("64_t", 64)
+ .Default(llvm::None);
+ if (!exp_result.hasValue()) {
+ result.AppendErrorWithFormat("Invalid format: %s.\n",
+ arg_entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
return false;
- }
+ }
+ width = *exp_result;
- TypeSystem *type_system = thread_module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
- if (type_system == nullptr)
- {
- result.AppendError ("Unable to create C type system.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- ValueList value_list;
-
- for (arg_index = 0; arg_index < num_args; ++arg_index)
- {
- const char *arg_type_cstr = args.GetArgumentAtIndex(arg_index);
- Value value;
- value.SetValueType(Value::eValueTypeScalar);
- CompilerType compiler_type;
-
- char *int_pos;
- if ((int_pos = strstr (const_cast<char*>(arg_type_cstr), "int")))
- {
- Encoding encoding = eEncodingSint;
-
- int width = 0;
-
- if (int_pos > arg_type_cstr + 1)
- {
- result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (int_pos == arg_type_cstr + 1 && arg_type_cstr[0] != 'u')
- {
- result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (arg_type_cstr[0] == 'u')
- {
- encoding = eEncodingUint;
- }
-
- char *width_pos = int_pos + 3;
-
- if (!strcmp (width_pos, "8_t"))
- width = 8;
- else if (!strcmp (width_pos, "16_t"))
- width = 16;
- else if (!strcmp (width_pos, "32_t"))
- width = 32;
- else if (!strcmp (width_pos, "64_t"))
- width = 64;
- else
- {
- result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(encoding, width);
-
- if (!compiler_type.IsValid())
- {
- result.AppendErrorWithFormat ("Couldn't get Clang type for format %s (%s integer, width %d).\n",
- arg_type_cstr,
- (encoding == eEncodingSint ? "signed" : "unsigned"),
- width);
-
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else if (strchr (arg_type_cstr, '*'))
- {
- if (!strcmp (arg_type_cstr, "void*"))
- compiler_type = type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
- else if (!strcmp (arg_type_cstr, "char*"))
- compiler_type = type_system->GetBasicTypeFromAST(eBasicTypeChar).GetPointerType();
- else
- {
- result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- value.SetCompilerType (compiler_type);
- value_list.PushValue(value);
- }
-
- if (!abi->GetArgumentValues (*thread, value_list))
- {
- result.AppendError ("Couldn't get argument values");
- result.SetStatus (eReturnStatusFailed);
+ compiler_type =
+ type_system->GetBuiltinTypeForEncodingAndBitSize(encoding, width);
+
+ if (!compiler_type.IsValid()) {
+ result.AppendErrorWithFormat(
+ "Couldn't get Clang type for format %s (%s integer, width %d).\n",
+ arg_entry.c_str(),
+ (encoding == eEncodingSint ? "signed" : "unsigned"), width);
+
+ result.SetStatus(eReturnStatusFailed);
return false;
+ }
+ } else if (arg_type == "void*") {
+ compiler_type =
+ type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
+ } else if (arg_type == "char*") {
+ compiler_type =
+ type_system->GetBasicTypeFromAST(eBasicTypeChar).GetPointerType();
+ } else {
+ result.AppendErrorWithFormat("Invalid format: %s.\n", arg_entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- result.GetOutputStream ().Printf("Arguments : \n");
-
- for (arg_index = 0; arg_index < num_args; ++arg_index)
- {
- result.GetOutputStream ().Printf ("%" PRIu64 " (%s): ", (uint64_t)arg_index, args.GetArgumentAtIndex (arg_index));
- value_list.GetValueAtIndex (arg_index)->Dump (&result.GetOutputStream ());
- result.GetOutputStream ().Printf("\n");
- }
-
- return result.Succeeded();
-}
-OptionDefinition
-CommandObjectArgs::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
-};
+ value.SetCompilerType(compiler_type);
+ value_list.PushValue(value);
+ }
+
+ if (!abi->GetArgumentValues(*thread, value_list)) {
+ result.AppendError("Couldn't get argument values");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ result.GetOutputStream().Printf("Arguments : \n");
+
+ for (auto entry : llvm::enumerate(args.entries())) {
+ result.GetOutputStream().Printf("%" PRIu64 " (%s): ", (uint64_t)entry.Index,
+ entry.Value.c_str());
+ value_list.GetValueAtIndex(entry.Index)->Dump(&result.GetOutputStream());
+ result.GetOutputStream().Printf("\n");
+ }
+
+ return result.Succeeded();
+}
diff --git a/source/Commands/CommandObjectArgs.h b/source/Commands/CommandObjectArgs.h
index 4a4e1c35cf31..a4b3f9fed0ee 100644
--- a/source/Commands/CommandObjectArgs.h
+++ b/source/Commands/CommandObjectArgs.h
@@ -18,49 +18,35 @@
#include "lldb/Interpreter/Options.h"
namespace lldb_private {
-
- class CommandObjectArgs : public CommandObjectParsed
- {
- public:
-
- class CommandOptions : public Options
- {
- public:
-
- CommandOptions (CommandInterpreter &interpreter);
-
- ~CommandOptions() override;
-
- Error
- SetOptionValue(uint32_t option_idx, const char *option_arg) override;
-
- void
- OptionParsingStarting() override;
-
- const OptionDefinition*
- GetDefinitions() override;
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
- };
-
- CommandObjectArgs (CommandInterpreter &interpreter);
-
- ~CommandObjectArgs() override;
-
- Options *
- GetOptions() override;
-
- protected:
-
- CommandOptions m_options;
- bool
- DoExecute(Args& command,
- CommandReturnObject &result) override;
- };
-
+class CommandObjectArgs : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions(CommandInterpreter &interpreter);
+
+ ~CommandOptions() override;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+ };
+
+ CommandObjectArgs(CommandInterpreter &interpreter);
+
+ ~CommandObjectArgs() override;
+
+ Options *GetOptions() override;
+
+protected:
+ CommandOptions m_options;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override;
+};
+
} // namespace lldb_private
#endif // liblldb_CommandObjectArgs_h_
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index 6a71389a3f69..941dd9a7849a 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -18,1174 +18,1033 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Host/StringConvert.h"
-#include "lldb/Interpreter/Options.h"
-#include "lldb/Interpreter/OptionValueBoolean.h"
-#include "lldb/Interpreter/OptionValueString.h"
-#include "lldb/Interpreter/OptionValueUInt64.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/OptionValueUInt64.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Target/Language.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
using namespace lldb;
using namespace lldb_private;
-static void
-AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
-{
- s->IndentMore();
- bp->GetDescription (s, level, true);
- s->IndentLess();
- s->EOL();
+static void AddBreakpointDescription(Stream *s, Breakpoint *bp,
+ lldb::DescriptionLevel level) {
+ s->IndentMore();
+ bp->GetDescription(s, level, true);
+ s->IndentLess();
+ s->EOL();
}
+// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
+// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
+#define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2)
+#define LLDB_OPT_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10)
+#define LLDB_OPT_SKIP_PROLOGUE (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8))
+#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8))
+#define LLDB_OPT_MOVE_TO_NEAREST_CODE (LLDB_OPT_SET_1 | LLDB_OPT_SET_9)
+#define LLDB_OPT_EXPR_LANGUAGE (LLDB_OPT_SET_FROM_TO(3, 8))
+
+static OptionDefinition g_breakpoint_set_options[] = {
+ // clang-format off
+ { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option "
+ "multiple times to specify multiple shared libraries." },
+ { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
+ { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The breakpoint is deleted the first time it causes a stop." },
+ { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
+ { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this "
+ "argument." },
+ { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." },
+ { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by "
+ "this argument." },
+ { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default "
+ "lldb only looks for files that are #included if they use the standard include "
+ "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are "
+ "#included, set target.inline-breakpoint-strategy to \"always\"." },
+ { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." },
+
+ // Comment out this option for the moment, as we don't actually use it, but will in the future.
+ // This way users won't see it, but the infrastructure is left in place.
+ // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
+ // "Set the breakpoint by source location at this particular column."},
+
+ { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to "
+ "a particular binary, then the address will be converted to a \"file\" "
+ "address, so that the breakpoint will track that binary+offset no matter where "
+ "the binary eventually loads. Alternately, if you also specify the module - "
+ "with the -s option - then the address will be treated as a file address in "
+ "that module, and resolved accordingly. Again, this will allow lldb to track "
+ "that offset on subsequent reloads. The module need not have been loaded at "
+ "the time you specify this breakpoint, and will get resolved when the module "
+ "is loaded." },
+ { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make "
+ "one breakpoint for multiple names" },
+ { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named "
+ "functions. Can be repeated multiple times." },
+ { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means "
+ "namespaces and all arguments, and for Objective C this means a full function "
+ "prototype with class and selector. Can be repeated multiple times to make "
+ "one breakpoint for multiple names." },
+ { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to "
+ "make one breakpoint for multiple Selectors." },
+ { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to "
+ "make one breakpoint for multiple methods." },
+ { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find "
+ "the function name(s)." },
+ { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be "
+ "ignored). Can be repeated multiple times to make one breakpoint for multiple "
+ "symbols." },
+ { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched "
+ "against the source text in a source file or files specified with the -f "
+ "option. The -f option can be specified more than once. If no source files "
+ "are specified, uses the current \"default source file\". If you want to "
+ "match against all source files, pass the \"--all-files\" option." },
+ { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "All files are searched for source pattern matches." },
+ { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without "
+ "options, on throw but not catch.)" },
+ { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." },
+ { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." },
+
+ // Don't add this option till it actually does something useful...
+ // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
+ // "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
+
+ { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression "
+ "(note: currently only implemented for setting breakpoints on identifiers). "
+ "If not set the target.language setting is used." },
+ { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. "
+ "If not set the target.skip-prologue setting is used." },
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, "
+ "which prime new targets." },
+ { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." },
+ { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. "
+ "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." },
+ { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code "
+ "setting is used." },
+ // clang-format on
+};
+
//-------------------------------------------------------------------------
// CommandObjectBreakpointSet
//-------------------------------------------------------------------------
-class CommandObjectBreakpointSet : public CommandObjectParsed
-{
+class CommandObjectBreakpointSet : public CommandObjectParsed {
public:
- typedef enum BreakpointSetType
- {
- eSetTypeInvalid,
- eSetTypeFileAndLine,
- eSetTypeAddress,
- eSetTypeFunctionName,
- eSetTypeFunctionRegexp,
- eSetTypeSourceRegexp,
- eSetTypeException
- } BreakpointSetType;
-
- CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "breakpoint set",
- "Sets a breakpoint or set of breakpoints in the executable.",
- "breakpoint set <cmd-options>"),
- m_options (interpreter)
- {
+ typedef enum BreakpointSetType {
+ eSetTypeInvalid,
+ eSetTypeFileAndLine,
+ eSetTypeAddress,
+ eSetTypeFunctionName,
+ eSetTypeFunctionRegexp,
+ eSetTypeSourceRegexp,
+ eSetTypeException
+ } BreakpointSetType;
+
+ CommandObjectBreakpointSet(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "breakpoint set",
+ "Sets a breakpoint or set of breakpoints in the executable.",
+ "breakpoint set <cmd-options>"),
+ m_options() {}
+
+ ~CommandObjectBreakpointSet() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_condition(), m_filenames(), m_line_num(0), m_column(0),
+ m_func_names(), m_func_name_type_mask(eFunctionNameTypeNone),
+ m_func_regexp(), m_source_text_regexp(), m_modules(), m_load_addr(),
+ m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
+ m_thread_index(UINT32_MAX), m_thread_name(), m_queue_name(),
+ m_catch_bp(false), m_throw_bp(true), m_hardware(false),
+ m_exception_language(eLanguageTypeUnknown),
+ m_language(lldb::eLanguageTypeUnknown),
+ m_skip_prologue(eLazyBoolCalculate), m_one_shot(false),
+ m_all_files(false), m_move_to_nearest_code(eLazyBoolCalculate) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'a': {
+ m_load_addr = Args::StringToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
+ } break;
+
+ case 'A':
+ m_all_files = true;
+ break;
+
+ case 'b':
+ m_func_names.push_back(option_arg);
+ m_func_name_type_mask |= eFunctionNameTypeBase;
+ break;
+
+ case 'C':
+ if (option_arg.getAsInteger(0, m_column))
+ error.SetErrorStringWithFormat("invalid column number: %s",
+ option_arg.str().c_str());
+ break;
+
+ case 'c':
+ m_condition.assign(option_arg);
+ break;
+
+ case 'D':
+ m_use_dummy = true;
+ break;
+
+ case 'E': {
+ LanguageType language = Language::GetLanguageTypeFromString(option_arg);
+
+ switch (language) {
+ case eLanguageTypeC89:
+ case eLanguageTypeC:
+ case eLanguageTypeC99:
+ case eLanguageTypeC11:
+ m_exception_language = eLanguageTypeC;
+ break;
+ case eLanguageTypeC_plus_plus:
+ case eLanguageTypeC_plus_plus_03:
+ case eLanguageTypeC_plus_plus_11:
+ case eLanguageTypeC_plus_plus_14:
+ m_exception_language = eLanguageTypeC_plus_plus;
+ break;
+ case eLanguageTypeObjC:
+ m_exception_language = eLanguageTypeObjC;
+ break;
+ case eLanguageTypeObjC_plus_plus:
+ error.SetErrorStringWithFormat(
+ "Set exception breakpoints separately for c++ and objective-c");
+ break;
+ case eLanguageTypeUnknown:
+ error.SetErrorStringWithFormat(
+ "Unknown language type: '%s' for exception breakpoint",
+ option_arg.str().c_str());
+ break;
+ default:
+ error.SetErrorStringWithFormat(
+ "Unsupported language type: '%s' for exception breakpoint",
+ option_arg.str().c_str());
+ }
+ } break;
+
+ case 'f':
+ m_filenames.AppendIfUnique(FileSpec(option_arg, false));
+ break;
+
+ case 'F':
+ m_func_names.push_back(option_arg);
+ m_func_name_type_mask |= eFunctionNameTypeFull;
+ break;
+
+ case 'h': {
+ bool success;
+ m_catch_bp = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for on-catch option: '%s'",
+ option_arg.str().c_str());
+ } break;
+
+ case 'H':
+ m_hardware = true;
+ break;
+
+ case 'i':
+ if (option_arg.getAsInteger(0, m_ignore_count))
+ error.SetErrorStringWithFormat("invalid ignore count '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'K': {
+ bool success;
+ bool value;
+ value = Args::StringToBoolean(option_arg, true, &success);
+ if (value)
+ m_skip_prologue = eLazyBoolYes;
+ else
+ m_skip_prologue = eLazyBoolNo;
+
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for skip prologue option: '%s'",
+ option_arg.str().c_str());
+ } break;
+
+ case 'l':
+ if (option_arg.getAsInteger(0, m_line_num))
+ error.SetErrorStringWithFormat("invalid line number: %s.",
+ option_arg.str().c_str());
+ break;
+
+ case 'L':
+ m_language = Language::GetLanguageTypeFromString(option_arg);
+ if (m_language == eLanguageTypeUnknown)
+ error.SetErrorStringWithFormat(
+ "Unknown language type: '%s' for breakpoint",
+ option_arg.str().c_str());
+ break;
+
+ case 'm': {
+ bool success;
+ bool value;
+ value = Args::StringToBoolean(option_arg, true, &success);
+ if (value)
+ m_move_to_nearest_code = eLazyBoolYes;
+ else
+ m_move_to_nearest_code = eLazyBoolNo;
+
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for move-to-nearest-code option: '%s'",
+ option_arg.str().c_str());
+ break;
+ }
+
+ case 'M':
+ m_func_names.push_back(option_arg);
+ m_func_name_type_mask |= eFunctionNameTypeMethod;
+ break;
+
+ case 'n':
+ m_func_names.push_back(option_arg);
+ m_func_name_type_mask |= eFunctionNameTypeAuto;
+ break;
+
+ case 'N': {
+ if (BreakpointID::StringIsBreakpointName(option_arg, error))
+ m_breakpoint_names.push_back(option_arg);
+ else
+ error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
+ option_arg.str().c_str());
+ break;
+ }
+
+ case 'R': {
+ lldb::addr_t tmp_offset_addr;
+ tmp_offset_addr =
+ Args::StringToAddress(execution_context, option_arg, 0, &error);
+ if (error.Success())
+ m_offset_addr = tmp_offset_addr;
+ } break;
+
+ case 'o':
+ m_one_shot = true;
+ break;
+
+ case 'O':
+ m_exception_extra_args.AppendArgument("-O");
+ m_exception_extra_args.AppendArgument(option_arg);
+ break;
+
+ case 'p':
+ m_source_text_regexp.assign(option_arg);
+ break;
+
+ case 'q':
+ m_queue_name.assign(option_arg);
+ break;
+
+ case 'r':
+ m_func_regexp.assign(option_arg);
+ break;
+
+ case 's':
+ m_modules.AppendIfUnique(FileSpec(option_arg, false));
+ break;
+
+ case 'S':
+ m_func_names.push_back(option_arg);
+ m_func_name_type_mask |= eFunctionNameTypeSelector;
+ break;
+
+ case 't':
+ if (option_arg.getAsInteger(0, m_thread_id))
+ error.SetErrorStringWithFormat("invalid thread id string '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'T':
+ m_thread_name.assign(option_arg);
+ break;
+
+ case 'w': {
+ bool success;
+ m_throw_bp = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for on-throw option: '%s'",
+ option_arg.str().c_str());
+ } break;
+
+ case 'x':
+ if (option_arg.getAsInteger(0, m_thread_index))
+ error.SetErrorStringWithFormat("invalid thread index string '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'X':
+ m_source_regex_func_names.insert(option_arg);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectBreakpointSet() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_condition.clear();
+ m_filenames.Clear();
+ m_line_num = 0;
+ m_column = 0;
+ m_func_names.clear();
+ m_func_name_type_mask = eFunctionNameTypeNone;
+ m_func_regexp.clear();
+ m_source_text_regexp.clear();
+ m_modules.Clear();
+ m_load_addr = LLDB_INVALID_ADDRESS;
+ m_offset_addr = 0;
+ m_ignore_count = 0;
+ m_thread_id = LLDB_INVALID_THREAD_ID;
+ m_thread_index = UINT32_MAX;
+ m_thread_name.clear();
+ m_queue_name.clear();
+ m_catch_bp = false;
+ m_throw_bp = true;
+ m_hardware = false;
+ m_exception_language = eLanguageTypeUnknown;
+ m_language = lldb::eLanguageTypeUnknown;
+ m_skip_prologue = eLazyBoolCalculate;
+ m_one_shot = false;
+ m_use_dummy = false;
+ m_breakpoint_names.clear();
+ m_all_files = false;
+ m_exception_extra_args.Clear();
+ m_move_to_nearest_code = eLazyBoolCalculate;
+ m_source_regex_func_names.clear();
}
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_condition (),
- m_filenames (),
- m_line_num (0),
- m_column (0),
- m_func_names (),
- m_func_name_type_mask (eFunctionNameTypeNone),
- m_func_regexp (),
- m_source_text_regexp(),
- m_modules (),
- m_load_addr(),
- m_ignore_count (0),
- m_thread_id(LLDB_INVALID_THREAD_ID),
- m_thread_index (UINT32_MAX),
- m_thread_name(),
- m_queue_name(),
- m_catch_bp (false),
- m_throw_bp (true),
- m_hardware (false),
- m_exception_language (eLanguageTypeUnknown),
- m_language (lldb::eLanguageTypeUnknown),
- m_skip_prologue (eLazyBoolCalculate),
- m_one_shot (false),
- m_all_files (false),
- m_move_to_nearest_code (eLazyBoolCalculate)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'a':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- }
- break;
-
- case 'A':
- m_all_files = true;
- break;
-
- case 'b':
- m_func_names.push_back (option_arg);
- m_func_name_type_mask |= eFunctionNameTypeBase;
- break;
-
- case 'C':
- {
- bool success;
- m_column = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid column number: %s", option_arg);
- break;
- }
-
- case 'c':
- m_condition.assign(option_arg);
- break;
-
- case 'D':
- m_use_dummy = true;
- break;
-
- case 'E':
- {
- LanguageType language = Language::GetLanguageTypeFromString (option_arg);
-
- switch (language)
- {
- case eLanguageTypeC89:
- case eLanguageTypeC:
- case eLanguageTypeC99:
- case eLanguageTypeC11:
- m_exception_language = eLanguageTypeC;
- break;
- case eLanguageTypeC_plus_plus:
- case eLanguageTypeC_plus_plus_03:
- case eLanguageTypeC_plus_plus_11:
- case eLanguageTypeC_plus_plus_14:
- m_exception_language = eLanguageTypeC_plus_plus;
- break;
- case eLanguageTypeObjC:
- m_exception_language = eLanguageTypeObjC;
- break;
- case eLanguageTypeObjC_plus_plus:
- error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
- break;
- case eLanguageTypeUnknown:
- error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
- break;
- default:
- error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
- }
- }
- break;
-
- case 'f':
- m_filenames.AppendIfUnique (FileSpec(option_arg, false));
- break;
-
- case 'F':
- m_func_names.push_back (option_arg);
- m_func_name_type_mask |= eFunctionNameTypeFull;
- break;
-
- case 'h':
- {
- bool success;
- m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
- }
- break;
-
- case 'H':
- m_hardware = true;
- break;
-
- case 'i':
- m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (m_ignore_count == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
- break;
-
- case 'K':
- {
- bool success;
- bool value;
- value = Args::StringToBoolean (option_arg, true, &success);
- if (value)
- m_skip_prologue = eLazyBoolYes;
- else
- m_skip_prologue = eLazyBoolNo;
-
- if (!success)
- error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
- }
- break;
-
- case 'l':
- {
- bool success;
- m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat ("invalid line number: %s.", option_arg);
- break;
- }
-
- case 'L':
- m_language = Language::GetLanguageTypeFromString (option_arg);
- if (m_language == eLanguageTypeUnknown)
- error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg);
- break;
-
- case 'm':
- {
- bool success;
- bool value;
- value = Args::StringToBoolean (option_arg, true, &success);
- if (value)
- m_move_to_nearest_code = eLazyBoolYes;
- else
- m_move_to_nearest_code = eLazyBoolNo;
-
- if (!success)
- error.SetErrorStringWithFormat ("Invalid boolean value for move-to-nearest-code option: '%s'", option_arg);
- break;
- }
-
- case 'M':
- m_func_names.push_back (option_arg);
- m_func_name_type_mask |= eFunctionNameTypeMethod;
- break;
-
- case 'n':
- m_func_names.push_back (option_arg);
- m_func_name_type_mask |= eFunctionNameTypeAuto;
- break;
-
- case 'N':
- if (BreakpointID::StringIsBreakpointName(option_arg, error))
- m_breakpoint_names.push_back (option_arg);
- break;
-
- case 'R':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- lldb::addr_t tmp_offset_addr;
- tmp_offset_addr = Args::StringToAddress(&exe_ctx, option_arg, 0, &error);
- if (error.Success())
- m_offset_addr = tmp_offset_addr;
- }
- break;
-
- case 'o':
- m_one_shot = true;
- break;
-
- case 'O':
- m_exception_extra_args.AppendArgument ("-O");
- m_exception_extra_args.AppendArgument (option_arg);
- break;
-
- case 'p':
- m_source_text_regexp.assign (option_arg);
- break;
-
- case 'q':
- m_queue_name.assign (option_arg);
- break;
-
- case 'r':
- m_func_regexp.assign (option_arg);
- break;
-
- case 's':
- m_modules.AppendIfUnique (FileSpec (option_arg, false));
- break;
-
- case 'S':
- m_func_names.push_back (option_arg);
- m_func_name_type_mask |= eFunctionNameTypeSelector;
- break;
-
- case 't' :
- m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
- if (m_thread_id == LLDB_INVALID_THREAD_ID)
- error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
- break;
-
- case 'T':
- m_thread_name.assign (option_arg);
- break;
-
- case 'w':
- {
- bool success;
- m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
- }
- break;
-
- case 'x':
- m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (m_thread_id == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
- break;
-
- case 'X':
- m_source_regex_func_names.insert(option_arg);
- break;
-
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_condition.clear();
- m_filenames.Clear();
- m_line_num = 0;
- m_column = 0;
- m_func_names.clear();
- m_func_name_type_mask = eFunctionNameTypeNone;
- m_func_regexp.clear();
- m_source_text_regexp.clear();
- m_modules.Clear();
- m_load_addr = LLDB_INVALID_ADDRESS;
- m_offset_addr = 0;
- m_ignore_count = 0;
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_index = UINT32_MAX;
- m_thread_name.clear();
- m_queue_name.clear();
- m_catch_bp = false;
- m_throw_bp = true;
- m_hardware = false;
- m_exception_language = eLanguageTypeUnknown;
- m_language = lldb::eLanguageTypeUnknown;
- m_skip_prologue = eLazyBoolCalculate;
- m_one_shot = false;
- m_use_dummy = false;
- m_breakpoint_names.clear();
- m_all_files = false;
- m_exception_extra_args.Clear();
- m_move_to_nearest_code = eLazyBoolCalculate;
- m_source_regex_func_names.clear();
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_set_options);
+ }
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- std::string m_condition;
- FileSpecList m_filenames;
- uint32_t m_line_num;
- uint32_t m_column;
- std::vector<std::string> m_func_names;
- std::vector<std::string> m_breakpoint_names;
- uint32_t m_func_name_type_mask;
- std::string m_func_regexp;
- std::string m_source_text_regexp;
- FileSpecList m_modules;
- lldb::addr_t m_load_addr;
- lldb::addr_t m_offset_addr;
- uint32_t m_ignore_count;
- lldb::tid_t m_thread_id;
- uint32_t m_thread_index;
- std::string m_thread_name;
- std::string m_queue_name;
- bool m_catch_bp;
- bool m_throw_bp;
- bool m_hardware; // Request to use hardware breakpoints
- lldb::LanguageType m_exception_language;
- lldb::LanguageType m_language;
- LazyBool m_skip_prologue;
- bool m_one_shot;
- bool m_use_dummy;
- bool m_all_files;
- Args m_exception_extra_args;
- LazyBool m_move_to_nearest_code;
- std::unordered_set<std::string> m_source_regex_func_names;
- };
+ // Instance variables to hold the values for command options.
+
+ std::string m_condition;
+ FileSpecList m_filenames;
+ uint32_t m_line_num;
+ uint32_t m_column;
+ std::vector<std::string> m_func_names;
+ std::vector<std::string> m_breakpoint_names;
+ uint32_t m_func_name_type_mask;
+ std::string m_func_regexp;
+ std::string m_source_text_regexp;
+ FileSpecList m_modules;
+ lldb::addr_t m_load_addr;
+ lldb::addr_t m_offset_addr;
+ uint32_t m_ignore_count;
+ lldb::tid_t m_thread_id;
+ uint32_t m_thread_index;
+ std::string m_thread_name;
+ std::string m_queue_name;
+ bool m_catch_bp;
+ bool m_throw_bp;
+ bool m_hardware; // Request to use hardware breakpoints
+ lldb::LanguageType m_exception_language;
+ lldb::LanguageType m_language;
+ LazyBool m_skip_prologue;
+ bool m_one_shot;
+ bool m_use_dummy;
+ bool m_all_files;
+ Args m_exception_extra_args;
+ LazyBool m_move_to_nearest_code;
+ std::unordered_set<std::string> m_source_regex_func_names;
+ };
protected:
- bool
- DoExecute (Args& command,
- CommandReturnObject &result) override
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+
+ if (target == nullptr) {
+ result.AppendError("Invalid target. Must set target before setting "
+ "breakpoints (see 'target create' command).");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // The following are the various types of breakpoints that could be set:
+ // 1). -f -l -p [-s -g] (setting breakpoint by source location)
+ // 2). -a [-s -g] (setting breakpoint by address)
+ // 3). -n [-s -g] (setting breakpoint by function name)
+ // 4). -r [-s -g] (setting breakpoint by function name regular
+ // expression)
+ // 5). -p -f (setting a breakpoint by comparing a reg-exp
+ // to source text)
+ // 6). -E [-w -h] (setting a breakpoint for exceptions for a
+ // given language.)
+
+ BreakpointSetType break_type = eSetTypeInvalid;
+
+ if (m_options.m_line_num != 0)
+ break_type = eSetTypeFileAndLine;
+ else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
+ break_type = eSetTypeAddress;
+ else if (!m_options.m_func_names.empty())
+ break_type = eSetTypeFunctionName;
+ else if (!m_options.m_func_regexp.empty())
+ break_type = eSetTypeFunctionRegexp;
+ else if (!m_options.m_source_text_regexp.empty())
+ break_type = eSetTypeSourceRegexp;
+ else if (m_options.m_exception_language != eLanguageTypeUnknown)
+ break_type = eSetTypeException;
+
+ Breakpoint *bp = nullptr;
+ FileSpec module_spec;
+ const bool internal = false;
+
+ // If the user didn't specify skip-prologue, having an offset should turn
+ // that off.
+ if (m_options.m_offset_addr != 0 &&
+ m_options.m_skip_prologue == eLazyBoolCalculate)
+ m_options.m_skip_prologue = eLazyBoolNo;
+
+ switch (break_type) {
+ case eSetTypeFileAndLine: // Breakpoint by source position
+ {
+ FileSpec file;
+ const size_t num_files = m_options.m_filenames.GetSize();
+ if (num_files == 0) {
+ if (!GetDefaultFile(target, file, result)) {
+ result.AppendError("No file supplied and no default file available.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else if (num_files > 1) {
+ result.AppendError("Only one file at a time is allowed for file and "
+ "line breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else
+ file = m_options.m_filenames.GetFileSpecAtIndex(0);
+
+ // Only check for inline functions if
+ LazyBool check_inlines = eLazyBoolCalculate;
+
+ bp = target
+ ->CreateBreakpoint(&(m_options.m_modules), file,
+ m_options.m_line_num, m_options.m_offset_addr,
+ check_inlines, m_options.m_skip_prologue,
+ internal, m_options.m_hardware,
+ m_options.m_move_to_nearest_code)
+ .get();
+ } break;
+
+ case eSetTypeAddress: // Breakpoint by address
+ {
+ // If a shared library has been specified, make an lldb_private::Address
+ // with the library, and
+ // use that. That way the address breakpoint will track the load location
+ // of the library.
+ size_t num_modules_specified = m_options.m_modules.GetSize();
+ if (num_modules_specified == 1) {
+ const FileSpec *file_spec =
+ m_options.m_modules.GetFileSpecPointerAtIndex(0);
+ bp = target
+ ->CreateAddressInModuleBreakpoint(m_options.m_load_addr,
+ internal, file_spec,
+ m_options.m_hardware)
+ .get();
+ } else if (num_modules_specified == 0) {
+ bp = target
+ ->CreateBreakpoint(m_options.m_load_addr, internal,
+ m_options.m_hardware)
+ .get();
+ } else {
+ result.AppendError("Only one shared library can be specified for "
+ "address breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ break;
+ }
+ case eSetTypeFunctionName: // Breakpoint by function name
+ {
+ uint32_t name_type_mask = m_options.m_func_name_type_mask;
+
+ if (name_type_mask == 0)
+ name_type_mask = eFunctionNameTypeAuto;
+
+ bp = target
+ ->CreateBreakpoint(
+ &(m_options.m_modules), &(m_options.m_filenames),
+ m_options.m_func_names, name_type_mask, m_options.m_language,
+ m_options.m_offset_addr, m_options.m_skip_prologue, internal,
+ m_options.m_hardware)
+ .get();
+ } break;
+
+ case eSetTypeFunctionRegexp: // Breakpoint by regular expression function
+ // name
+ {
+ RegularExpression regexp(m_options.m_func_regexp);
+ if (!regexp.IsValid()) {
+ char err_str[1024];
+ regexp.GetErrorAsCString(err_str, sizeof(err_str));
+ result.AppendErrorWithFormat(
+ "Function name regular expression could not be compiled: \"%s\"",
+ err_str);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ bp = target
+ ->CreateFuncRegexBreakpoint(
+ &(m_options.m_modules), &(m_options.m_filenames), regexp,
+ m_options.m_language, m_options.m_skip_prologue, internal,
+ m_options.m_hardware)
+ .get();
+ }
+ break;
+ case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
{
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ const size_t num_files = m_options.m_filenames.GetSize();
+
+ if (num_files == 0 && !m_options.m_all_files) {
+ FileSpec file;
+ if (!GetDefaultFile(target, file, result)) {
+ result.AppendError(
+ "No files provided and could not find default file.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ m_options.m_filenames.Append(file);
+ }
+ }
+
+ RegularExpression regexp(m_options.m_source_text_regexp);
+ if (!regexp.IsValid()) {
+ char err_str[1024];
+ regexp.GetErrorAsCString(err_str, sizeof(err_str));
+ result.AppendErrorWithFormat(
+ "Source text regular expression could not be compiled: \"%s\"",
+ err_str);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ bp = target
+ ->CreateSourceRegexBreakpoint(
+ &(m_options.m_modules), &(m_options.m_filenames),
+ m_options.m_source_regex_func_names, regexp, internal,
+ m_options.m_hardware, m_options.m_move_to_nearest_code)
+ .get();
+ } break;
+ case eSetTypeException: {
+ Error precond_error;
+ bp = target
+ ->CreateExceptionBreakpoint(
+ m_options.m_exception_language, m_options.m_catch_bp,
+ m_options.m_throw_bp, internal,
+ &m_options.m_exception_extra_args, &precond_error)
+ .get();
+ if (precond_error.Fail()) {
+ result.AppendErrorWithFormat(
+ "Error setting extra exception arguments: %s",
+ precond_error.AsCString());
+ target->RemoveBreakpointByID(bp->GetID());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } break;
+ default:
+ break;
+ }
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. Must set target before setting breakpoints (see 'target create' command).");
- result.SetStatus (eReturnStatusFailed);
+ // Now set the various options that were passed in:
+ if (bp) {
+ if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
+ bp->SetThreadID(m_options.m_thread_id);
+
+ if (m_options.m_thread_index != UINT32_MAX)
+ bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
+
+ if (!m_options.m_thread_name.empty())
+ bp->GetOptions()->GetThreadSpec()->SetName(
+ m_options.m_thread_name.c_str());
+
+ if (!m_options.m_queue_name.empty())
+ bp->GetOptions()->GetThreadSpec()->SetQueueName(
+ m_options.m_queue_name.c_str());
+
+ if (m_options.m_ignore_count != 0)
+ bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
+
+ if (!m_options.m_condition.empty())
+ bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
+
+ if (!m_options.m_breakpoint_names.empty()) {
+ Error name_error;
+ for (auto name : m_options.m_breakpoint_names) {
+ bp->AddName(name.c_str(), name_error);
+ if (name_error.Fail()) {
+ result.AppendErrorWithFormat("Invalid breakpoint name: %s",
+ name.c_str());
+ target->RemoveBreakpointByID(bp->GetID());
+ result.SetStatus(eReturnStatusFailed);
return false;
+ }
}
+ }
- // The following are the various types of breakpoints that could be set:
- // 1). -f -l -p [-s -g] (setting breakpoint by source location)
- // 2). -a [-s -g] (setting breakpoint by address)
- // 3). -n [-s -g] (setting breakpoint by function name)
- // 4). -r [-s -g] (setting breakpoint by function name regular expression)
- // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
- // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
-
- BreakpointSetType break_type = eSetTypeInvalid;
-
- if (m_options.m_line_num != 0)
- break_type = eSetTypeFileAndLine;
- else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
- break_type = eSetTypeAddress;
- else if (!m_options.m_func_names.empty())
- break_type = eSetTypeFunctionName;
- else if (!m_options.m_func_regexp.empty())
- break_type = eSetTypeFunctionRegexp;
- else if (!m_options.m_source_text_regexp.empty())
- break_type = eSetTypeSourceRegexp;
- else if (m_options.m_exception_language != eLanguageTypeUnknown)
- break_type = eSetTypeException;
-
- Breakpoint *bp = nullptr;
- FileSpec module_spec;
- const bool internal = false;
-
- // If the user didn't specify skip-prologue, having an offset should turn that off.
- if (m_options.m_offset_addr != 0 && m_options.m_skip_prologue == eLazyBoolCalculate)
- m_options.m_skip_prologue = eLazyBoolNo;
-
- switch (break_type)
- {
- case eSetTypeFileAndLine: // Breakpoint by source position
- {
- FileSpec file;
- const size_t num_files = m_options.m_filenames.GetSize();
- if (num_files == 0)
- {
- if (!GetDefaultFile (target, file, result))
- {
- result.AppendError("No file supplied and no default file available.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else if (num_files > 1)
- {
- result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- file = m_options.m_filenames.GetFileSpecAtIndex(0);
-
- // Only check for inline functions if
- LazyBool check_inlines = eLazyBoolCalculate;
-
- bp = target->CreateBreakpoint (&(m_options.m_modules),
- file,
- m_options.m_line_num,
- m_options.m_offset_addr,
- check_inlines,
- m_options.m_skip_prologue,
- internal,
- m_options.m_hardware,
- m_options.m_move_to_nearest_code).get();
- }
- break;
-
- case eSetTypeAddress: // Breakpoint by address
- {
- // If a shared library has been specified, make an lldb_private::Address with the library, and
- // use that. That way the address breakpoint will track the load location of the library.
- size_t num_modules_specified = m_options.m_modules.GetSize();
- if (num_modules_specified == 1)
- {
- const FileSpec *file_spec = m_options.m_modules.GetFileSpecPointerAtIndex(0);
- bp = target->CreateAddressInModuleBreakpoint (m_options.m_load_addr,
- internal,
- file_spec,
- m_options.m_hardware).get();
- }
- else if (num_modules_specified == 0)
- {
- bp = target->CreateBreakpoint (m_options.m_load_addr,
- internal,
- m_options.m_hardware).get();
- }
- else
- {
- result.AppendError("Only one shared library can be specified for address breakpoints.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- break;
- }
- case eSetTypeFunctionName: // Breakpoint by function name
- {
- uint32_t name_type_mask = m_options.m_func_name_type_mask;
-
- if (name_type_mask == 0)
- name_type_mask = eFunctionNameTypeAuto;
-
- bp = target->CreateBreakpoint (&(m_options.m_modules),
- &(m_options.m_filenames),
- m_options.m_func_names,
- name_type_mask,
- m_options.m_language,
- m_options.m_offset_addr,
- m_options.m_skip_prologue,
- internal,
- m_options.m_hardware).get();
- }
- break;
-
- case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
- {
- RegularExpression regexp(m_options.m_func_regexp.c_str());
- if (!regexp.IsValid())
- {
- char err_str[1024];
- regexp.GetErrorAsCString(err_str, sizeof(err_str));
- result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
- err_str);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
- &(m_options.m_filenames),
- regexp,
- m_options.m_language,
- m_options.m_skip_prologue,
- internal,
- m_options.m_hardware).get();
- }
- break;
- case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
- {
- const size_t num_files = m_options.m_filenames.GetSize();
-
- if (num_files == 0 && !m_options.m_all_files)
- {
- FileSpec file;
- if (!GetDefaultFile (target, file, result))
- {
- result.AppendError ("No files provided and could not find default file.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- m_options.m_filenames.Append (file);
- }
- }
-
- RegularExpression regexp(m_options.m_source_text_regexp.c_str());
- if (!regexp.IsValid())
- {
- char err_str[1024];
- regexp.GetErrorAsCString(err_str, sizeof(err_str));
- result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
- err_str);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
- &(m_options.m_filenames),
- m_options.m_source_regex_func_names,
- regexp,
- internal,
- m_options.m_hardware,
- m_options.m_move_to_nearest_code).get();
- }
- break;
- case eSetTypeException:
- {
- Error precond_error;
- bp = target->CreateExceptionBreakpoint (m_options.m_exception_language,
- m_options.m_catch_bp,
- m_options.m_throw_bp,
- internal,
- &m_options.m_exception_extra_args,
- &precond_error).get();
- if (precond_error.Fail())
- {
- result.AppendErrorWithFormat("Error setting extra exception arguments: %s",
- precond_error.AsCString());
- target->RemoveBreakpointByID(bp->GetID());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- break;
- default:
- break;
- }
-
- // Now set the various options that were passed in:
- if (bp)
- {
- if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
- bp->SetThreadID (m_options.m_thread_id);
-
- if (m_options.m_thread_index != UINT32_MAX)
- bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
-
- if (!m_options.m_thread_name.empty())
- bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
-
- if (!m_options.m_queue_name.empty())
- bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
-
- if (!m_options.m_condition.empty())
- bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
-
- if (!m_options.m_breakpoint_names.empty())
- {
- Error error; // We don't need to check the error here, since the option parser checked it...
- for (auto name : m_options.m_breakpoint_names)
- bp->AddName(name.c_str(), error);
- }
-
- bp->SetOneShot (m_options.m_one_shot);
- }
-
- if (bp)
- {
- Stream &output_stream = result.GetOutputStream();
- const bool show_locations = false;
- bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
- if (target == m_interpreter.GetDebugger().GetDummyTarget())
- output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
- else
- {
- // Don't print out this warning for exception breakpoints. They can get set before the target
- // is set, but we won't know how to actually set the breakpoint till we run.
- if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
- {
- output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
- }
- }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else if (!bp)
- {
- result.AppendError ("Breakpoint creation failed: No breakpoint created.");
- result.SetStatus (eReturnStatusFailed);
- }
-
- return result.Succeeded();
+ bp->SetOneShot(m_options.m_one_shot);
}
-private:
- bool
- GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
- {
- uint32_t default_line;
- // First use the Source Manager's default file.
- // Then use the current stack frame's file.
- if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
- {
- StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
- if (cur_frame == nullptr)
- {
- result.AppendError ("No selected frame to use to find the default file.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else if (!cur_frame->HasDebugInformation())
- {
- result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
- if (sc.line_entry.file)
- {
- file = sc.line_entry.file;
- }
- else
- {
- result.AppendError ("Can't find the file for the selected frame to use as the default file.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
- return true;
+ if (bp) {
+ Stream &output_stream = result.GetOutputStream();
+ const bool show_locations = false;
+ bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
+ show_locations);
+ if (target == m_interpreter.GetDebugger().GetDummyTarget())
+ output_stream.Printf("Breakpoint set in dummy target, will get copied "
+ "into future targets.\n");
+ else {
+ // Don't print out this warning for exception breakpoints. They can get
+ // set before the target
+ // is set, but we won't know how to actually set the breakpoint till we
+ // run.
+ if (bp->GetNumLocations() == 0 && break_type != eSetTypeException) {
+ output_stream.Printf("WARNING: Unable to resolve breakpoint to any "
+ "actual locations.\n");
+ }
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else if (!bp) {
+ result.AppendError("Breakpoint creation failed: No breakpoint created.");
+ result.SetStatus(eReturnStatusFailed);
}
-
- CommandOptions m_options;
-};
-
-// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
-// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
-#define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
-#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
-#define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
-#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
-#define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 )
-#define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) )
-
-OptionDefinition
-CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
- "Set the breakpoint only in this shared library. "
- "Can repeat this option multiple times to specify multiple shared libraries."},
-
- { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,
- "Set the number of times this breakpoint is skipped before stopping." },
-
- { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "The breakpoint is deleted the first time it causes a stop." },
-
- { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression,
- "The breakpoint stops only if this condition expression evaluates to true."},
-
- { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex,
- "The breakpoint stops only for the thread whose indeX matches this argument."},
-
- { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,
- "The breakpoint stops only for the thread whose TID matches this argument."},
-
- { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,
- "The breakpoint stops only for the thread whose thread name matches this argument."},
- { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Require the breakpoint to use hardware breakpoints."},
+ return result.Succeeded();
+ }
- { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,
- "The breakpoint stops only for threads in the queue whose name is given by this argument."},
-
- { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
- "Specifies the source file in which to set this breakpoint. "
- "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. "
- "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
- " to \"always\"."},
-
- { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
- "Specifies the line number on which to set this breakpoint."},
-
- // Comment out this option for the moment, as we don't actually use it, but will in the future.
- // This way users won't see it, but the infrastructure is left in place.
- // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>",
- // "Set the breakpoint by source location at this particular column."},
-
- { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
- "Set the breakpoint at the specified address. "
- "If the address maps uniquely to a particular "
- "binary, then the address will be converted to a \"file\" address, so that the breakpoint will track that binary+offset no matter where "
- "the binary eventually loads. "
- "Alternately, if you also specify the module - with the -s option - then the address will be treated as "
- "a file address in that module, and resolved accordingly. Again, this will allow lldb to track that offset on "
- "subsequent reloads. The module need not have been loaded at the time you specify this breakpoint, and will "
- "get resolved when the module is loaded."},
-
- { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" },
+private:
+ bool GetDefaultFile(Target *target, FileSpec &file,
+ CommandReturnObject &result) {
+ uint32_t default_line;
+ // First use the Source Manager's default file.
+ // Then use the current stack frame's file.
+ if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) {
+ StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
+ if (cur_frame == nullptr) {
+ result.AppendError(
+ "No selected frame to use to find the default file.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (!cur_frame->HasDebugInformation()) {
+ result.AppendError("Cannot use the selected frame to find the default "
+ "file, it has no debug info.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ const SymbolContext &sc =
+ cur_frame->GetSymbolContext(eSymbolContextLineEntry);
+ if (sc.line_entry.file) {
+ file = sc.line_entry.file;
+ } else {
+ result.AppendError("Can't find the file for the selected frame to "
+ "use as the default file.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
- { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "When used with '-p' limits the source regex to source contained in the named functions. Can be repeated multiple times." },
+ CommandOptions m_options;
+};
- { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
- "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
- "for Objective C this means a full function prototype with class and selector. "
- "Can be repeated multiple times to make one breakpoint for multiple names." },
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointModify
+//-------------------------------------------------------------------------
- { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector,
- "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
+#pragma mark Modify::CommandOptions
+static OptionDefinition g_breakpoint_modify_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
+ { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
+ { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." },
+ { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." },
+ { LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint." },
+ { LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint." },
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
+ // clang-format on
+};
- { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod,
- "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." },
+#pragma mark Modify
- { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression,
- "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
+class CommandObjectBreakpointModify : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointModify(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint modify",
+ "Modify the options on a breakpoint or set of "
+ "breakpoints in the executable. "
+ "If no breakpoint is specified, acts on the last "
+ "created breakpoint. "
+ "With the exception of -e, -d and -i, passing an "
+ "empty argument clears the modification.",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointModify() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_ignore_count(0), m_thread_id(LLDB_INVALID_THREAD_ID),
+ m_thread_id_passed(false), m_thread_index(UINT32_MAX),
+ m_thread_index_passed(false), m_thread_name(), m_queue_name(),
+ m_condition(), m_one_shot(false), m_enable_passed(false),
+ m_enable_value(false), m_name_passed(false), m_queue_passed(false),
+ m_condition_passed(false), m_one_shot_passed(false),
+ m_use_dummy(false) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c':
+ m_condition = option_arg;
+ m_condition_passed = true;
+ break;
+ case 'd':
+ m_enable_passed = true;
+ m_enable_value = false;
+ break;
+ case 'D':
+ m_use_dummy = true;
+ break;
+ case 'e':
+ m_enable_passed = true;
+ m_enable_value = true;
+ break;
+ case 'i':
+ if (option_arg.getAsInteger(0, m_ignore_count))
+ error.SetErrorStringWithFormat("invalid ignore count '%s'",
+ option_arg.str().c_str());
+ break;
+ case 'o': {
+ bool value, success;
+ value = Args::StringToBoolean(option_arg, false, &success);
+ if (success) {
+ m_one_shot_passed = true;
+ m_one_shot = value;
+ } else
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' passed for -o option",
+ option_arg.str().c_str());
+ } break;
+ case 't':
+ if (option_arg[0] == '\0') {
+ m_thread_id = LLDB_INVALID_THREAD_ID;
+ m_thread_id_passed = true;
+ } else {
+ if (option_arg.getAsInteger(0, m_thread_id))
+ error.SetErrorStringWithFormat("invalid thread id string '%s'",
+ option_arg.str().c_str());
+ else
+ m_thread_id_passed = true;
+ }
+ break;
+ case 'T':
+ m_thread_name = option_arg;
+ m_name_passed = true;
+ break;
+ case 'q':
+ m_queue_name = option_arg;
+ m_queue_passed = true;
+ break;
+ case 'x':
+ if (option_arg[0] == '\n') {
+ m_thread_index = UINT32_MAX;
+ m_thread_index_passed = true;
+ } else {
+ if (option_arg.getAsInteger(0, m_thread_index))
+ error.SetErrorStringWithFormat("invalid thread index string '%s'",
+ option_arg.str().c_str());
+ else
+ m_thread_index_passed = true;
+ }
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
- { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
- "Can be repeated multiple times to make one breakpoint for multiple symbols." },
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_ignore_count = 0;
+ m_thread_id = LLDB_INVALID_THREAD_ID;
+ m_thread_id_passed = false;
+ m_thread_index = UINT32_MAX;
+ m_thread_index_passed = false;
+ m_thread_name.clear();
+ m_queue_name.clear();
+ m_condition.clear();
+ m_one_shot = false;
+ m_enable_passed = false;
+ m_queue_passed = false;
+ m_name_passed = false;
+ m_condition_passed = false;
+ m_one_shot_passed = false;
+ m_use_dummy = false;
+ }
- { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression,
- "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
- "specified with the -f option. The -f option can be specified more than once. "
- "If no source files are specified, uses the current \"default source file\". "
- "If you want to match against all source files, pass the \"--all-files\" option." },
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_modify_options);
+ }
- { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "All files are searched for source pattern matches." },
+ // Instance variables to hold the values for command options.
+
+ uint32_t m_ignore_count;
+ lldb::tid_t m_thread_id;
+ bool m_thread_id_passed;
+ uint32_t m_thread_index;
+ bool m_thread_index_passed;
+ std::string m_thread_name;
+ std::string m_queue_name;
+ std::string m_condition;
+ bool m_one_shot;
+ bool m_enable_passed;
+ bool m_enable_value;
+ bool m_name_passed;
+ bool m_queue_passed;
+ bool m_condition_passed;
+ bool m_one_shot_passed;
+ bool m_use_dummy;
+ };
- { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,
- "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
- "Set the breakpoint on exception throW." },
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
- "Set the breakpoint on exception catcH." },
+ BreakpointIDList valid_bp_ids;
-// Don't add this option till it actually does something useful...
-// { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName,
-// "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" },
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
- { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,
- "Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for setting breakpoints on identifiers). If not set the target.language setting is used." },
+ if (result.Succeeded()) {
+ const size_t count = valid_bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
- { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
- "sKip the prologue if the breakpoint is at the beginning of a function. If not set the target.skip-prologue setting is used." },
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *bp =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
+ BreakpointLocation *location =
+ bp->FindLocationByID(cur_bp_id.GetLocationID()).get();
+ if (location) {
+ if (m_options.m_thread_id_passed)
+ location->SetThreadID(m_options.m_thread_id);
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ if (m_options.m_thread_index_passed)
+ location->SetThreadIndex(m_options.m_thread_index);
- { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName,
- "Adds this to the list of names for this breakpoint."},
+ if (m_options.m_name_passed)
+ location->SetThreadName(m_options.m_thread_name.c_str());
- { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress,
- "Add the specified offset to whatever address(es) the breakpoint resolves to. "
- "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries."},
+ if (m_options.m_queue_passed)
+ location->SetQueueName(m_options.m_queue_name.c_str());
- { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
- "Move breakpoints to nearest code. If not set the target.move-to-nearest-code setting is used." },
+ if (m_options.m_ignore_count != 0)
+ location->SetIgnoreCount(m_options.m_ignore_count);
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
-};
+ if (m_options.m_enable_passed)
+ location->SetEnabled(m_options.m_enable_value);
-//-------------------------------------------------------------------------
-// CommandObjectBreakpointModify
-//-------------------------------------------------------------------------
-#pragma mark Modify
-
-class CommandObjectBreakpointModify : public CommandObjectParsed
-{
-public:
- CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "breakpoint modify",
- "Modify the options on a breakpoint or set of breakpoints in the executable. "
- "If no breakpoint is specified, acts on the last created breakpoint. "
- "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
- nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectBreakpointModify() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ if (m_options.m_condition_passed)
+ location->SetCondition(m_options.m_condition.c_str());
+ }
+ } else {
+ if (m_options.m_thread_id_passed)
+ bp->SetThreadID(m_options.m_thread_id);
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_ignore_count (0),
- m_thread_id(LLDB_INVALID_THREAD_ID),
- m_thread_id_passed(false),
- m_thread_index (UINT32_MAX),
- m_thread_index_passed(false),
- m_thread_name(),
- m_queue_name(),
- m_condition (),
- m_one_shot (false),
- m_enable_passed (false),
- m_enable_value (false),
- m_name_passed (false),
- m_queue_passed (false),
- m_condition_passed (false),
- m_one_shot_passed (false),
- m_use_dummy (false)
- {
- }
+ if (m_options.m_thread_index_passed)
+ bp->SetThreadIndex(m_options.m_thread_index);
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'c':
- if (option_arg != nullptr)
- m_condition.assign (option_arg);
- else
- m_condition.clear();
- m_condition_passed = true;
- break;
- case 'd':
- m_enable_passed = true;
- m_enable_value = false;
- break;
- case 'D':
- m_use_dummy = true;
- break;
- case 'e':
- m_enable_passed = true;
- m_enable_value = true;
- break;
- case 'i':
- m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (m_ignore_count == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
- break;
- case 'o':
- {
- bool value, success;
- value = Args::StringToBoolean(option_arg, false, &success);
- if (success)
- {
- m_one_shot_passed = true;
- m_one_shot = value;
- }
- else
- error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
- }
- break;
- case 't' :
- if (option_arg[0] == '\0')
- {
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_id_passed = true;
- }
- else
- {
- m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
- if (m_thread_id == LLDB_INVALID_THREAD_ID)
- error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
- else
- m_thread_id_passed = true;
- }
- break;
- case 'T':
- if (option_arg != nullptr)
- m_thread_name.assign (option_arg);
- else
- m_thread_name.clear();
- m_name_passed = true;
- break;
- case 'q':
- if (option_arg != nullptr)
- m_queue_name.assign (option_arg);
- else
- m_queue_name.clear();
- m_queue_passed = true;
- break;
- case 'x':
- if (option_arg[0] == '\n')
- {
- m_thread_index = UINT32_MAX;
- m_thread_index_passed = true;
- }
- else
- {
- m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
- if (m_thread_id == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
- else
- m_thread_index_passed = true;
- }
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
+ if (m_options.m_name_passed)
+ bp->SetThreadName(m_options.m_thread_name.c_str());
- return error;
- }
+ if (m_options.m_queue_passed)
+ bp->SetQueueName(m_options.m_queue_name.c_str());
- void
- OptionParsingStarting () override
- {
- m_ignore_count = 0;
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_id_passed = false;
- m_thread_index = UINT32_MAX;
- m_thread_index_passed = false;
- m_thread_name.clear();
- m_queue_name.clear();
- m_condition.clear();
- m_one_shot = false;
- m_enable_passed = false;
- m_queue_passed = false;
- m_name_passed = false;
- m_condition_passed = false;
- m_one_shot_passed = false;
- m_use_dummy = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- uint32_t m_ignore_count;
- lldb::tid_t m_thread_id;
- bool m_thread_id_passed;
- uint32_t m_thread_index;
- bool m_thread_index_passed;
- std::string m_thread_name;
- std::string m_queue_name;
- std::string m_condition;
- bool m_one_shot;
- bool m_enable_passed;
- bool m_enable_value;
- bool m_name_passed;
- bool m_queue_passed;
- bool m_condition_passed;
- bool m_one_shot_passed;
- bool m_use_dummy;
- };
+ if (m_options.m_ignore_count != 0)
+ bp->SetIgnoreCount(m_options.m_ignore_count);
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (m_options.m_enable_passed)
+ bp->SetEnabled(m_options.m_enable_value);
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
-
- BreakpointIDList valid_bp_ids;
-
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- const size_t count = valid_bp_ids.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
-
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
- {
- BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
- if (location)
- {
- if (m_options.m_thread_id_passed)
- location->SetThreadID (m_options.m_thread_id);
-
- if (m_options.m_thread_index_passed)
- location->SetThreadIndex(m_options.m_thread_index);
-
- if (m_options.m_name_passed)
- location->SetThreadName(m_options.m_thread_name.c_str());
-
- if (m_options.m_queue_passed)
- location->SetQueueName(m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- location->SetIgnoreCount(m_options.m_ignore_count);
-
- if (m_options.m_enable_passed)
- location->SetEnabled (m_options.m_enable_value);
-
- if (m_options.m_condition_passed)
- location->SetCondition (m_options.m_condition.c_str());
- }
- }
- else
- {
- if (m_options.m_thread_id_passed)
- bp->SetThreadID (m_options.m_thread_id);
-
- if (m_options.m_thread_index_passed)
- bp->SetThreadIndex(m_options.m_thread_index);
-
- if (m_options.m_name_passed)
- bp->SetThreadName(m_options.m_thread_name.c_str());
-
- if (m_options.m_queue_passed)
- bp->SetQueueName(m_options.m_queue_name.c_str());
-
- if (m_options.m_ignore_count != 0)
- bp->SetIgnoreCount(m_options.m_ignore_count);
-
- if (m_options.m_enable_passed)
- bp->SetEnabled (m_options.m_enable_value);
-
- if (m_options.m_condition_passed)
- bp->SetCondition (m_options.m_condition.c_str());
- }
- }
- }
+ if (m_options.m_condition_passed)
+ bp->SetCondition(m_options.m_condition.c_str());
+ }
}
-
- return result.Succeeded();
+ }
}
-private:
- CommandOptions m_options;
-};
+ return result.Succeeded();
+ }
-#pragma mark Modify::CommandOptions
-OptionDefinition
-CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
-{ LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
-{ LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
-{ LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
-{ LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
-{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
-{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
-{ LLDB_OPT_SET_1, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint."},
-{ LLDB_OPT_SET_2, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint."},
-{ LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
-
-{ 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -1193,97 +1052,89 @@ CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
//-------------------------------------------------------------------------
#pragma mark Enable
-class CommandObjectBreakpointEnable : public CommandObjectParsed
-{
+class CommandObjectBreakpointEnable : public CommandObjectParsed {
public:
- CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "enable",
- "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectBreakpointEnable() override = default;
+ CommandObjectBreakpointEnable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "enable",
+ "Enable the specified disabled breakpoint(s). If "
+ "no breakpoints are specified, enable all of them.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointEnable() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.AppendError ("No breakpoints exist to be enabled.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_breakpoints == 0) {
+ result.AppendError("No breakpoints exist to be enabled.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- // No breakpoint selected; enable all currently set breakpoints.
- target->EnableAllBreakpoints ();
- result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular breakpoint selected; enable that breakpoint.
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- int enable_count = 0;
- int loc_count = 0;
- const size_t count = valid_bp_ids.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
-
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
- {
- BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
- if (location)
- {
- location->SetEnabled (true);
- ++loc_count;
- }
- }
- else
- {
- breakpoint->SetEnabled (true);
- ++enable_count;
- }
- }
- }
- result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ if (command.empty()) {
+ // No breakpoint selected; enable all currently set breakpoints.
+ target->EnableAllBreakpoints();
+ result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64
+ " breakpoints)\n",
+ (uint64_t)num_breakpoints);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular breakpoint selected; enable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ int enable_count = 0;
+ int loc_count = 0;
+ const size_t count = valid_bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *breakpoint =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
+ BreakpointLocation *location =
+ breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
+ if (location) {
+ location->SetEnabled(true);
+ ++loc_count;
+ }
+ } else {
+ breakpoint->SetEnabled(true);
+ ++enable_count;
}
+ }
}
-
- return result.Succeeded();
+ result.AppendMessageWithFormat("%d breakpoints enabled.\n",
+ enable_count + loc_count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
@@ -1291,23 +1142,24 @@ protected:
//-------------------------------------------------------------------------
#pragma mark Disable
-class CommandObjectBreakpointDisable : public CommandObjectParsed
-{
+class CommandObjectBreakpointDisable : public CommandObjectParsed {
public:
- CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "breakpoint disable", "Disable the specified breakpoint(s) without deleting "
- "them. If none are specified, disable all "
- "breakpoints.",
- nullptr)
- {
- SetHelpLong("Disable the specified breakpoint(s) without deleting them. \
+ CommandObjectBreakpointDisable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "breakpoint disable",
+ "Disable the specified breakpoint(s) without deleting "
+ "them. If none are specified, disable all "
+ "breakpoints.",
+ nullptr) {
+ SetHelpLong(
+ "Disable the specified breakpoint(s) without deleting them. \
If none are specified, disable all breakpoints."
- R"(
+ R"(
)"
- "Note: disabling a breakpoint will cause none of its locations to be hit \
+ "Note: disabling a breakpoint will cause none of its locations to be hit \
regardless of whether individual locations are enabled or disabled. After the sequence:"
- R"(
+ R"(
(lldb) break disable 1
(lldb) break enable 1.1
@@ -1318,674 +1170,562 @@ execution will NOT stop at location 1.1. To achieve that, type:
(lldb) break enable 1.1
)"
- "The first command disables all locations for breakpoint 1, \
+ "The first command disables all locations for breakpoint 1, \
the second re-enables the first location.");
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back (arg);
- }
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
- ~CommandObjectBreakpointDisable() override = default;
+ ~CommandObjectBreakpointDisable() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ const BreakpointList &breakpoints = target->GetBreakpointList();
+ size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.AppendError ("No breakpoints exist to be disabled.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_breakpoints == 0) {
+ result.AppendError("No breakpoints exist to be disabled.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- // No breakpoint selected; disable all currently set breakpoints.
- target->DisableAllBreakpoints ();
- result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular breakpoint selected; disable that breakpoint.
- BreakpointIDList valid_bp_ids;
-
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- int disable_count = 0;
- int loc_count = 0;
- const size_t count = valid_bp_ids.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
-
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
- {
- BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
- if (location)
- {
- location->SetEnabled (false);
- ++loc_count;
- }
- }
- else
- {
- breakpoint->SetEnabled (false);
- ++disable_count;
- }
- }
- }
- result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ if (command.empty()) {
+ // No breakpoint selected; disable all currently set breakpoints.
+ target->DisableAllBreakpoints();
+ result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64
+ " breakpoints)\n",
+ (uint64_t)num_breakpoints);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular breakpoint selected; disable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ int disable_count = 0;
+ int loc_count = 0;
+ const size_t count = valid_bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *breakpoint =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
+ BreakpointLocation *location =
+ breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
+ if (location) {
+ location->SetEnabled(false);
+ ++loc_count;
+ }
+ } else {
+ breakpoint->SetEnabled(false);
+ ++disable_count;
}
+ }
}
-
- return result.Succeeded();
+ result.AppendMessageWithFormat("%d breakpoints disabled.\n",
+ disable_count + loc_count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointList
//-------------------------------------------------------------------------
-#pragma mark List
-
-class CommandObjectBreakpointList : public CommandObjectParsed
-{
-public:
- CommandObjectBreakpointList (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "breakpoint list",
- "List some or all breakpoints at configurable levels of detail.",
- nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData bp_id_arg;
- // Define the first (and only) variant of this arg.
- bp_id_arg.arg_type = eArgTypeBreakpointID;
- bp_id_arg.arg_repetition = eArgRepeatOptional;
+#pragma mark List::CommandOptions
+static OptionDefinition g_breakpoint_list_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show debugger internal breakpoints" },
+ { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)." },
+ // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
+ // But I need to see it for now, and don't want to wait.
+ { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations." },
+ { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
+ // clang-format on
+};
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (bp_id_arg);
+#pragma mark List
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+class CommandObjectBreakpointList : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "breakpoint list",
+ "List some or all breakpoints at configurable levels of detail.",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData bp_id_arg;
+
+ // Define the first (and only) variant of this arg.
+ bp_id_arg.arg_type = eArgTypeBreakpointID;
+ bp_id_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(bp_id_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointList() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_level(lldb::eDescriptionLevelBrief), m_use_dummy(false) {
}
- ~CommandObjectBreakpointList() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'b':
+ m_level = lldb::eDescriptionLevelBrief;
+ break;
+ case 'D':
+ m_use_dummy = true;
+ break;
+ case 'f':
+ m_level = lldb::eDescriptionLevelFull;
+ break;
+ case 'v':
+ m_level = lldb::eDescriptionLevelVerbose;
+ break;
+ case 'i':
+ m_internal = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_level (lldb::eDescriptionLevelBrief),
- m_use_dummy(false)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'b':
- m_level = lldb::eDescriptionLevelBrief;
- break;
- case 'D':
- m_use_dummy = true;
- break;
- case 'f':
- m_level = lldb::eDescriptionLevelFull;
- break;
- case 'v':
- m_level = lldb::eDescriptionLevelVerbose;
- break;
- case 'i':
- m_internal = true;
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
- void
- OptionParsingStarting () override
- {
- m_level = lldb::eDescriptionLevelFull;
- m_internal = false;
- m_use_dummy = false;
- }
-
- const OptionDefinition *
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_level = lldb::eDescriptionLevelFull;
+ m_internal = false;
+ m_use_dummy = false;
+ }
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_list_options);
+ }
- // Instance variables to hold the values for command options.
+ // Instance variables to hold the values for command options.
- lldb::DescriptionLevel m_level;
+ lldb::DescriptionLevel m_level;
- bool m_internal;
- bool m_use_dummy;
- };
+ bool m_internal;
+ bool m_use_dummy;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
-
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No current target or breakpoints.");
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- return true;
- }
-
- const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList(m_options.m_internal).GetListMutex(lock);
-
- size_t num_breakpoints = breakpoints.GetSize();
-
- if (num_breakpoints == 0)
- {
- result.AppendMessage ("No breakpoints currently set.");
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- return true;
- }
-
- Stream &output_stream = result.GetOutputStream();
-
- if (command.GetArgumentCount() == 0)
- {
- // No breakpoint selected; show info about all currently set breakpoints.
- result.AppendMessage ("Current breakpoints:");
- for (size_t i = 0; i < num_breakpoints; ++i)
- {
- Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
- AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
- }
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular breakpoints selected; show info about that breakpoint.
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
- Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
- }
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError("Invalid breakpoint ID.");
- result.SetStatus (eReturnStatusFailed);
- }
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- return result.Succeeded();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No current target or breakpoints.");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
}
-private:
- CommandOptions m_options;
-};
+ const BreakpointList &breakpoints =
+ target->GetBreakpointList(m_options.m_internal);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList(m_options.m_internal).GetListMutex(lock);
-#pragma mark List::CommandOptions
-OptionDefinition
-CommandObjectBreakpointList::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Show debugger internal breakpoints" },
+ size_t num_breakpoints = breakpoints.GetSize();
- { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Give a brief description of the breakpoint (no location info)."},
-
- // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
- // But I need to see it for now, and don't want to wait.
- { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Give a full description of the breakpoint and its locations."},
+ if (num_breakpoints == 0) {
+ result.AppendMessage("No breakpoints currently set.");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
+ }
- { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
+ Stream &output_stream = result.GetOutputStream();
+
+ if (command.empty()) {
+ // No breakpoint selected; show info about all currently set breakpoints.
+ result.AppendMessage("Current breakpoints:");
+ for (size_t i = 0; i < num_breakpoints; ++i) {
+ Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex(i).get();
+ AddBreakpointDescription(&output_stream, breakpoint, m_options.m_level);
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular breakpoints selected; show info about that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+ Breakpoint *breakpoint =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ AddBreakpointDescription(&output_stream, breakpoint,
+ m_options.m_level);
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("Invalid breakpoint ID.");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ return result.Succeeded();
+ }
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointClear
//-------------------------------------------------------------------------
-#pragma mark Clear
+#pragma mark Clear::CommandOptions
-class CommandObjectBreakpointClear : public CommandObjectParsed
-{
-public:
- typedef enum BreakpointClearType
- {
- eClearTypeInvalid,
- eClearTypeFileAndLine
- } BreakpointClearType;
-
- CommandObjectBreakpointClear(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "breakpoint clear",
- "Delete or disable breakpoints matching the specified source file and line.",
- "breakpoint clear <cmd-options>"),
- m_options(interpreter)
- {
- }
+static OptionDefinition g_breakpoint_clear_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." },
+ { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line." }
+ // clang-format on
+};
- ~CommandObjectBreakpointClear() override = default;
+#pragma mark Clear
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+class CommandObjectBreakpointClear : public CommandObjectParsed {
+public:
+ typedef enum BreakpointClearType {
+ eClearTypeInvalid,
+ eClearTypeFileAndLine
+ } BreakpointClearType;
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_filename (),
- m_line_num (0)
- {
- }
+ CommandObjectBreakpointClear(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint clear",
+ "Delete or disable breakpoints matching the "
+ "specified source file and line.",
+ "breakpoint clear <cmd-options>"),
+ m_options() {}
- ~CommandOptions() override = default;
+ ~CommandObjectBreakpointClear() override = default;
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
+ Options *GetOptions() override { return &m_options; }
- switch (short_option)
- {
- case 'f':
- m_filename.assign (option_arg);
- break;
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_filename(), m_line_num(0) {}
- case 'l':
- m_line_num = StringConvert::ToUInt32 (option_arg, 0);
- break;
+ ~CommandOptions() override = default;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
- return error;
- }
+ switch (short_option) {
+ case 'f':
+ m_filename.assign(option_arg);
+ break;
- void
- OptionParsingStarting () override
- {
- m_filename.clear();
- m_line_num = 0;
- }
+ case 'l':
+ option_arg.getAsInteger(0, m_line_num);
+ break;
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
- // Options table: Required for subclasses of Options.
+ return error;
+ }
- static OptionDefinition g_option_table[];
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_filename.clear();
+ m_line_num = 0;
+ }
- // Instance variables to hold the values for command options.
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_clear_options);
+ }
- std::string m_filename;
- uint32_t m_line_num;
+ // Instance variables to hold the values for command options.
- };
+ std::string m_filename;
+ uint32_t m_line_num;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget();
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- // The following are the various types of breakpoints that could be cleared:
- // 1). -f -l (clearing breakpoint by source location)
+ // The following are the various types of breakpoints that could be cleared:
+ // 1). -f -l (clearing breakpoint by source location)
- BreakpointClearType break_type = eClearTypeInvalid;
+ BreakpointClearType break_type = eClearTypeInvalid;
- if (m_options.m_line_num != 0)
- break_type = eClearTypeFileAndLine;
+ if (m_options.m_line_num != 0)
+ break_type = eClearTypeFileAndLine;
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ BreakpointList &breakpoints = target->GetBreakpointList();
+ size_t num_breakpoints = breakpoints.GetSize();
- // Early return if there's no breakpoint at all.
- if (num_breakpoints == 0)
- {
- result.AppendError ("Breakpoint clear: No breakpoint cleared.");
- result.SetStatus (eReturnStatusFailed);
- return result.Succeeded();
- }
+ // Early return if there's no breakpoint at all.
+ if (num_breakpoints == 0) {
+ result.AppendError("Breakpoint clear: No breakpoint cleared.");
+ result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
+ }
- // Find matching breakpoints and delete them.
-
- // First create a copy of all the IDs.
- std::vector<break_id_t> BreakIDs;
- for (size_t i = 0; i < num_breakpoints; ++i)
- BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
-
- int num_cleared = 0;
- StreamString ss;
- switch (break_type)
- {
- case eClearTypeFileAndLine: // Breakpoint by source position
- {
- const ConstString filename(m_options.m_filename.c_str());
- BreakpointLocationCollection loc_coll;
-
- for (size_t i = 0; i < num_breakpoints; ++i)
- {
- Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
-
- if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
- {
- // If the collection size is 0, it's a full match and we can just remove the breakpoint.
- if (loc_coll.GetSize() == 0)
- {
- bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
- ss.EOL();
- target->RemoveBreakpointByID (bp->GetID());
- ++num_cleared;
- }
- }
- }
- }
- break;
-
- default:
- break;
- }
+ // Find matching breakpoints and delete them.
- if (num_cleared > 0)
- {
- Stream &output_stream = result.GetOutputStream();
- output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
- output_stream << ss.GetData();
- output_stream.EOL();
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError ("Breakpoint clear: No breakpoint cleared.");
- result.SetStatus (eReturnStatusFailed);
- }
+ // First create a copy of all the IDs.
+ std::vector<break_id_t> BreakIDs;
+ for (size_t i = 0; i < num_breakpoints; ++i)
+ BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i)->GetID());
- return result.Succeeded();
+ int num_cleared = 0;
+ StreamString ss;
+ switch (break_type) {
+ case eClearTypeFileAndLine: // Breakpoint by source position
+ {
+ const ConstString filename(m_options.m_filename.c_str());
+ BreakpointLocationCollection loc_coll;
+
+ for (size_t i = 0; i < num_breakpoints; ++i) {
+ Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
+
+ if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll)) {
+ // If the collection size is 0, it's a full match and we can just
+ // remove the breakpoint.
+ if (loc_coll.GetSize() == 0) {
+ bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
+ ss.EOL();
+ target->RemoveBreakpointByID(bp->GetID());
+ ++num_cleared;
+ }
+ }
+ }
+ } break;
+
+ default:
+ break;
}
-private:
- CommandOptions m_options;
-};
-
-#pragma mark Clear::CommandOptions
-
-OptionDefinition
-CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
- "Specify the breakpoint by source location in this particular file."},
+ if (num_cleared > 0) {
+ Stream &output_stream = result.GetOutputStream();
+ output_stream.Printf("%d breakpoints cleared:\n", num_cleared);
+ output_stream << ss.GetString();
+ output_stream.EOL();
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("Breakpoint clear: No breakpoint cleared.");
+ result.SetStatus(eReturnStatusFailed);
+ }
- { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
- "Specify the breakpoint by source location at this particular line."},
+ return result.Succeeded();
+ }
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointDelete
//-------------------------------------------------------------------------
+static OptionDefinition g_breakpoint_delete_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." },
+ { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
+ // clang-format on
+};
+
#pragma mark Delete
-class CommandObjectBreakpointDelete : public CommandObjectParsed
-{
+class CommandObjectBreakpointDelete : public CommandObjectParsed {
public:
- CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "breakpoint delete",
- "Delete the specified breakpoint(s). If no breakpoints are specified, delete them all.",
+ CommandObjectBreakpointDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint delete",
+ "Delete the specified breakpoint(s). If no "
+ "breakpoints are specified, delete them all.",
nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back (arg);
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointDelete() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ m_force = true;
+ break;
+
+ case 'D':
+ m_use_dummy = true;
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectBreakpointDelete() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_use_dummy = false;
+ m_force = false;
}
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_use_dummy (false),
- m_force (false)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'f':
- m_force = true;
- break;
-
- case 'D':
- m_use_dummy = true;
- break;
-
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_use_dummy = false;
- m_force = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_delete_options);
+ }
- // Instance variables to hold the values for command options.
- bool m_use_dummy;
- bool m_force;
- };
+ // Instance variables to hold the values for command options.
+ bool m_use_dummy;
+ bool m_force;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ const BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.AppendError ("No breakpoints exist to be deleted.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_breakpoints == 0) {
+ result.AppendError("No breakpoints exist to be deleted.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
- {
- result.AppendMessage("Operation cancelled...");
- }
- else
- {
- target->RemoveAllBreakpoints ();
- result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
+ if (command.empty()) {
+ if (!m_options.m_force &&
+ !m_interpreter.Confirm(
+ "About to delete all breakpoints, do you want to do that?",
+ true)) {
+ result.AppendMessage("Operation cancelled...");
+ } else {
+ target->RemoveAllBreakpoints();
+ result.AppendMessageWithFormat(
+ "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n",
+ (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular breakpoint selected; disable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ int delete_count = 0;
+ int disable_count = 0;
+ const size_t count = valid_bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *breakpoint =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ BreakpointLocation *location =
+ breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get();
+ // It makes no sense to try to delete individual locations, so we
+ // disable them instead.
+ if (location) {
+ location->SetEnabled(false);
+ ++disable_count;
+ }
+ } else {
+ target->RemoveBreakpointByID(cur_bp_id.GetBreakpointID());
+ ++delete_count;
}
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
}
- else
- {
- // Particular breakpoint selected; disable that breakpoint.
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- int delete_count = 0;
- int disable_count = 0;
- const size_t count = valid_bp_ids.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
-
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
- // It makes no sense to try to delete individual locations, so we disable them instead.
- if (location)
- {
- location->SetEnabled (false);
- ++disable_count;
- }
- }
- else
- {
- target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
- ++delete_count;
- }
- }
- }
- result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
- delete_count, disable_count);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- }
- return result.Succeeded();
+ result.AppendMessageWithFormat(
+ "%d breakpoints deleted; %d breakpoint locations disabled.\n",
+ delete_count, disable_count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
}
+ return result.Succeeded();
+ }
private:
- CommandOptions m_options;
-};
-
-OptionDefinition
-CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Delete all breakpoints without querying for confirmation."},
-
- { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
-
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -1993,375 +1733,566 @@ CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
//-------------------------------------------------------------------------
static OptionDefinition g_breakpoint_name_options[] = {
- {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName,
- "Specifies a breakpoint name to use."},
- {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0,
- eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
- {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ // clang-format off
+ {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
+ {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."},
+ {LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
+ // clang-format on
};
-class BreakpointNameOptionGroup : public OptionGroup
-{
+class BreakpointNameOptionGroup : public OptionGroup {
public:
- BreakpointNameOptionGroup() :
- OptionGroup(),
- m_breakpoint(LLDB_INVALID_BREAK_ID),
- m_use_dummy (false)
- {
+ BreakpointNameOptionGroup()
+ : OptionGroup(), m_breakpoint(LLDB_INVALID_BREAK_ID), m_use_dummy(false) {
+ }
+
+ ~BreakpointNameOptionGroup() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_name_options);
+ }
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = g_breakpoint_name_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'N':
+ if (BreakpointID::StringIsBreakpointName(option_arg, error) &&
+ error.Success())
+ m_name.SetValueFromString(option_arg);
+ break;
+
+ case 'B':
+ if (m_breakpoint.SetValueFromString(option_arg).Fail())
+ error.SetErrorStringWithFormat(
+ "unrecognized value \"%s\" for breakpoint",
+ option_arg.str().c_str());
+ break;
+ case 'D':
+ if (m_use_dummy.SetValueFromString(option_arg).Fail())
+ error.SetErrorStringWithFormat(
+ "unrecognized value \"%s\" for use-dummy",
+ option_arg.str().c_str());
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'",
+ short_option);
+ break;
}
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_name.Clear();
+ m_breakpoint.Clear();
+ m_use_dummy.Clear();
+ m_use_dummy.SetDefaultValue(false);
+ }
+
+ OptionValueString m_name;
+ OptionValueUInt64 m_breakpoint;
+ OptionValueBoolean m_use_dummy;
+};
- ~BreakpointNameOptionGroup() override = default;
+class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointNameAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "add", "Add a name to the breakpoints provided.",
+ "breakpoint name add <command-options> <breakpoint-id-list>"),
+ m_name_options(), m_option_group() {
+ // Create the first variant for the first (and only) argument for this
+ // command.
+ CommandArgumentEntry arg1;
+ CommandArgumentData id_arg;
+ id_arg.arg_type = eArgTypeBreakpointID;
+ id_arg.arg_repetition = eArgRepeatOptional;
+ arg1.push_back(id_arg);
+ m_arguments.push_back(arg1);
+
+ m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectBreakpointNameAdd() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
- uint32_t
- GetNumDefinitions () override
- {
- return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (!m_name_options.m_name.OptionWasSet()) {
+ result.SetError("No name option provided.");
+ return false;
}
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_breakpoint_name_options;
+ Target *target =
+ GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- Error
- SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_value) override
- {
- Error error;
- const int short_option = g_breakpoint_name_options[option_idx].short_option;
-
- switch (short_option)
- {
- case 'N':
- if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
- m_name.SetValueFromString(option_value);
- break;
-
- case 'B':
- if (m_breakpoint.SetValueFromString(option_value).Fail())
- error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
- break;
- case 'D':
- if (m_use_dummy.SetValueFromString(option_value).Fail())
- error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
- break;
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
- break;
- }
- return error;
+ const BreakpointList &breakpoints = target->GetBreakpointList();
+
+ size_t num_breakpoints = breakpoints.GetSize();
+ if (num_breakpoints == 0) {
+ result.SetError("No breakpoints, cannot add names.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- void
- OptionParsingStarting (CommandInterpreter &interpreter) override
- {
- m_name.Clear();
- m_breakpoint.Clear();
- m_use_dummy.Clear();
- m_use_dummy.SetDefaultValue(false);
+ // Particular breakpoint selected; disable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ if (valid_bp_ids.GetSize() == 0) {
+ result.SetError("No breakpoints specified, cannot add names.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ size_t num_valid_ids = valid_bp_ids.GetSize();
+ for (size_t index = 0; index < num_valid_ids; index++) {
+ lldb::break_id_t bp_id =
+ valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
+ BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
+ Error error; // We don't need to check the error here, since the option
+ // parser checked it...
+ bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
+ }
}
- OptionValueString m_name;
- OptionValueUInt64 m_breakpoint;
- OptionValueBoolean m_use_dummy;
+ return true;
+ }
+
+private:
+ BreakpointNameOptionGroup m_name_options;
+ OptionGroupOptions m_option_group;
};
-class CommandObjectBreakpointNameAdd : public CommandObjectParsed
-{
+class CommandObjectBreakpointNameDelete : public CommandObjectParsed {
public:
- CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "add",
- "Add a name to the breakpoints provided.",
- "breakpoint name add <command-options> <breakpoint-id-list>"),
- m_name_options(),
- m_option_group(interpreter)
- {
- // Create the first variant for the first (and only) argument for this command.
- CommandArgumentEntry arg1;
- CommandArgumentData id_arg;
- id_arg.arg_type = eArgTypeBreakpointID;
- id_arg.arg_repetition = eArgRepeatOptional;
- arg1.push_back(id_arg);
- m_arguments.push_back (arg1);
-
- m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
- m_option_group.Finalize();
- }
+ CommandObjectBreakpointNameDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "delete",
+ "Delete a name from the breakpoints provided.",
+ "breakpoint name delete <command-options> <breakpoint-id-list>"),
+ m_name_options(), m_option_group() {
+ // Create the first variant for the first (and only) argument for this
+ // command.
+ CommandArgumentEntry arg1;
+ CommandArgumentData id_arg;
+ id_arg.arg_type = eArgTypeBreakpointID;
+ id_arg.arg_repetition = eArgRepeatOptional;
+ arg1.push_back(id_arg);
+ m_arguments.push_back(arg1);
+
+ m_option_group.Append(&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectBreakpointNameDelete() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (!m_name_options.m_name.OptionWasSet()) {
+ result.SetError("No name option provided.");
+ return false;
+ }
- ~CommandObjectBreakpointNameAdd() override = default;
+ Target *target =
+ GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
- Options *
- GetOptions() override
- {
- return &m_option_group;
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- if (!m_name_options.m_name.OptionWasSet())
- {
- result.SetError("No name option provided.");
- return false;
- }
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+ const BreakpointList &breakpoints = target->GetBreakpointList();
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ size_t num_breakpoints = breakpoints.GetSize();
+ if (num_breakpoints == 0) {
+ result.SetError("No breakpoints, cannot delete names.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ // Particular breakpoint selected; disable that breakpoint.
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ if (valid_bp_ids.GetSize() == 0) {
+ result.SetError("No breakpoints specified, cannot delete names.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ size_t num_valid_ids = valid_bp_ids.GetSize();
+ for (size_t index = 0; index < num_valid_ids; index++) {
+ lldb::break_id_t bp_id =
+ valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
+ BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
+ bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
+ }
+ }
- const BreakpointList &breakpoints = target->GetBreakpointList();
+ return true;
+ }
- size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.SetError("No breakpoints, cannot add names.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+private:
+ BreakpointNameOptionGroup m_name_options;
+ OptionGroupOptions m_option_group;
+};
- // Particular breakpoint selected; disable that breakpoint.
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- if (valid_bp_ids.GetSize() == 0)
- {
- result.SetError("No breakpoints specified, cannot add names.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- size_t num_valid_ids = valid_bp_ids.GetSize();
- for (size_t index = 0; index < num_valid_ids; index++)
- {
- lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
- BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
- Error error; // We don't need to check the error here, since the option parser checked it...
- bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
- }
- }
+class CommandObjectBreakpointNameList : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointNameList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "list",
+ "List either the names for a breakpoint or the "
+ "breakpoints for a given name.",
+ "breakpoint name list <command-options>"),
+ m_name_options(), m_option_group() {
+ m_option_group.Append(&m_name_options);
+ m_option_group.Finalize();
+ }
- return true;
+ ~CommandObjectBreakpointNameList() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target =
+ GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ if (m_name_options.m_name.OptionWasSet()) {
+ const char *name = m_name_options.m_name.GetCurrentValue();
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
+
+ BreakpointList &breakpoints = target->GetBreakpointList();
+ for (BreakpointSP bp_sp : breakpoints.Breakpoints()) {
+ if (bp_sp->MatchesName(name)) {
+ StreamString s;
+ bp_sp->GetDescription(&s, eDescriptionLevelBrief);
+ s.EOL();
+ result.AppendMessage(s.GetString());
+ }
+ }
+
+ } else if (m_name_options.m_breakpoint.OptionWasSet()) {
+ BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(
+ m_name_options.m_breakpoint.GetCurrentValue());
+ if (bp_sp) {
+ std::vector<std::string> names;
+ bp_sp->GetNames(names);
+ result.AppendMessage("Names:");
+ for (auto name : names)
+ result.AppendMessageWithFormat(" %s\n", name.c_str());
+ } else {
+ result.AppendErrorWithFormat(
+ "Could not find breakpoint %" PRId64 ".\n",
+ m_name_options.m_breakpoint.GetCurrentValue());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ result.SetError("Must specify -N or -B option to list.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ return true;
+ }
+
private:
- BreakpointNameOptionGroup m_name_options;
- OptionGroupOptions m_option_group;
+ BreakpointNameOptionGroup m_name_options;
+ OptionGroupOptions m_option_group;
};
-class CommandObjectBreakpointNameDelete : public CommandObjectParsed
-{
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointName
+//-------------------------------------------------------------------------
+class CommandObjectBreakpointName : public CommandObjectMultiword {
public:
- CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "delete",
- "Delete a name from the breakpoints provided.",
- "breakpoint name delete <command-options> <breakpoint-id-list>"),
- m_name_options(),
- m_option_group(interpreter)
- {
- // Create the first variant for the first (and only) argument for this command.
- CommandArgumentEntry arg1;
- CommandArgumentData id_arg;
- id_arg.arg_type = eArgTypeBreakpointID;
- id_arg.arg_repetition = eArgRepeatOptional;
- arg1.push_back(id_arg);
- m_arguments.push_back (arg1);
+ CommandObjectBreakpointName(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "name", "Commands to manage name tags for breakpoints",
+ "breakpoint name <subcommand> [<command-options>]") {
+ CommandObjectSP add_command_object(
+ new CommandObjectBreakpointNameAdd(interpreter));
+ CommandObjectSP delete_command_object(
+ new CommandObjectBreakpointNameDelete(interpreter));
+ CommandObjectSP list_command_object(
+ new CommandObjectBreakpointNameList(interpreter));
+
+ LoadSubCommand("add", add_command_object);
+ LoadSubCommand("delete", delete_command_object);
+ LoadSubCommand("list", list_command_object);
+ }
+
+ ~CommandObjectBreakpointName() override = default;
+};
- m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
- m_option_group.Finalize();
- }
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointRead
+//-------------------------------------------------------------------------
+#pragma mark Read::CommandOptions
+static OptionDefinition g_breakpoint_read_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." },
+ {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Only read in breakpoints with this name."},
+ // clang-format on
+};
- ~CommandObjectBreakpointNameDelete() override = default;
+#pragma mark Read
- Options *
- GetOptions() override
- {
- return &m_option_group;
+class CommandObjectBreakpointRead : public CommandObjectParsed {
+public:
+ CommandObjectBreakpointRead(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint read",
+ "Read and set the breakpoints previously saved to "
+ "a file with \"breakpoint write\". ",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointRead() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ m_filename.assign(option_arg);
+ break;
+ case 'N': {
+ Error name_error;
+ if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg),
+ name_error)) {
+ error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
+ name_error.AsCString());
+ }
+ m_names.push_back(option_arg);
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- if (!m_name_options.m_name.OptionWasSet())
- {
- result.SetError("No name option provided.");
- return false;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_filename.clear();
+ m_names.clear();
+ }
- Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_read_options);
+ }
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Instance variables to hold the values for command options.
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
+ std::string m_filename;
+ std::vector<std::string> m_names;
+ };
- const BreakpointList &breakpoints = target->GetBreakpointList();
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.SetError("No breakpoints, cannot delete names.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
- // Particular breakpoint selected; disable that breakpoint.
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- if (valid_bp_ids.GetSize() == 0)
- {
- result.SetError("No breakpoints specified, cannot delete names.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- size_t num_valid_ids = valid_bp_ids.GetSize();
- for (size_t index = 0; index < num_valid_ids; index++)
- {
- lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
- BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
- bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
- }
- }
+ FileSpec input_spec(m_options.m_filename, true);
+ BreakpointIDList new_bps;
+ Error error = target->CreateBreakpointsFromFile(input_spec,
+ m_options.m_names, new_bps);
+
+ if (!error.Success()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- return true;
+ Stream &output_stream = result.GetOutputStream();
+
+ size_t num_breakpoints = new_bps.GetSize();
+ if (num_breakpoints == 0) {
+ result.AppendMessage("No breakpoints added.");
+ } else {
+ // No breakpoint selected; show info about all currently set breakpoints.
+ result.AppendMessage("New breakpoints:");
+ for (size_t i = 0; i < num_breakpoints; ++i) {
+ BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i);
+ Breakpoint *bp = target->GetBreakpointList()
+ .FindBreakpointByID(bp_id.GetBreakpointID())
+ .get();
+ if (bp)
+ bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
+ false);
+ }
}
+ return result.Succeeded();
+ }
private:
- BreakpointNameOptionGroup m_name_options;
- OptionGroupOptions m_option_group;
+ CommandOptions m_options;
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointWrite
+//-------------------------------------------------------------------------
+#pragma mark Write::CommandOptions
+static OptionDefinition g_breakpoint_write_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." },
+ { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."},
+ // clang-format on
};
-class CommandObjectBreakpointNameList : public CommandObjectParsed
-{
+#pragma mark Write
+class CommandObjectBreakpointWrite : public CommandObjectParsed {
public:
- CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "list",
- "List either the names for a breakpoint or the breakpoints for a given name.",
- "breakpoint name list <command-options>"),
- m_name_options(),
- m_option_group(interpreter)
- {
- m_option_group.Append (&m_name_options);
- m_option_group.Finalize();
+ CommandObjectBreakpointWrite(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "breakpoint write",
+ "Write the breakpoints listed to a file that can "
+ "be read in with \"breakpoint read\". "
+ "If given no arguments, writes all breakpoints.",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID,
+ eArgTypeBreakpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointWrite() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ m_filename.assign(option_arg);
+ break;
+ case 'a':
+ m_append = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectBreakpointNameList() override = default;
-
- Options *
- GetOptions() override
- {
- return &m_option_group;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_filename.clear();
+ m_append = false;
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_write_options);
+ }
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or breakpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Instance variables to hold the values for command options.
- if (m_name_options.m_name.OptionWasSet())
- {
- const char *name = m_name_options.m_name.GetCurrentValue();
- std::unique_lock<std::recursive_mutex> lock;
- target->GetBreakpointList().GetListMutex(lock);
-
- BreakpointList &breakpoints = target->GetBreakpointList();
- for (BreakpointSP bp_sp : breakpoints.Breakpoints())
- {
- if (bp_sp->MatchesName(name))
- {
- StreamString s;
- bp_sp->GetDescription(&s, eDescriptionLevelBrief);
- s.EOL();
- result.AppendMessage(s.GetData());
- }
- }
+ std::string m_filename;
+ bool m_append = false;
+ };
- }
- else if (m_name_options.m_breakpoint.OptionWasSet())
- {
- BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
- if (bp_sp)
- {
- std::vector<std::string> names;
- bp_sp->GetNames (names);
- result.AppendMessage ("Names:");
- for (auto name : names)
- result.AppendMessageWithFormat (" %s\n", name.c_str());
- }
- else
- {
- result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
- m_name_options.m_breakpoint.GetCurrentValue());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- result.SetError ("Must specify -N or -B option to list.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- return true;
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-private:
- BreakpointNameOptionGroup m_name_options;
- OptionGroupOptions m_option_group;
-};
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetBreakpointList().GetListMutex(lock);
-//-------------------------------------------------------------------------
-// CommandObjectMultiwordBreakpoint
-//-------------------------------------------------------------------------
-class CommandObjectBreakpointName : public CommandObjectMultiword
-{
-public:
- CommandObjectBreakpointName(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "name", "Commands to manage name tags for breakpoints",
- "breakpoint name <subcommand> [<command-options>]")
- {
- CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
- CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
- CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
+ BreakpointIDList valid_bp_ids;
+ if (!command.empty()) {
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
+ command, target, result, &valid_bp_ids);
- LoadSubCommand ("add", add_command_object);
- LoadSubCommand ("delete", delete_command_object);
- LoadSubCommand ("list", list_command_object);
+ if (!result.Succeeded()) {
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ Error error = target->SerializeBreakpointsToFile(
+ FileSpec(m_options.m_filename, true), valid_bp_ids, m_options.m_append);
+ if (!error.Success()) {
+ result.AppendErrorWithFormat("error serializing breakpoints: %s.",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
- ~CommandObjectBreakpointName() override = default;
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -2369,120 +2300,142 @@ public:
//-------------------------------------------------------------------------
#pragma mark MultiwordBreakpoint
-CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "breakpoint",
- "Commands for operating on breakpoints (see 'help b' for shorthand.)",
- "breakpoint <subcommand> [<command-options>]")
-{
- CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
- CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
- CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
- CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
- CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
- CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
- CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
- CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
- CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
-
- list_command_object->SetCommandName ("breakpoint list");
- enable_command_object->SetCommandName("breakpoint enable");
- disable_command_object->SetCommandName("breakpoint disable");
- clear_command_object->SetCommandName("breakpoint clear");
- delete_command_object->SetCommandName("breakpoint delete");
- set_command_object->SetCommandName("breakpoint set");
- command_command_object->SetCommandName ("breakpoint command");
- modify_command_object->SetCommandName ("breakpoint modify");
- name_command_object->SetCommandName ("breakpoint name");
-
- LoadSubCommand ("list", list_command_object);
- LoadSubCommand ("enable", enable_command_object);
- LoadSubCommand ("disable", disable_command_object);
- LoadSubCommand ("clear", clear_command_object);
- LoadSubCommand ("delete", delete_command_object);
- LoadSubCommand ("set", set_command_object);
- LoadSubCommand ("command", command_command_object);
- LoadSubCommand ("modify", modify_command_object);
- LoadSubCommand ("name", name_command_object);
+CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "breakpoint",
+ "Commands for operating on breakpoints (see 'help b' for shorthand.)",
+ "breakpoint <subcommand> [<command-options>]") {
+ CommandObjectSP list_command_object(
+ new CommandObjectBreakpointList(interpreter));
+ CommandObjectSP enable_command_object(
+ new CommandObjectBreakpointEnable(interpreter));
+ CommandObjectSP disable_command_object(
+ new CommandObjectBreakpointDisable(interpreter));
+ CommandObjectSP clear_command_object(
+ new CommandObjectBreakpointClear(interpreter));
+ CommandObjectSP delete_command_object(
+ new CommandObjectBreakpointDelete(interpreter));
+ CommandObjectSP set_command_object(
+ new CommandObjectBreakpointSet(interpreter));
+ CommandObjectSP command_command_object(
+ new CommandObjectBreakpointCommand(interpreter));
+ CommandObjectSP modify_command_object(
+ new CommandObjectBreakpointModify(interpreter));
+ CommandObjectSP name_command_object(
+ new CommandObjectBreakpointName(interpreter));
+ CommandObjectSP write_command_object(
+ new CommandObjectBreakpointWrite(interpreter));
+ CommandObjectSP read_command_object(
+ new CommandObjectBreakpointRead(interpreter));
+
+ list_command_object->SetCommandName("breakpoint list");
+ enable_command_object->SetCommandName("breakpoint enable");
+ disable_command_object->SetCommandName("breakpoint disable");
+ clear_command_object->SetCommandName("breakpoint clear");
+ delete_command_object->SetCommandName("breakpoint delete");
+ set_command_object->SetCommandName("breakpoint set");
+ command_command_object->SetCommandName("breakpoint command");
+ modify_command_object->SetCommandName("breakpoint modify");
+ name_command_object->SetCommandName("breakpoint name");
+ write_command_object->SetCommandName("breakpoint write");
+ read_command_object->SetCommandName("breakpoint read");
+
+ LoadSubCommand("list", list_command_object);
+ LoadSubCommand("enable", enable_command_object);
+ LoadSubCommand("disable", disable_command_object);
+ LoadSubCommand("clear", clear_command_object);
+ LoadSubCommand("delete", delete_command_object);
+ LoadSubCommand("set", set_command_object);
+ LoadSubCommand("command", command_command_object);
+ LoadSubCommand("modify", modify_command_object);
+ LoadSubCommand("name", name_command_object);
+ LoadSubCommand("write", write_command_object);
+ LoadSubCommand("read", read_command_object);
}
CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
-void
-CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
- Target *target,
- bool allow_locations,
- CommandReturnObject &result,
- BreakpointIDList *valid_ids)
-{
- // args can be strings representing 1). integers (for breakpoint ids)
- // 2). the full breakpoint & location canonical representation
- // 3). the word "to" or a hyphen, representing a range (in which case there
- // had *better* be an entry both before & after of one of the first two types.
- // 4). A breakpoint name
- // If args is empty, we will use the last created breakpoint (if there is one.)
-
- Args temp_args;
-
- if (args.GetArgumentCount() == 0)
- {
- if (target->GetLastCreatedBreakpoint())
- {
- valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError("No breakpoint specified and no last created breakpoint.");
- result.SetStatus (eReturnStatusFailed);
- }
- return;
+void CommandObjectMultiwordBreakpoint::VerifyIDs(Args &args, Target *target,
+ bool allow_locations,
+ CommandReturnObject &result,
+ BreakpointIDList *valid_ids) {
+ // args can be strings representing 1). integers (for breakpoint ids)
+ // 2). the full breakpoint & location
+ // canonical representation
+ // 3). the word "to" or a hyphen,
+ // representing a range (in which case there
+ // had *better* be an entry both before &
+ // after of one of the first two types.
+ // 4). A breakpoint name
+ // If args is empty, we will use the last created breakpoint (if there is
+ // one.)
+
+ Args temp_args;
+
+ if (args.empty()) {
+ if (target->GetLastCreatedBreakpoint()) {
+ valid_ids->AddBreakpointID(BreakpointID(
+ target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError(
+ "No breakpoint specified and no last created breakpoint.");
+ result.SetStatus(eReturnStatusFailed);
}
-
- // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
- // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead generate a list of strings for
- // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
-
- BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
-
- // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
-
- valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
-
- // At this point, all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
- // and put into valid_ids.
-
- if (result.Succeeded())
- {
- // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
- // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
-
- const size_t count = valid_ids->GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
- Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- if (breakpoint != nullptr)
- {
- const size_t num_locations = breakpoint->GetNumLocations();
- if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
- {
- StreamString id_str;
- BreakpointID::GetCanonicalReference (&id_str,
- cur_bp_id.GetBreakpointID(),
- cur_bp_id.GetLocationID());
- i = valid_ids->GetSize() + 1;
- result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
- id_str.GetData());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- i = valid_ids->GetSize() + 1;
- result.AppendErrorWithFormat("'%d' is not a currently valid breakpoint ID.\n",
- cur_bp_id.GetBreakpointID());
- result.SetStatus (eReturnStatusFailed);
- }
- }
+ return;
+ }
+
+ // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff
+ // directly from the old ARGS to
+ // the new TEMP_ARGS. Do not copy breakpoint id range strings over; instead
+ // generate a list of strings for
+ // all the breakpoint ids in the range, and shove all of those breakpoint id
+ // strings into TEMP_ARGS.
+
+ BreakpointIDList::FindAndReplaceIDRanges(args, target, allow_locations,
+ result, temp_args);
+
+ // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual
+ // BreakpointIDList:
+
+ valid_ids->InsertStringArray(temp_args.GetConstArgumentVector(),
+ temp_args.GetArgumentCount(), result);
+
+ // At this point, all of the breakpoint ids that the user passed in have been
+ // converted to breakpoint IDs
+ // and put into valid_ids.
+
+ if (result.Succeeded()) {
+ // Now that we've converted everything from args into a list of breakpoint
+ // ids, go through our tentative list
+ // of breakpoint id's and verify that they correspond to valid/currently set
+ // breakpoints.
+
+ const size_t count = valid_ids->GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex(i);
+ Breakpoint *breakpoint =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ if (breakpoint != nullptr) {
+ const size_t num_locations = breakpoint->GetNumLocations();
+ if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations) {
+ StreamString id_str;
+ BreakpointID::GetCanonicalReference(
+ &id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID());
+ i = valid_ids->GetSize() + 1;
+ result.AppendErrorWithFormat(
+ "'%s' is not a currently valid breakpoint/location id.\n",
+ id_str.GetData());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ i = valid_ids->GetSize() + 1;
+ result.AppendErrorWithFormat(
+ "'%d' is not a currently valid breakpoint ID.\n",
+ cur_bp_id.GetBreakpointID());
+ result.SetStatus(eReturnStatusFailed);
+ }
}
+ }
}
diff --git a/source/Commands/CommandObjectBreakpoint.h b/source/Commands/CommandObjectBreakpoint.h
index 123e8232c987..6e14b8f876a0 100644
--- a/source/Commands/CommandObjectBreakpoint.h
+++ b/source/Commands/CommandObjectBreakpoint.h
@@ -19,9 +19,9 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Address.h"
+#include "lldb/Core/STLUtils.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/Options.h"
-#include "lldb/Core/STLUtils.h"
namespace lldb_private {
@@ -29,28 +29,28 @@ namespace lldb_private {
// CommandObjectMultiwordBreakpoint
//-------------------------------------------------------------------------
-class CommandObjectMultiwordBreakpoint : public CommandObjectMultiword
-{
+class CommandObjectMultiwordBreakpoint : public CommandObjectMultiword {
public:
- CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter);
+ CommandObjectMultiwordBreakpoint(CommandInterpreter &interpreter);
- ~CommandObjectMultiwordBreakpoint() override;
+ ~CommandObjectMultiwordBreakpoint() override;
- static void
- VerifyBreakpointOrLocationIDs (Args &args, Target *target, CommandReturnObject &result, BreakpointIDList *valid_ids)
- {
- VerifyIDs (args, target, true, result, valid_ids);
- }
+ static void VerifyBreakpointOrLocationIDs(Args &args, Target *target,
+ CommandReturnObject &result,
+ BreakpointIDList *valid_ids) {
+ VerifyIDs(args, target, true, result, valid_ids);
+ }
- static void
- VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result, BreakpointIDList *valid_ids)
- {
- VerifyIDs (args, target, false, result, valid_ids);
- }
+ static void VerifyBreakpointIDs(Args &args, Target *target,
+ CommandReturnObject &result,
+ BreakpointIDList *valid_ids) {
+ VerifyIDs(args, target, false, result, valid_ids);
+ }
private:
- static void
- VerifyIDs (Args &args, Target *target, bool allow_locations, CommandReturnObject &result, BreakpointIDList *valid_ids);
+ static void VerifyIDs(Args &args, Target *target, bool allow_locations,
+ CommandReturnObject &result,
+ BreakpointIDList *valid_ids);
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp
index 57572c8ef144..5e4ee0ba0700 100644
--- a/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -13,16 +13,18 @@
// Project includes
#include "CommandObjectBreakpointCommand.h"
#include "CommandObjectBreakpoint.h"
+#include "lldb/Breakpoint/Breakpoint.h"
+#include "lldb/Breakpoint/BreakpointIDList.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/IOHandler.h"
+#include "lldb/Core/State.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Breakpoint/BreakpointIDList.h"
-#include "lldb/Breakpoint/Breakpoint.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Core/State.h"
+
+#include "llvm/ADT/STLExtras.h"
using namespace lldb;
using namespace lldb_private;
@@ -31,44 +33,75 @@ using namespace lldb_private;
// CommandObjectBreakpointCommandAdd
//-------------------------------------------------------------------------
-class CommandObjectBreakpointCommandAdd :
- public CommandObjectParsed,
- public IOHandlerDelegateMultiline
-{
+// FIXME: "script-type" needs to have its contents determined dynamically, so
+// somebody can add a new scripting
+// language to lldb and have it pickable here without having to change this
+// enumeration by hand and rebuild lldb proper.
+
+static OptionEnumValueElement g_script_option_enumeration[4] = {
+ {eScriptLanguageNone, "command",
+ "Commands are in the lldb command interpreter language"},
+ {eScriptLanguagePython, "python", "Commands are in the Python language."},
+ {eSortOrderByName, "default-script",
+ "Commands are in the default scripting language."},
+ {0, nullptr, nullptr}};
+
+static OptionDefinition g_breakpoint_add_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
+ { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Specify whether breakpoint command execution should terminate on error." },
+ { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." },
+ { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate." },
+ { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
+ // clang-format on
+};
+
+class CommandObjectBreakpointCommandAdd : public CommandObjectParsed,
+ public IOHandlerDelegateMultiline {
public:
- CommandObjectBreakpointCommandAdd(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "add",
- "Add LLDB commands to a breakpoint, to be executed whenever the breakpoint is hit."
- " If no breakpoint is specified, adds the commands to the last created breakpoint.",
- nullptr),
- IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand),
- m_options(interpreter)
- {
- SetHelpLong (
-R"(
+ CommandObjectBreakpointCommandAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "add",
+ "Add LLDB commands to a breakpoint, to be executed "
+ "whenever the breakpoint is hit."
+ " If no breakpoint is specified, adds the "
+ "commands to the last created breakpoint.",
+ nullptr),
+ IOHandlerDelegateMultiline("DONE",
+ IOHandlerDelegate::Completion::LLDBCommand),
+ m_options() {
+ SetHelpLong(
+ R"(
General information about entering breakpoint commands
------------------------------------------------------
-)" "This command will prompt for commands to be executed when the specified \
+)"
+ "This command will prompt for commands to be executed when the specified \
breakpoint is hit. Each command is typed on its own line following the '> ' \
-prompt until 'DONE' is entered." R"(
+prompt until 'DONE' is entered."
+ R"(
-)" "Syntactic errors may not be detected when initially entered, and many \
+)"
+ "Syntactic errors may not be detected when initially entered, and many \
malformed commands can silently fail when executed. If your breakpoint commands \
-do not appear to be executing, double-check the command syntax." R"(
+do not appear to be executing, double-check the command syntax."
+ R"(
-)" "Note: You may enter any debugger command exactly as you would at the debugger \
+)"
+ "Note: You may enter any debugger command exactly as you would at the debugger \
prompt. There is no limit to the number of commands supplied, but do NOT enter \
-more than one command per line." R"(
+more than one command per line."
+ R"(
Special information about PYTHON breakpoint commands
----------------------------------------------------
-)" "You may enter either one or more lines of Python, including function \
+)"
+ "You may enter either one or more lines of Python, including function \
definitions or calls to functions that will have been imported by the time \
the code executes. Single line breakpoint commands will be interpreted 'as is' \
when the breakpoint is hit. Multiple lines of Python will be wrapped in a \
-generated function, and a call to the function will be attached to the breakpoint." R"(
+generated function, and a call to the function will be attached to the breakpoint."
+ R"(
This auto-generated function is passed in three arguments:
@@ -78,8 +111,10 @@ This auto-generated function is passed in three arguments:
dict: the python session dictionary hit.
-)" "When specifying a python function with the --python-function option, you need \
-to supply the function name prepended by the module name:" R"(
+)"
+ "When specifying a python function with the --python-function option, you need \
+to supply the function name prepended by the module name:"
+ R"(
--python-function myutils.breakpoint_callback
@@ -88,16 +123,20 @@ The function itself must have the following prototype:
def breakpoint_callback(frame, bp_loc, dict):
# Your code goes here
-)" "The arguments are the same as the arguments passed to generated functions as \
+)"
+ "The arguments are the same as the arguments passed to generated functions as \
described above. Note that the global variable 'lldb.frame' will NOT be updated when \
this function is called, so be sure to use the 'frame' argument. The 'frame' argument \
can get you to the thread via frame.GetThread(), the thread can get you to the \
process via thread.GetProcess(), and the process can get you back to the target \
-via process.GetTarget()." R"(
+via process.GetTarget()."
+ R"(
-)" "Important Note: As Python code gets collected into functions, access to global \
+)"
+ "Important Note: As Python code gets collected into functions, access to global \
variables requires explicit scoping using the 'global' keyword. Be sure to use correct \
-Python syntax, including indentation, when entering Python breakpoint commands." R"(
+Python syntax, including indentation, when entering Python breakpoint commands."
+ R"(
Example Python one-line breakpoint command:
@@ -142,735 +181,572 @@ Enter your Python command(s). Type 'DONE' to end.
> breakpoint_output (1)
> DONE
-)" "In this case, since there is a reference to a global variable, \
+)"
+ "In this case, since there is a reference to a global variable, \
'bp_count', you will also need to make sure 'bp_count' exists and is \
-initialized:" R"(
+initialized:"
+ R"(
(lldb) script
>>> bp_count = 0
>>> quit()
-)" "Your Python code, however organized, can optionally return a value. \
+)"
+ "Your Python code, however organized, can optionally return a value. \
If the returned value is False, that tells LLDB not to stop at the breakpoint \
to which the code is associated. Returning anything other than False, or even \
returning None, or even omitting a return statement entirely, will cause \
-LLDB to stop." R"(
+LLDB to stop."
+ R"(
-)" "Final Note: A warning that no breakpoint command was generated when there \
-are no syntax errors may indicate that a function was declared but never called."
- );
+)"
+ "Final Note: A warning that no breakpoint command was generated when there \
+are no syntax errors may indicate that a function was declared but never called.");
- CommandArgumentEntry arg;
- CommandArgumentData bp_id_arg;
+ CommandArgumentEntry arg;
+ CommandArgumentData bp_id_arg;
- // Define the first (and only) variant of this arg.
- bp_id_arg.arg_type = eArgTypeBreakpointID;
- bp_id_arg.arg_repetition = eArgRepeatOptional;
+ // Define the first (and only) variant of this arg.
+ bp_id_arg.arg_type = eArgTypeBreakpointID;
+ bp_id_arg.arg_repetition = eArgRepeatOptional;
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (bp_id_arg);
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(bp_id_arg);
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
- ~CommandObjectBreakpointCommandAdd() override = default;
+ ~CommandObjectBreakpointCommandAdd() override = default;
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ Options *GetOptions() override { return &m_options; }
- void
- IOHandlerActivated (IOHandler &io_handler) override
- {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- if (output_sp)
- {
- output_sp->PutCString(g_reader_instructions);
- output_sp->Flush();
- }
+ void IOHandlerActivated(IOHandler &io_handler) override {
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp) {
+ output_sp->PutCString(g_reader_instructions);
+ output_sp->Flush();
}
+ }
- void
- IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override
- {
- io_handler.SetIsDone(true);
-
- std::vector<BreakpointOptions *> *bp_options_vec = (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
- for (BreakpointOptions *bp_options : *bp_options_vec)
- {
- if (!bp_options)
- continue;
-
- std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
- if (data_ap)
- {
- data_ap->user_source.SplitIntoLines (line.c_str(), line.size());
- BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
- bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp);
- }
- }
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &line) override {
+ io_handler.SetIsDone(true);
+
+ std::vector<BreakpointOptions *> *bp_options_vec =
+ (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
+ for (BreakpointOptions *bp_options : *bp_options_vec) {
+ if (!bp_options)
+ continue;
+
+ auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
+ cmd_data->user_source.SplitIntoLines(line.c_str(), line.size());
+ bp_options->SetCommandDataCallback(cmd_data);
}
-
- void
- CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec,
- CommandReturnObject &result)
- {
- m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt
- *this, // IOHandlerDelegate
- true, // Run IOHandler in async mode
- &bp_options_vec); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
+ }
+
+ void CollectDataForBreakpointCommandCallback(
+ std::vector<BreakpointOptions *> &bp_options_vec,
+ CommandReturnObject &result) {
+ m_interpreter.GetLLDBCommandsFromIOHandler(
+ "> ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ &bp_options_vec); // Baton for the "io_handler" that will be passed back
+ // into our IOHandlerDelegate functions
+ }
+
+ /// Set a one-liner as the callback for the breakpoint.
+ void
+ SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec,
+ const char *oneliner) {
+ for (auto bp_options : bp_options_vec) {
+ auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>();
+
+ cmd_data->user_source.AppendString(oneliner);
+ cmd_data->stop_on_error = m_options.m_stop_on_error;
+
+ bp_options->SetCommandDataCallback(cmd_data);
}
-
- /// Set a one-liner as the callback for the breakpoint.
- void
- SetBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec,
- const char *oneliner)
- {
- for (auto bp_options : bp_options_vec)
- {
- std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
-
- // It's necessary to set both user_source and script_source to the oneliner.
- // The former is used to generate callback description (as in breakpoint command list)
- // while the latter is used for Python to interpret during the actual callback.
- data_ap->user_source.AppendString (oneliner);
- data_ap->script_source.assign (oneliner);
- data_ap->stop_on_error = m_options.m_stop_on_error;
-
- BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
- bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp);
+ }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_use_commands(false), m_use_script_language(false),
+ m_script_language(eScriptLanguageNone), m_use_one_liner(false),
+ m_one_liner(), m_function_name() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'o':
+ m_use_one_liner = true;
+ m_one_liner = option_arg;
+ break;
+
+ case 's':
+ m_script_language = (lldb::ScriptLanguage)Args::StringToOptionEnum(
+ option_arg, g_breakpoint_add_options[option_idx].enum_values,
+ eScriptLanguageNone, error);
+
+ if (m_script_language == eScriptLanguagePython ||
+ m_script_language == eScriptLanguageDefault) {
+ m_use_script_language = true;
+ } else {
+ m_use_script_language = false;
}
+ break;
+
+ case 'e': {
+ bool success = false;
+ m_stop_on_error = Args::StringToBoolean(option_arg, false, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid value for stop-on-error: \"%s\"",
+ option_arg.str().c_str());
+ } break;
+
+ case 'F':
+ m_use_one_liner = false;
+ m_use_script_language = true;
+ m_function_name.assign(option_arg);
+ break;
+
+ case 'D':
+ m_use_dummy = true;
+ break;
+
+ default:
+ break;
+ }
+ return error;
}
-
- static bool
- BreakpointOptionsCallbackFunction (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id)
- {
- bool ret_value = true;
- if (baton == nullptr)
- return true;
-
- BreakpointOptions::CommandData *data = (BreakpointOptions::CommandData *) baton;
- StringList &commands = data->user_source;
-
- if (commands.GetSize() > 0)
- {
- ExecutionContext exe_ctx (context->exe_ctx_ref);
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- CommandReturnObject result;
- Debugger &debugger = target->GetDebugger();
- // Rig up the results secondary output stream to the debugger's, so the output will come out synchronously
- // if the debugger is set up that way.
-
- StreamSP output_stream (debugger.GetAsyncOutputStream());
- StreamSP error_stream (debugger.GetAsyncErrorStream());
- result.SetImmediateOutputStream (output_stream);
- result.SetImmediateErrorStream (error_stream);
-
- CommandInterpreterRunOptions options;
- options.SetStopOnContinue(true);
- options.SetStopOnError (data->stop_on_error);
- options.SetEchoCommands (true);
- options.SetPrintResults (true);
- options.SetAddToHistory (false);
-
- debugger.GetCommandInterpreter().HandleCommands (commands,
- &exe_ctx,
- options,
- result);
- result.GetImmediateOutputStream()->Flush();
- result.GetImmediateErrorStream()->Flush();
- }
- }
- return ret_value;
- }
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_use_commands (false),
- m_use_script_language (false),
- m_script_language (eScriptLanguageNone),
- m_use_one_liner (false),
- m_one_liner(),
- m_function_name()
- {
- }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'o':
- m_use_one_liner = true;
- m_one_liner = option_arg;
- break;
-
- case 's':
- m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg,
- g_option_table[option_idx].enum_values,
- eScriptLanguageNone,
- error);
-
- if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault)
- {
- m_use_script_language = true;
- }
- else
- {
- m_use_script_language = false;
- }
- break;
-
- case 'e':
- {
- bool success = false;
- m_stop_on_error = Args::StringToBoolean(option_arg, false, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid value for stop-on-error: \"%s\"", option_arg);
- }
- break;
-
- case 'F':
- m_use_one_liner = false;
- m_use_script_language = true;
- m_function_name.assign(option_arg);
- break;
-
- case 'D':
- m_use_dummy = true;
- break;
-
- default:
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_use_commands = true;
- m_use_script_language = false;
- m_script_language = eScriptLanguageNone;
-
- m_use_one_liner = false;
- m_stop_on_error = true;
- m_one_liner.clear();
- m_function_name.clear();
- m_use_dummy = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_use_commands = true;
+ m_use_script_language = false;
+ m_script_language = eScriptLanguageNone;
- // Options table: Required for subclasses of Options.
+ m_use_one_liner = false;
+ m_stop_on_error = true;
+ m_one_liner.clear();
+ m_function_name.clear();
+ m_use_dummy = false;
+ }
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_add_options);
+ }
- // Instance variables to hold the values for command options.
+ // Instance variables to hold the values for command options.
- bool m_use_commands;
- bool m_use_script_language;
- lldb::ScriptLanguage m_script_language;
+ bool m_use_commands;
+ bool m_use_script_language;
+ lldb::ScriptLanguage m_script_language;
- // Instance variables to hold the values for one_liner options.
- bool m_use_one_liner;
- std::string m_one_liner;
- bool m_stop_on_error;
- std::string m_function_name;
- bool m_use_dummy;
- };
+ // Instance variables to hold the values for one_liner options.
+ bool m_use_one_liner;
+ std::string m_one_liner;
+ bool m_stop_on_error;
+ std::string m_function_name;
+ bool m_use_dummy;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
-
- if (target == nullptr)
- {
- result.AppendError ("There is not a current executable; there are no breakpoints to which to add commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+
+ if (target == nullptr) {
+ result.AppendError("There is not a current executable; there are no "
+ "breakpoints to which to add commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- const BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ const BreakpointList &breakpoints = target->GetBreakpointList();
+ size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.AppendError ("No breakpoints exist to have commands added");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_breakpoints == 0) {
+ result.AppendError("No breakpoints exist to have commands added");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (!m_options.m_use_script_language && !m_options.m_function_name.empty())
- {
- result.AppendError ("need to enable scripting to have a function run as a breakpoint command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- m_bp_options_vec.clear();
-
- if (result.Succeeded())
- {
- const size_t count = valid_bp_ids.GetSize();
-
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- BreakpointOptions *bp_options = nullptr;
- if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID)
- {
- // This breakpoint does not have an associated location.
- bp_options = bp->GetOptions();
- }
- else
- {
- BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID()));
- // This breakpoint does have an associated location.
- // Get its breakpoint options.
- if (bp_loc_sp)
- bp_options = bp_loc_sp->GetLocationOptions();
- }
- if (bp_options)
- m_bp_options_vec.push_back (bp_options);
- }
- }
+ if (!m_options.m_use_script_language &&
+ !m_options.m_function_name.empty()) {
+ result.AppendError("need to enable scripting to have a function run as a "
+ "breakpoint command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- // If we are using script language, get the script interpreter
- // in order to set or collect command callback. Otherwise, call
- // the methods associated with this object.
- if (m_options.m_use_script_language)
- {
- ScriptInterpreter *script_interp = m_interpreter.GetScriptInterpreter();
- // Special handling for one-liner specified inline.
- if (m_options.m_use_one_liner)
- {
- script_interp->SetBreakpointCommandCallback (m_bp_options_vec,
- m_options.m_one_liner.c_str());
- }
- else if (!m_options.m_function_name.empty())
- {
- script_interp->SetBreakpointCommandCallbackFunction (m_bp_options_vec,
- m_options.m_function_name.c_str());
- }
- else
- {
- script_interp->CollectDataForBreakpointCommandCallback (m_bp_options_vec,
- result);
- }
- }
- else
- {
- // Special handling for one-liner specified inline.
- if (m_options.m_use_one_liner)
- SetBreakpointCommandCallback (m_bp_options_vec,
- m_options.m_one_liner.c_str());
- else
- CollectDataForBreakpointCommandCallback (m_bp_options_vec,
- result);
- }
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ m_bp_options_vec.clear();
+
+ if (result.Succeeded()) {
+ const size_t count = valid_bp_ids.GetSize();
+
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *bp =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ BreakpointOptions *bp_options = nullptr;
+ if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID) {
+ // This breakpoint does not have an associated location.
+ bp_options = bp->GetOptions();
+ } else {
+ BreakpointLocationSP bp_loc_sp(
+ bp->FindLocationByID(cur_bp_id.GetLocationID()));
+ // This breakpoint does have an associated location.
+ // Get its breakpoint options.
+ if (bp_loc_sp)
+ bp_options = bp_loc_sp->GetLocationOptions();
+ }
+ if (bp_options)
+ m_bp_options_vec.push_back(bp_options);
}
-
- return result.Succeeded();
+ }
+
+ // If we are using script language, get the script interpreter
+ // in order to set or collect command callback. Otherwise, call
+ // the methods associated with this object.
+ if (m_options.m_use_script_language) {
+ ScriptInterpreter *script_interp = m_interpreter.GetScriptInterpreter();
+ // Special handling for one-liner specified inline.
+ if (m_options.m_use_one_liner) {
+ script_interp->SetBreakpointCommandCallback(
+ m_bp_options_vec, m_options.m_one_liner.c_str());
+ } else if (!m_options.m_function_name.empty()) {
+ script_interp->SetBreakpointCommandCallbackFunction(
+ m_bp_options_vec, m_options.m_function_name.c_str());
+ } else {
+ script_interp->CollectDataForBreakpointCommandCallback(
+ m_bp_options_vec, result);
+ }
+ } else {
+ // Special handling for one-liner specified inline.
+ if (m_options.m_use_one_liner)
+ SetBreakpointCommandCallback(m_bp_options_vec,
+ m_options.m_one_liner.c_str());
+ else
+ CollectDataForBreakpointCommandCallback(m_bp_options_vec, result);
+ }
}
-private:
- CommandOptions m_options;
- std::vector<BreakpointOptions *> m_bp_options_vec; // This stores the breakpoint options that we are currently
- // collecting commands for. In the CollectData... calls we need
- // to hand this off to the IOHandler, which may run asynchronously.
- // So we have to have some way to keep it alive, and not leak it.
- // Making it an ivar of the command object, which never goes away
- // achieves this. Note that if we were able to run
- // the same command concurrently in one interpreter we'd have to
- // make this "per invocation". But there are many more reasons
- // why it is not in general safe to do that in lldb at present,
- // so it isn't worthwhile to come up with a more complex mechanism
- // to address this particular weakness right now.
- static const char *g_reader_instructions;
-};
-
-const char *
-CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.\n";
+ return result.Succeeded();
+ }
-// FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting
-// language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper.
-
-static OptionEnumValueElement
-g_script_option_enumeration[4] =
-{
- { eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"},
- { eScriptLanguagePython, "python", "Commands are in the Python language."},
- { eSortOrderByName, "default-script", "Commands are in the default scripting language."},
- { 0, nullptr, nullptr }
+private:
+ CommandOptions m_options;
+ std::vector<BreakpointOptions *> m_bp_options_vec; // This stores the
+ // breakpoint options that
+ // we are currently
+ // collecting commands for. In the CollectData... calls we need
+ // to hand this off to the IOHandler, which may run asynchronously.
+ // So we have to have some way to keep it alive, and not leak it.
+ // Making it an ivar of the command object, which never goes away
+ // achieves this. Note that if we were able to run
+ // the same command concurrently in one interpreter we'd have to
+ // make this "per invocation". But there are many more reasons
+ // why it is not in general safe to do that in lldb at present,
+ // so it isn't worthwhile to come up with a more complex mechanism
+ // to address this particular weakness right now.
+ static const char *g_reader_instructions;
};
-OptionDefinition
-CommandObjectBreakpointCommandAdd::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
- "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
-
- { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
- "Specify whether breakpoint command execution should terminate on error." },
-
- { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 0, eArgTypeNone,
- "Specify the language for the commands - if none is specified, the lldb command interpreter will be used."},
-
- { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction,
- "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate."},
-
- { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
-
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
-};
+const char *CommandObjectBreakpointCommandAdd::g_reader_instructions =
+ "Enter your debugger command(s). Type 'DONE' to end.\n";
//-------------------------------------------------------------------------
// CommandObjectBreakpointCommandDelete
//-------------------------------------------------------------------------
-class CommandObjectBreakpointCommandDelete : public CommandObjectParsed
-{
+static OptionDefinition g_breakpoint_delete_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." },
+ // clang-format on
+};
+
+class CommandObjectBreakpointCommandDelete : public CommandObjectParsed {
public:
- CommandObjectBreakpointCommandDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "delete",
+ CommandObjectBreakpointCommandDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "delete",
"Delete the set of commands from a breakpoint.",
nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData bp_id_arg;
-
- // Define the first (and only) variant of this arg.
- bp_id_arg.arg_type = eArgTypeBreakpointID;
- bp_id_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (bp_id_arg);
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData bp_id_arg;
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ // Define the first (and only) variant of this arg.
+ bp_id_arg.arg_type = eArgTypeBreakpointID;
+ bp_id_arg.arg_repetition = eArgRepeatPlain;
- ~CommandObjectBreakpointCommandDelete() override = default;
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(bp_id_arg);
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_use_dummy (false)
- {
- }
+ ~CommandObjectBreakpointCommandDelete() override = default;
- ~CommandOptions() override = default;
+ Options *GetOptions() override { return &m_options; }
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_use_dummy(false) {}
- switch (short_option)
- {
- case 'D':
- m_use_dummy = true;
- break;
+ ~CommandOptions() override = default;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
- return error;
- }
+ switch (short_option) {
+ case 'D':
+ m_use_dummy = true;
+ break;
- void
- OptionParsingStarting () override
- {
- m_use_dummy = false;
- }
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ return error;
+ }
- // Options table: Required for subclasses of Options.
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_use_dummy = false;
+ }
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_breakpoint_delete_options);
+ }
- // Instance variables to hold the values for command options.
- bool m_use_dummy;
- };
+ // Instance variables to hold the values for command options.
+ bool m_use_dummy;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
-
- if (target == nullptr)
- {
- result.AppendError ("There is not a current executable; there are no breakpoints from which to delete commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
+
+ if (target == nullptr) {
+ result.AppendError("There is not a current executable; there are no "
+ "breakpoints from which to delete commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- const BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ const BreakpointList &breakpoints = target->GetBreakpointList();
+ size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.AppendError ("No breakpoints exist to have commands deleted");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_breakpoints == 0) {
+ result.AppendError("No breakpoints exist to have commands deleted");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- result.AppendError ("No breakpoint specified from which to delete the commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (command.empty()) {
+ result.AppendError(
+ "No breakpoint specified from which to delete the commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- const size_t count = valid_bp_ids.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
- if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
- {
- BreakpointLocationSP bp_loc_sp (bp->FindLocationByID (cur_bp_id.GetLocationID()));
- if (bp_loc_sp)
- bp_loc_sp->ClearCallback();
- else
- {
- result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n",
- cur_bp_id.GetBreakpointID(),
- cur_bp_id.GetLocationID());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- bp->ClearCallback();
- }
- }
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ const size_t count = valid_bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *bp =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
+ BreakpointLocationSP bp_loc_sp(
+ bp->FindLocationByID(cur_bp_id.GetLocationID()));
+ if (bp_loc_sp)
+ bp_loc_sp->ClearCallback();
+ else {
+ result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n",
+ cur_bp_id.GetBreakpointID(),
+ cur_bp_id.GetLocationID());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ } else {
+ bp->ClearCallback();
+ }
}
- return result.Succeeded();
+ }
}
+ return result.Succeeded();
+ }
private:
- CommandOptions m_options;
-};
-
-OptionDefinition
-CommandObjectBreakpointCommandDelete::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
-
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointCommandList
//-------------------------------------------------------------------------
-class CommandObjectBreakpointCommandList : public CommandObjectParsed
-{
+class CommandObjectBreakpointCommandList : public CommandObjectParsed {
public:
- CommandObjectBreakpointCommandList (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "list",
- "List the script or set of commands to be executed when the breakpoint is hit.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandArgumentData bp_id_arg;
-
- // Define the first (and only) variant of this arg.
- bp_id_arg.arg_type = eArgTypeBreakpointID;
- bp_id_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (bp_id_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ CommandObjectBreakpointCommandList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "list", "List the script or set of "
+ "commands to be executed when "
+ "the breakpoint is hit.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData bp_id_arg;
+
+ // Define the first (and only) variant of this arg.
+ bp_id_arg.arg_type = eArgTypeBreakpointID;
+ bp_id_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(bp_id_arg);
- ~CommandObjectBreakpointCommandList() override = default;
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectBreakpointCommandList() override = default;
protected:
- bool
- DoExecute (Args& command,
- CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
-
- if (target == nullptr)
- {
- result.AppendError ("There is not a current executable; there are no breakpoints for which to list commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+
+ if (target == nullptr) {
+ result.AppendError("There is not a current executable; there are no "
+ "breakpoints for which to list commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- const BreakpointList &breakpoints = target->GetBreakpointList();
- size_t num_breakpoints = breakpoints.GetSize();
+ const BreakpointList &breakpoints = target->GetBreakpointList();
+ size_t num_breakpoints = breakpoints.GetSize();
- if (num_breakpoints == 0)
- {
- result.AppendError ("No breakpoints exist for which to list commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_breakpoints == 0) {
+ result.AppendError("No breakpoints exist for which to list commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- result.AppendError ("No breakpoint specified for which to list the commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (command.empty()) {
+ result.AppendError(
+ "No breakpoint specified for which to list the commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
-
- if (result.Succeeded())
- {
- const size_t count = valid_bp_ids.GetSize();
- for (size_t i = 0; i < count; ++i)
- {
- BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
- if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
- {
- Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
-
- if (bp)
- {
- const BreakpointOptions *bp_options = nullptr;
- if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
- {
- BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID()));
- if (bp_loc_sp)
- bp_options = bp_loc_sp->GetOptionsNoCreate();
- else
- {
- result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n",
- cur_bp_id.GetBreakpointID(),
- cur_bp_id.GetLocationID());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- bp_options = bp->GetOptions();
- }
-
- if (bp_options)
- {
- StreamString id_str;
- BreakpointID::GetCanonicalReference (&id_str,
- cur_bp_id.GetBreakpointID(),
- cur_bp_id.GetLocationID());
- const Baton *baton = bp_options->GetBaton();
- if (baton)
- {
- result.GetOutputStream().Printf ("Breakpoint %s:\n", id_str.GetData());
- result.GetOutputStream().IndentMore ();
- baton->GetDescription(&result.GetOutputStream(), eDescriptionLevelFull);
- result.GetOutputStream().IndentLess ();
- }
- else
- {
- result.AppendMessageWithFormat ("Breakpoint %s does not have an associated command.\n",
- id_str.GetData());
- }
- }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n", cur_bp_id.GetBreakpointID());
- result.SetStatus (eReturnStatusFailed);
- }
- }
+ BreakpointIDList valid_bp_ids;
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded()) {
+ const size_t count = valid_bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i);
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) {
+ Breakpoint *bp =
+ target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get();
+
+ if (bp) {
+ const BreakpointOptions *bp_options = nullptr;
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) {
+ BreakpointLocationSP bp_loc_sp(
+ bp->FindLocationByID(cur_bp_id.GetLocationID()));
+ if (bp_loc_sp)
+ bp_options = bp_loc_sp->GetOptionsNoCreate();
+ else {
+ result.AppendErrorWithFormat("Invalid breakpoint ID: %u.%u.\n",
+ cur_bp_id.GetBreakpointID(),
+ cur_bp_id.GetLocationID());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ bp_options = bp->GetOptions();
}
- }
- return result.Succeeded();
+ if (bp_options) {
+ StreamString id_str;
+ BreakpointID::GetCanonicalReference(&id_str,
+ cur_bp_id.GetBreakpointID(),
+ cur_bp_id.GetLocationID());
+ const Baton *baton = bp_options->GetBaton();
+ if (baton) {
+ result.GetOutputStream().Printf("Breakpoint %s:\n",
+ id_str.GetData());
+ result.GetOutputStream().IndentMore();
+ baton->GetDescription(&result.GetOutputStream(),
+ eDescriptionLevelFull);
+ result.GetOutputStream().IndentLess();
+ } else {
+ result.AppendMessageWithFormat(
+ "Breakpoint %s does not have an associated command.\n",
+ id_str.GetData());
+ }
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Invalid breakpoint ID: %u.\n",
+ cur_bp_id.GetBreakpointID());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+ }
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectBreakpointCommand
//-------------------------------------------------------------------------
-CommandObjectBreakpointCommand::CommandObjectBreakpointCommand(CommandInterpreter &interpreter)
+CommandObjectBreakpointCommand::CommandObjectBreakpointCommand(
+ CommandInterpreter &interpreter)
: CommandObjectMultiword(
- interpreter, "command",
- "Commands for adding, removing and listing LLDB commands executed when a breakpoint is hit.",
- "command <sub-command> [<sub-command-options>] <breakpoint-id>")
-{
- CommandObjectSP add_command_object (new CommandObjectBreakpointCommandAdd (interpreter));
- CommandObjectSP delete_command_object (new CommandObjectBreakpointCommandDelete (interpreter));
- CommandObjectSP list_command_object (new CommandObjectBreakpointCommandList (interpreter));
-
- add_command_object->SetCommandName ("breakpoint command add");
- delete_command_object->SetCommandName ("breakpoint command delete");
- list_command_object->SetCommandName ("breakpoint command list");
-
- LoadSubCommand ("add", add_command_object);
- LoadSubCommand ("delete", delete_command_object);
- LoadSubCommand ("list", list_command_object);
+ interpreter, "command", "Commands for adding, removing and listing "
+ "LLDB commands executed when a breakpoint is "
+ "hit.",
+ "command <sub-command> [<sub-command-options>] <breakpoint-id>") {
+ CommandObjectSP add_command_object(
+ new CommandObjectBreakpointCommandAdd(interpreter));
+ CommandObjectSP delete_command_object(
+ new CommandObjectBreakpointCommandDelete(interpreter));
+ CommandObjectSP list_command_object(
+ new CommandObjectBreakpointCommandList(interpreter));
+
+ add_command_object->SetCommandName("breakpoint command add");
+ delete_command_object->SetCommandName("breakpoint command delete");
+ list_command_object->SetCommandName("breakpoint command list");
+
+ LoadSubCommand("add", add_command_object);
+ LoadSubCommand("delete", delete_command_object);
+ LoadSubCommand("list", list_command_object);
}
CommandObjectBreakpointCommand::~CommandObjectBreakpointCommand() = default;
diff --git a/source/Commands/CommandObjectBreakpointCommand.h b/source/Commands/CommandObjectBreakpointCommand.h
index 94afc785c575..048cc5e07c1b 100644
--- a/source/Commands/CommandObjectBreakpointCommand.h
+++ b/source/Commands/CommandObjectBreakpointCommand.h
@@ -16,11 +16,11 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-types.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandObject.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
+#include "lldb/lldb-types.h"
namespace lldb_private {
@@ -28,12 +28,11 @@ namespace lldb_private {
// CommandObjectMultiwordBreakpoint
//-------------------------------------------------------------------------
-class CommandObjectBreakpointCommand : public CommandObjectMultiword
-{
+class CommandObjectBreakpointCommand : public CommandObjectMultiword {
public:
- CommandObjectBreakpointCommand (CommandInterpreter &interpreter);
+ CommandObjectBreakpointCommand(CommandInterpreter &interpreter);
- ~CommandObjectBreakpointCommand() override;
+ ~CommandObjectBreakpointCommand() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectBugreport.cpp b/source/Commands/CommandObjectBugreport.cpp
index db8c06c0e9e3..04050e3a6692 100644
--- a/source/Commands/CommandObjectBugreport.cpp
+++ b/source/Commands/CommandObjectBugreport.cpp
@@ -28,100 +28,87 @@ using namespace lldb_private;
// "bugreport unwind"
//-------------------------------------------------------------------------
-class CommandObjectBugreportUnwind : public CommandObjectParsed
-{
+class CommandObjectBugreportUnwind : public CommandObjectParsed {
public:
- CommandObjectBugreportUnwind(CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "bugreport unwind",
- "Create a bugreport for a bug in the stack unwinding code.",
- nullptr),
- m_option_group(interpreter),
- m_outfile_options()
- {
- m_option_group.Append (&m_outfile_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
- m_option_group.Finalize();
- }
+ CommandObjectBugreportUnwind(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "bugreport unwind",
+ "Create a bugreport for a bug in the stack unwinding code.",
+ nullptr),
+ m_option_group(), m_outfile_options() {
+ m_option_group.Append(&m_outfile_options, LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
+ m_option_group.Finalize();
+ }
- ~CommandObjectBugreportUnwind() override
- {
- }
+ ~CommandObjectBugreportUnwind() override {}
- Options *
- GetOptions() override
- {
- return &m_option_group;
- }
+ Options *GetOptions() override { return &m_option_group; }
protected:
- bool
- DoExecute(Args& command, CommandReturnObject &result) override
- {
- StringList commands;
- commands.AppendString("thread backtrace");
-
- Thread *thread = m_exe_ctx.GetThreadPtr();
- if (thread)
- {
- char command_buffer[256];
-
- uint32_t frame_count = thread->GetStackFrameCount();
- for (uint32_t i = 0; i < frame_count; ++i)
- {
- StackFrameSP frame = thread->GetStackFrameAtIndex(i);
- lldb::addr_t pc = frame->GetStackID().GetPC();
-
- snprintf(command_buffer, sizeof(command_buffer), "disassemble --bytes --address 0x%" PRIx64, pc);
- commands.AppendString(command_buffer);
-
- snprintf(command_buffer, sizeof(command_buffer), "image show-unwind --address 0x%" PRIx64, pc);
- commands.AppendString(command_buffer);
- }
- }
-
- const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue();
- if (outfile_spec)
- {
- char path[PATH_MAX];
- outfile_spec.GetPath (path, sizeof(path));
-
- uint32_t open_options = File::eOpenOptionWrite |
- File::eOpenOptionCanCreate |
- File::eOpenOptionAppend |
- File::eOpenOptionCloseOnExec;
-
- const bool append = m_outfile_options.GetAppend().GetCurrentValue();
- if (!append)
- open_options |= File::eOpenOptionTruncate;
-
- StreamFileSP outfile_stream = std::make_shared<StreamFile>();
- Error error = outfile_stream->GetFile().Open(path, open_options);
- if (error.Fail())
- {
- result.AppendErrorWithFormat("Failed to open file '%s' for %s: %s\n",
- path,
- append ? "append" : "write",
- error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- result.SetImmediateOutputStream(outfile_stream);
- }
-
- CommandInterpreterRunOptions options;
- options.SetStopOnError(false);
- options.SetEchoCommands(true);
- options.SetPrintResults(true);
- options.SetAddToHistory(false);
- m_interpreter.HandleCommands(commands, &m_exe_ctx, options, result);
-
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ StringList commands;
+ commands.AppendString("thread backtrace");
+
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ if (thread) {
+ char command_buffer[256];
+
+ uint32_t frame_count = thread->GetStackFrameCount();
+ for (uint32_t i = 0; i < frame_count; ++i) {
+ StackFrameSP frame = thread->GetStackFrameAtIndex(i);
+ lldb::addr_t pc = frame->GetStackID().GetPC();
+
+ snprintf(command_buffer, sizeof(command_buffer),
+ "disassemble --bytes --address 0x%" PRIx64, pc);
+ commands.AppendString(command_buffer);
+
+ snprintf(command_buffer, sizeof(command_buffer),
+ "image show-unwind --address 0x%" PRIx64, pc);
+ commands.AppendString(command_buffer);
+ }
+ }
+
+ const FileSpec &outfile_spec =
+ m_outfile_options.GetFile().GetCurrentValue();
+ if (outfile_spec) {
+ char path[PATH_MAX];
+ outfile_spec.GetPath(path, sizeof(path));
+
+ uint32_t open_options =
+ File::eOpenOptionWrite | File::eOpenOptionCanCreate |
+ File::eOpenOptionAppend | File::eOpenOptionCloseOnExec;
+
+ const bool append = m_outfile_options.GetAppend().GetCurrentValue();
+ if (!append)
+ open_options |= File::eOpenOptionTruncate;
+
+ StreamFileSP outfile_stream = std::make_shared<StreamFile>();
+ Error error = outfile_stream->GetFile().Open(path, open_options);
+ if (error.Fail()) {
+ result.AppendErrorWithFormat("Failed to open file '%s' for %s: %s\n",
+ path, append ? "append" : "write",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ result.SetImmediateOutputStream(outfile_stream);
}
+ CommandInterpreterRunOptions options;
+ options.SetStopOnError(false);
+ options.SetEchoCommands(true);
+ options.SetPrintResults(true);
+ options.SetAddToHistory(false);
+ m_interpreter.HandleCommands(commands, &m_exe_ctx, options, result);
+
+ return result.Succeeded();
+ }
+
private:
- OptionGroupOptions m_option_group;
- OptionGroupOutputFile m_outfile_options;
+ OptionGroupOptions m_option_group;
+ OptionGroupOutputFile m_outfile_options;
};
#pragma mark CommandObjectMultiwordBugreport
@@ -130,14 +117,15 @@ private:
// CommandObjectMultiwordBugreport
//-------------------------------------------------------------------------
-CommandObjectMultiwordBugreport::CommandObjectMultiwordBugreport(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "bugreport", "Commands for creating domain-specific bug reports.",
- "bugreport <subcommand> [<subcommand-options>]")
-{
+CommandObjectMultiwordBugreport::CommandObjectMultiwordBugreport(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "bugreport",
+ "Commands for creating domain-specific bug reports.",
+ "bugreport <subcommand> [<subcommand-options>]") {
- LoadSubCommand("unwind", CommandObjectSP(new CommandObjectBugreportUnwind(interpreter)));
+ LoadSubCommand(
+ "unwind", CommandObjectSP(new CommandObjectBugreportUnwind(interpreter)));
}
-CommandObjectMultiwordBugreport::~CommandObjectMultiwordBugreport ()
-{
-}
+CommandObjectMultiwordBugreport::~CommandObjectMultiwordBugreport() {}
diff --git a/source/Commands/CommandObjectBugreport.h b/source/Commands/CommandObjectBugreport.h
index 3adde51e0274..281ea2dd203e 100644
--- a/source/Commands/CommandObjectBugreport.h
+++ b/source/Commands/CommandObjectBugreport.h
@@ -22,12 +22,11 @@ namespace lldb_private {
// CommandObjectMultiwordBugreport
//-------------------------------------------------------------------------
-class CommandObjectMultiwordBugreport : public CommandObjectMultiword
-{
+class CommandObjectMultiwordBugreport : public CommandObjectMultiword {
public:
- CommandObjectMultiwordBugreport(CommandInterpreter &interpreter);
+ CommandObjectMultiwordBugreport(CommandInterpreter &interpreter);
- ~CommandObjectMultiwordBugreport() override;
+ ~CommandObjectMultiwordBugreport() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp
index dd2fd9a0efc8..aa07c104846f 100644
--- a/source/Commands/CommandObjectCommands.cpp
+++ b/source/Commands/CommandObjectCommands.cpp
@@ -1,4 +1,4 @@
-//===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
+//===-- CommandObjectCommands.cpp -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -36,386 +36,305 @@ using namespace lldb_private;
// CommandObjectCommandsSource
//-------------------------------------------------------------------------
-class CommandObjectCommandsHistory : public CommandObjectParsed
-{
+static OptionDefinition g_history_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "How many history commands to print." },
+ { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)." },
+ { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands." },
+ { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clears the current command history." },
+ // clang-format on
+};
+
+class CommandObjectCommandsHistory : public CommandObjectParsed {
public:
- CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "command history",
+ CommandObjectCommandsHistory(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "command history",
"Dump the history of commands in this session.",
nullptr),
- m_options (interpreter)
- {
- }
+ m_options() {}
- ~CommandObjectCommandsHistory() override = default;
+ ~CommandObjectCommandsHistory() override = default;
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ Options *GetOptions() override { return &m_options; }
protected:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_start_idx(0),
- m_stop_idx(0),
- m_count(0),
- m_clear(false)
- {
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_start_idx(0), m_stop_idx(0), m_count(0), m_clear(false) {
+ }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'c':
- error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
- break;
- case 's':
- if (option_arg && strcmp("end", option_arg) == 0)
- {
- m_start_idx.SetCurrentValue(UINT64_MAX);
- m_start_idx.SetOptionWasSet();
- }
- else
- error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
- break;
- case 'e':
- error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
- break;
- case 'C':
- m_clear.SetCurrentValue(true);
- m_clear.SetOptionWasSet();
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c':
+ error = m_count.SetValueFromString(option_arg, eVarSetOperationAssign);
+ break;
+ case 's':
+ if (option_arg == "end") {
+ m_start_idx.SetCurrentValue(UINT64_MAX);
+ m_start_idx.SetOptionWasSet();
+ } else
+ error = m_start_idx.SetValueFromString(option_arg,
+ eVarSetOperationAssign);
+ break;
+ case 'e':
+ error =
+ m_stop_idx.SetValueFromString(option_arg, eVarSetOperationAssign);
+ break;
+ case 'C':
+ m_clear.SetCurrentValue(true);
+ m_clear.SetOptionWasSet();
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
- void
- OptionParsingStarting () override
- {
- m_start_idx.Clear();
- m_stop_idx.Clear();
- m_count.Clear();
- m_clear.Clear();
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_start_idx.Clear();
+ m_stop_idx.Clear();
+ m_count.Clear();
+ m_clear.Clear();
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_history_options);
+ }
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- OptionValueUInt64 m_start_idx;
- OptionValueUInt64 m_stop_idx;
- OptionValueUInt64 m_count;
- OptionValueBoolean m_clear;
- };
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
- {
- m_interpreter.GetCommandHistory().Clear();
- result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
- {
- result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
- result.SetStatus(lldb::eReturnStatusFailed);
+ // Instance variables to hold the values for command options.
+
+ OptionValueUInt64 m_start_idx;
+ OptionValueUInt64 m_stop_idx;
+ OptionValueUInt64 m_count;
+ OptionValueBoolean m_clear;
+ };
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (m_options.m_clear.GetCurrentValue() &&
+ m_options.m_clear.OptionWasSet()) {
+ m_interpreter.GetCommandHistory().Clear();
+ result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
+ } else {
+ if (m_options.m_start_idx.OptionWasSet() &&
+ m_options.m_stop_idx.OptionWasSet() &&
+ m_options.m_count.OptionWasSet()) {
+ result.AppendError("--count, --start-index and --end-index cannot be "
+ "all specified in the same invocation");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ } else {
+ std::pair<bool, uint64_t> start_idx(
+ m_options.m_start_idx.OptionWasSet(),
+ m_options.m_start_idx.GetCurrentValue());
+ std::pair<bool, uint64_t> stop_idx(
+ m_options.m_stop_idx.OptionWasSet(),
+ m_options.m_stop_idx.GetCurrentValue());
+ std::pair<bool, uint64_t> count(m_options.m_count.OptionWasSet(),
+ m_options.m_count.GetCurrentValue());
+
+ const CommandHistory &history(m_interpreter.GetCommandHistory());
+
+ if (start_idx.first && start_idx.second == UINT64_MAX) {
+ if (count.first) {
+ start_idx.second = history.GetSize() - count.second;
+ stop_idx.second = history.GetSize() - 1;
+ } else if (stop_idx.first) {
+ start_idx.second = stop_idx.second;
+ stop_idx.second = history.GetSize() - 1;
+ } else {
+ start_idx.second = 0;
+ stop_idx.second = history.GetSize() - 1;
+ }
+ } else {
+ if (!start_idx.first && !stop_idx.first && !count.first) {
+ start_idx.second = 0;
+ stop_idx.second = history.GetSize() - 1;
+ } else if (start_idx.first) {
+ if (count.first) {
+ stop_idx.second = start_idx.second + count.second - 1;
+ } else if (!stop_idx.first) {
+ stop_idx.second = history.GetSize() - 1;
}
- else
- {
- std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
- std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
- std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
-
- const CommandHistory& history(m_interpreter.GetCommandHistory());
-
- if (start_idx.first && start_idx.second == UINT64_MAX)
- {
- if (count.first)
- {
- start_idx.second = history.GetSize() - count.second;
- stop_idx.second = history.GetSize() - 1;
- }
- else if (stop_idx.first)
- {
- start_idx.second = stop_idx.second;
- stop_idx.second = history.GetSize() - 1;
- }
- else
- {
- start_idx.second = 0;
- stop_idx.second = history.GetSize() - 1;
- }
- }
- else
- {
- if (!start_idx.first && !stop_idx.first && !count.first)
- {
- start_idx.second = 0;
- stop_idx.second = history.GetSize() - 1;
- }
- else if (start_idx.first)
- {
- if (count.first)
- {
- stop_idx.second = start_idx.second + count.second - 1;
- }
- else if (!stop_idx.first)
- {
- stop_idx.second = history.GetSize() - 1;
- }
- }
- else if (stop_idx.first)
- {
- if (count.first)
- {
- if (stop_idx.second >= count.second)
- start_idx.second = stop_idx.second - count.second + 1;
- else
- start_idx.second = 0;
- }
- }
- else /* if (count.first) */
- {
- start_idx.second = 0;
- stop_idx.second = count.second - 1;
- }
- }
- history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
+ } else if (stop_idx.first) {
+ if (count.first) {
+ if (stop_idx.second >= count.second)
+ start_idx.second = stop_idx.second - count.second + 1;
+ else
+ start_idx.second = 0;
}
- }
- return result.Succeeded();
-
+ } else /* if (count.first) */
+ {
+ start_idx.second = 0;
+ stop_idx.second = count.second - 1;
+ }
+ }
+ history.Dump(result.GetOutputStream(), start_idx.second,
+ stop_idx.second);
+ }
}
+ return result.Succeeded();
+ }
- CommandOptions m_options;
-};
-
-OptionDefinition
-CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "How many history commands to print."},
-{ LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."},
-{ LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."},
-{ LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clears the current command history."},
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectCommandsSource
//-------------------------------------------------------------------------
-class CommandObjectCommandsSource : public CommandObjectParsed
-{
+static OptionDefinition g_source_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on error." },
+ { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on continue." },
+ { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true don't echo commands while executing." },
+ // clang-format on
+};
+
+class CommandObjectCommandsSource : public CommandObjectParsed {
public:
- CommandObjectCommandsSource(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "command source", "Read and execute LLDB commands from the file <filename>.",
- nullptr),
- m_options(interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData file_arg;
-
- // Define the first (and only) variant of this arg.
- file_arg.arg_type = eArgTypeFilename;
- file_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (file_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectCommandsSource() override = default;
-
- const char*
- GetRepeatCommand (Args &current_command_args, uint32_t index) override
- {
- return "";
- }
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
- }
-
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ CommandObjectCommandsSource(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "command source",
+ "Read and execute LLDB commands from the file <filename>.",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData file_arg;
+
+ // Define the first (and only) variant of this arg.
+ file_arg.arg_type = eArgTypeFilename;
+ file_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(file_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectCommandsSource() override = default;
+
+ const char *GetRepeatCommand(Args &current_command_args,
+ uint32_t index) override {
+ return "";
+ }
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ auto completion_str = input[cursor_index].ref;
+ completion_str = completion_str.take_front(cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ completion_str, match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
+
+ Options *GetOptions() override { return &m_options; }
protected:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_stop_on_error (true),
- m_silent_run (false),
- m_stop_on_continue (true)
- {
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_stop_on_error(true), m_silent_run(false),
+ m_stop_on_continue(true) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'e':
+ error = m_stop_on_error.SetValueFromString(option_arg);
+ break;
+
+ case 'c':
+ error = m_stop_on_continue.SetValueFromString(option_arg);
+ break;
+
+ case 's':
+ error = m_silent_run.SetValueFromString(option_arg);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'e':
- error = m_stop_on_error.SetValueFromString(option_arg);
- break;
-
- case 'c':
- error = m_stop_on_continue.SetValueFromString(option_arg);
- break;
-
- case 's':
- error = m_silent_run.SetValueFromString(option_arg);
- break;
-
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_stop_on_error.Clear();
+ m_silent_run.Clear();
+ m_stop_on_continue.Clear();
+ }
- void
- OptionParsingStarting () override
- {
- m_stop_on_error.Clear();
- m_silent_run.Clear();
- m_stop_on_continue.Clear();
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_source_options);
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ // Instance variables to hold the values for command options.
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- OptionValueBoolean m_stop_on_error;
- OptionValueBoolean m_silent_run;
- OptionValueBoolean m_stop_on_continue;
- };
-
- bool
- DoExecute(Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 1)
- {
- const char *filename = command.GetArgumentAtIndex(0);
-
- FileSpec cmd_file (filename, true);
- ExecutionContext *exe_ctx = nullptr; // Just use the default context.
-
- // If any options were set, then use them
- if (m_options.m_stop_on_error.OptionWasSet() ||
- m_options.m_silent_run.OptionWasSet() ||
- m_options.m_stop_on_continue.OptionWasSet())
- {
- // Use user set settings
- CommandInterpreterRunOptions options;
- options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
- options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
- options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
- options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
-
- m_interpreter.HandleCommandsFromFile (cmd_file,
- exe_ctx,
- options,
- result);
- }
- else
- {
- // No options were set, inherit any settings from nested "command source" commands,
- // or set to sane default settings...
- CommandInterpreterRunOptions options;
- m_interpreter.HandleCommandsFromFile (cmd_file,
- exe_ctx,
- options,
- result);
- }
- }
- else
- {
- result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ OptionValueBoolean m_stop_on_error;
+ OptionValueBoolean m_silent_run;
+ OptionValueBoolean m_stop_on_continue;
+ };
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (command.GetArgumentCount() != 1) {
+ result.AppendErrorWithFormat(
+ "'%s' takes exactly one executable filename argument.\n",
+ GetCommandName().str().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- CommandOptions m_options;
-};
+ FileSpec cmd_file(command[0].ref, true);
+ ExecutionContext *exe_ctx = nullptr; // Just use the default context.
+
+ // If any options were set, then use them
+ if (m_options.m_stop_on_error.OptionWasSet() ||
+ m_options.m_silent_run.OptionWasSet() ||
+ m_options.m_stop_on_continue.OptionWasSet()) {
+ // Use user set settings
+ CommandInterpreterRunOptions options;
+ options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
+ options.SetStopOnError(m_options.m_stop_on_error.GetCurrentValue());
+ options.SetEchoCommands(!m_options.m_silent_run.GetCurrentValue());
+ options.SetPrintResults(!m_options.m_silent_run.GetCurrentValue());
+
+ m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result);
+ } else {
+ // No options were set, inherit any settings from nested "command
+ // source" commands,
+ // or set to sane default settings...
+ CommandInterpreterRunOptions options;
+ m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result);
+ }
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectCommandsSource::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on error."},
-{ LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
-{ LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
#pragma mark CommandObjectCommandsAlias
@@ -423,102 +342,85 @@ CommandObjectCommandsSource::CommandOptions::g_option_table[] =
// CommandObjectCommandsAlias
//-------------------------------------------------------------------------
-static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
- "You must define a Python function with this signature:\n"
- "def my_command_impl(debugger, args, result, internal_dict):\n";
+static OptionDefinition g_alias_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Help text for this command" },
+ { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Long help text for this command" },
+ // clang-format on
+};
+
+static const char *g_python_command_instructions =
+ "Enter your Python command(s). Type 'DONE' to end.\n"
+ "You must define a Python function with this signature:\n"
+ "def my_command_impl(debugger, args, result, internal_dict):\n";
-class CommandObjectCommandsAlias : public CommandObjectRaw
-{
+class CommandObjectCommandsAlias : public CommandObjectRaw {
protected:
- class CommandOptions : public OptionGroup
- {
- public:
- CommandOptions () :
- OptionGroup(),
- m_help(),
- m_long_help()
- {}
-
- ~CommandOptions() override = default;
-
- uint32_t
- GetNumDefinitions () override
- {
- return 3;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- Error
- SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_value) override
- {
- Error error;
-
- const int short_option = g_option_table[option_idx].short_option;
-
- switch (short_option)
- {
- case 'h':
- m_help.SetCurrentValue(option_value);
- m_help.SetOptionWasSet();
- break;
-
- case 'H':
- m_long_help.SetCurrentValue(option_value);
- m_long_help.SetOptionWasSet();
- break;
-
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting (CommandInterpreter &interpreter) override
- {
- m_help.Clear();
- m_long_help.Clear();
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
- OptionValueString m_help;
- OptionValueString m_long_help;
- };
-
- OptionGroupOptions m_option_group;
- CommandOptions m_command_options;
-
+ class CommandOptions : public OptionGroup {
+ public:
+ CommandOptions() : OptionGroup(), m_help(), m_long_help() {}
+
+ ~CommandOptions() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_alias_options);
+ }
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override {
+ Error error;
+
+ const int short_option = GetDefinitions()[option_idx].short_option;
+ std::string option_str(option_value);
+
+ switch (short_option) {
+ case 'h':
+ m_help.SetCurrentValue(option_str);
+ m_help.SetOptionWasSet();
+ break;
+
+ case 'H':
+ m_long_help.SetCurrentValue(option_str);
+ m_long_help.SetOptionWasSet();
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_help.Clear();
+ m_long_help.Clear();
+ }
+
+ OptionValueString m_help;
+ OptionValueString m_long_help;
+ };
+
+ OptionGroupOptions m_option_group;
+ CommandOptions m_command_options;
+
public:
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
-
- CommandObjectCommandsAlias(CommandInterpreter &interpreter)
- : CommandObjectRaw(interpreter, "command alias", "Define a custom command in terms of an existing command.",
- nullptr),
- m_option_group(interpreter),
- m_command_options()
- {
- m_option_group.Append(&m_command_options);
- m_option_group.Finalize();
-
- SetHelpLong(
-"'alias' allows the user to create a short-cut or abbreviation for long \
+ Options *GetOptions() override { return &m_option_group; }
+
+ CommandObjectCommandsAlias(CommandInterpreter &interpreter)
+ : CommandObjectRaw(
+ interpreter, "command alias",
+ "Define a custom command in terms of an existing command."),
+ m_option_group(), m_command_options() {
+ m_option_group.Append(&m_command_options);
+ m_option_group.Finalize();
+
+ SetHelpLong(
+ "'alias' allows the user to create a short-cut or abbreviation for long \
commands, multi-word commands, and commands that take particular options. \
-Below are some simple examples of how one might use the 'alias' command:" R"(
+Below are some simple examples of how one might use the 'alias' command:"
+ R"(
(lldb) command alias sc script
@@ -526,22 +428,27 @@ Below are some simple examples of how one might use the 'alias' command:" R"(
(lldb) command alias bp breakpoint
-)" " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \
+)"
+ " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \
breakpoint commands are two-word commands, the user would still need to \
-enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"(
+enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'."
+ R"(
(lldb) command alias bpl breakpoint list
Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
-)" "An alias can include some options for the command, with the values either \
+)"
+ "An alias can include some options for the command, with the values either \
filled in at the time the alias is created, or specified as positional \
arguments, to be filled in when the alias is invoked. The following example \
-shows how to create aliases with options:" R"(
+shows how to create aliases with options:"
+ R"(
(lldb) command alias bfl breakpoint set -f %1 -l %2
-)" " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
+)"
+ " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
options already part of the alias. So if the user wants to set a breakpoint \
by file and line without explicitly having to use the -f and -l options, the \
user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \
@@ -551,18 +458,23 @@ occupies when the alias is used. All the occurrences of '%1' in the alias \
will be replaced with the first argument, all the occurrences of '%2' in the \
alias will be replaced with the second argument, and so on. This also allows \
actual arguments to be used multiple times within an alias (see 'process \
-launch' example below)." R"(
+launch' example below)."
+ R"(
-)" "Note: the positional arguments must substitute as whole words in the resultant \
+)"
+ "Note: the positional arguments must substitute as whole words in the resultant \
command, so you can't at present do something like this to append the file extension \
-\".cpp\":" R"(
+\".cpp\":"
+ R"(
(lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
-)" "For more complex aliasing, use the \"command regex\" command instead. In the \
+)"
+ "For more complex aliasing, use the \"command regex\" command instead. In the \
'bfl' case above, the actual file value will be filled in with the first argument \
following 'bfl' and the actual line number value will be filled in with the second \
-argument. The user would use this alias as follows:" R"(
+argument. The user would use this alias as follows:"
+ R"(
(lldb) command alias bfl breakpoint set -f %1 -l %2
(lldb) bfl my-file.c 137
@@ -576,340 +488,310 @@ Another example:
Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
-)" "If the user always wanted to pass the same value to a particular option, the \
+)"
+ "If the user always wanted to pass the same value to a particular option, the \
alias could be defined with that value directly in the alias as a constant, \
-rather than using a positional placeholder:" R"(
+rather than using a positional placeholder:"
+ R"(
(lldb) command alias bl3 breakpoint set -f %1 -l 3
- Always sets a breakpoint on line 3 of whatever file is indicated.)"
- );
-
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentEntry arg3;
- CommandArgumentData alias_arg;
- CommandArgumentData cmd_arg;
- CommandArgumentData options_arg;
-
- // Define the first (and only) variant of this arg.
- alias_arg.arg_type = eArgTypeAliasName;
- alias_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (alias_arg);
-
- // Define the first (and only) variant of this arg.
- cmd_arg.arg_type = eArgTypeCommandName;
- cmd_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg2.push_back (cmd_arg);
-
- // Define the first (and only) variant of this arg.
- options_arg.arg_type = eArgTypeAliasOptions;
- options_arg.arg_repetition = eArgRepeatOptional;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg3.push_back (options_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
- m_arguments.push_back (arg3);
- }
-
- ~CommandObjectCommandsAlias() override = default;
+ Always sets a breakpoint on line 3 of whatever file is indicated.)");
+
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentEntry arg3;
+ CommandArgumentData alias_arg;
+ CommandArgumentData cmd_arg;
+ CommandArgumentData options_arg;
+
+ // Define the first (and only) variant of this arg.
+ alias_arg.arg_type = eArgTypeAliasName;
+ alias_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(alias_arg);
+
+ // Define the first (and only) variant of this arg.
+ cmd_arg.arg_type = eArgTypeCommandName;
+ cmd_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(cmd_arg);
+
+ // Define the first (and only) variant of this arg.
+ options_arg.arg_type = eArgTypeAliasOptions;
+ options_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg3.push_back(options_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ m_arguments.push_back(arg3);
+ }
+
+ ~CommandObjectCommandsAlias() override = default;
protected:
- bool
- DoExecute (const char *raw_command_line, CommandReturnObject &result) override
- {
- if (!raw_command_line || !raw_command_line[0])
- {
- result.AppendError ("'command alias' requires at least two arguments");
- return false;
- }
-
- m_option_group.NotifyOptionParsingStarting();
-
- const char * remainder = nullptr;
-
- if (raw_command_line[0] == '-')
- {
- // We have some options and these options MUST end with --.
- const char *end_options = nullptr;
- const char *s = raw_command_line;
- while (s && s[0])
- {
- end_options = ::strstr (s, "--");
- if (end_options)
- {
- end_options += 2; // Get past the "--"
- if (::isspace (end_options[0]))
- {
- remainder = end_options;
- while (::isspace (*remainder))
- ++remainder;
- break;
- }
- }
- s = end_options;
- }
-
- if (end_options)
- {
- Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
- if (!ParseOptions (args, result))
- return false;
-
- Error error (m_option_group.NotifyOptionParsingFinished());
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
- if (nullptr == remainder)
- remainder = raw_command_line;
-
- std::string raw_command_string (remainder);
- Args args (raw_command_string.c_str());
-
- size_t argc = args.GetArgumentCount();
-
- if (argc < 2)
- {
- result.AppendError ("'command alias' requires at least two arguments");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- // Get the alias command.
-
- const std::string alias_command = args.GetArgumentAtIndex (0);
- if (alias_command.size() > 1 &&
- alias_command[0] == '-')
- {
- result.AppendError("aliases starting with a dash are not supported");
- if (alias_command == "--help" || alias_command == "--long-help")
- {
- result.AppendWarning("if trying to pass options to 'command alias' add a -- at the end of the options");
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which
- // does the stripping itself.
- size_t pos = raw_command_string.find (alias_command);
- if (pos == 0)
- {
- raw_command_string = raw_command_string.substr (alias_command.size());
- pos = raw_command_string.find_first_not_of (' ');
- if ((pos != std::string::npos) && (pos > 0))
- raw_command_string = raw_command_string.substr (pos);
- }
- else
- {
- result.AppendError ("Error parsing command string. No alias created.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
-
- // Verify that the command is alias-able.
- if (m_interpreter.CommandExists (alias_command.c_str()))
- {
- result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
- alias_command.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
- // raw_command_string is returned with the name of the command object stripped off the front.
- std::string original_raw_command_string(raw_command_string);
- CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
-
- if (!cmd_obj)
- {
- result.AppendErrorWithFormat ("invalid command given to 'command alias'. '%s' does not begin with a valid command."
- " No alias created.", original_raw_command_string.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else if (!cmd_obj->WantsRawCommandString ())
- {
- // Note that args was initialized with the original command, and has not been updated to this point.
- // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
- return HandleAliasingNormalCommand (args, result);
- }
- else
- {
- return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
- }
- return result.Succeeded();
- }
-
- bool
- HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
- {
- // Verify & handle any options/arguments passed to the alias command
-
- OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
-
- if (CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false))
- {
- if (m_interpreter.AliasExists (alias_command.c_str())
- || m_interpreter.UserCommandExists (alias_command.c_str()))
- {
- result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
- alias_command.c_str());
- }
- if (CommandAlias *alias = m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp, raw_command_string.c_str()))
- {
- if (m_command_options.m_help.OptionWasSet())
- alias->SetHelp(m_command_options.m_help.GetCurrentValue());
- if (m_command_options.m_long_help.OptionWasSet())
- alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError ("Unable to create requested alias.\n");
- result.SetStatus (eReturnStatusFailed);
- }
+ bool DoExecute(const char *raw_command_line,
+ CommandReturnObject &result) override {
+ if (!raw_command_line || !raw_command_line[0]) {
+ result.AppendError("'command alias' requires at least two arguments");
+ return false;
+ }
- }
- else
- {
- result.AppendError ("Unable to create requested alias.\n");
- result.SetStatus (eReturnStatusFailed);
- }
+ ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext();
+ m_option_group.NotifyOptionParsingStarting(&exe_ctx);
+
+ const char *remainder = nullptr;
+
+ if (raw_command_line[0] == '-') {
+ // We have some options and these options MUST end with --.
+ const char *end_options = nullptr;
+ const char *s = raw_command_line;
+ while (s && s[0]) {
+ end_options = ::strstr(s, "--");
+ if (end_options) {
+ end_options += 2; // Get past the "--"
+ if (::isspace(end_options[0])) {
+ remainder = end_options;
+ while (::isspace(*remainder))
+ ++remainder;
+ break;
+ }
+ }
+ s = end_options;
+ }
+
+ if (end_options) {
+ Args args(
+ llvm::StringRef(raw_command_line, end_options - raw_command_line));
+ if (!ParseOptions(args, result))
+ return false;
+
+ Error error(m_option_group.NotifyOptionParsingFinished(&exe_ctx));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ }
+ if (nullptr == remainder)
+ remainder = raw_command_line;
- return result.Succeeded ();
+ llvm::StringRef raw_command_string(remainder);
+ Args args(raw_command_string);
+
+ if (args.GetArgumentCount() < 2) {
+ result.AppendError("'command alias' requires at least two arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- bool
- HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
- {
- size_t argc = args.GetArgumentCount();
- if (argc < 2)
- {
- result.AppendError ("'command alias' requires at least two arguments");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Get the alias command.
+
+ auto alias_command = args[0].ref;
+ if (alias_command.startswith("-")) {
+ result.AppendError("aliases starting with a dash are not supported");
+ if (alias_command == "--help" || alias_command == "--long-help") {
+ result.AppendWarning("if trying to pass options to 'command alias' add "
+ "a -- at the end of the options");
+ }
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- const std::string alias_command = args.GetArgumentAtIndex(0);
- const std::string actual_command = args.GetArgumentAtIndex(1);
+ // Strip the new alias name off 'raw_command_string' (leave it on args,
+ // which gets passed to 'Execute', which
+ // does the stripping itself.
+ size_t pos = raw_command_string.find(alias_command);
+ if (pos == 0) {
+ raw_command_string = raw_command_string.substr(alias_command.size());
+ pos = raw_command_string.find_first_not_of(' ');
+ if ((pos != std::string::npos) && (pos > 0))
+ raw_command_string = raw_command_string.substr(pos);
+ } else {
+ result.AppendError("Error parsing command string. No alias created.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- args.Shift(); // Shift the alias command word off the argument vector.
- args.Shift(); // Shift the old command word off the argument vector.
+ // Verify that the command is alias-able.
+ if (m_interpreter.CommandExists(alias_command)) {
+ result.AppendErrorWithFormat(
+ "'%s' is a permanent debugger command and cannot be redefined.\n",
+ args[0].c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Get CommandObject that is being aliased. The command name is read from
+ // the front of raw_command_string. raw_command_string is returned with the
+ // name of the command object stripped off the front.
+ llvm::StringRef original_raw_command_string = raw_command_string;
+ CommandObject *cmd_obj =
+ m_interpreter.GetCommandObjectForCommand(raw_command_string);
+
+ if (!cmd_obj) {
+ result.AppendErrorWithFormat("invalid command given to 'command alias'. "
+ "'%s' does not begin with a valid command."
+ " No alias created.",
+ original_raw_command_string.str().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (!cmd_obj->WantsRawCommandString()) {
+ // Note that args was initialized with the original command, and has not
+ // been updated to this point.
+ // Therefore can we pass it to the version of Execute that does not
+ // need/expect raw input in the alias.
+ return HandleAliasingNormalCommand(args, result);
+ } else {
+ return HandleAliasingRawCommand(alias_command, raw_command_string,
+ *cmd_obj, result);
+ }
+ return result.Succeeded();
+ }
+
+ bool HandleAliasingRawCommand(llvm::StringRef alias_command,
+ llvm::StringRef raw_command_string,
+ CommandObject &cmd_obj,
+ CommandReturnObject &result) {
+ // Verify & handle any options/arguments passed to the alias command
+
+ OptionArgVectorSP option_arg_vector_sp =
+ OptionArgVectorSP(new OptionArgVector);
+
+ if (CommandObjectSP cmd_obj_sp =
+ m_interpreter.GetCommandSPExact(cmd_obj.GetCommandName(), false)) {
+ if (m_interpreter.AliasExists(alias_command) ||
+ m_interpreter.UserCommandExists(alias_command)) {
+ result.AppendWarningWithFormat(
+ "Overwriting existing definition for '%s'.\n",
+ alias_command.str().c_str());
+ }
+ if (CommandAlias *alias = m_interpreter.AddAlias(
+ alias_command, cmd_obj_sp, raw_command_string)) {
+ if (m_command_options.m_help.OptionWasSet())
+ alias->SetHelp(m_command_options.m_help.GetCurrentValue());
+ if (m_command_options.m_long_help.OptionWasSet())
+ alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("Unable to create requested alias.\n");
+ result.SetStatus(eReturnStatusFailed);
+ }
+
+ } else {
+ result.AppendError("Unable to create requested alias.\n");
+ result.SetStatus(eReturnStatusFailed);
+ }
- // Verify that the command is alias'able, and get the appropriate command object.
+ return result.Succeeded();
+ }
- if (m_interpreter.CommandExists (alias_command.c_str()))
- {
- result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
- alias_command.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
- CommandObjectSP subcommand_obj_sp;
- bool use_subcommand = false;
- if (command_obj_sp)
- {
- CommandObject *cmd_obj = command_obj_sp.get();
- CommandObject *sub_cmd_obj = nullptr;
- OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
-
- while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
- {
- if (argc >= 3)
- {
- const std::string sub_command = args.GetArgumentAtIndex(0);
- assert (sub_command.length() != 0);
- subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
- if (subcommand_obj_sp)
- {
- sub_cmd_obj = subcommand_obj_sp.get();
- use_subcommand = true;
- args.Shift(); // Shift the sub_command word off the argument vector.
- cmd_obj = sub_cmd_obj;
- }
- else
- {
- result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. "
- "Unable to create alias.\n",
- sub_command.c_str(), actual_command.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
-
- // Verify & handle any options/arguments passed to the alias command
-
- std::string args_string;
-
- if (args.GetArgumentCount () > 0)
- {
- CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
- if (use_subcommand)
- tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
-
- args.GetCommandString (args_string);
- }
-
- if (m_interpreter.AliasExists (alias_command.c_str())
- || m_interpreter.UserCommandExists (alias_command.c_str()))
- {
- result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
- alias_command.c_str());
- }
-
- if (CommandAlias *alias = m_interpreter.AddAlias(alias_command.c_str(),
- use_subcommand ? subcommand_obj_sp : command_obj_sp,
- args_string.c_str()))
- {
- if (m_command_options.m_help.OptionWasSet())
- alias->SetHelp(m_command_options.m_help.GetCurrentValue());
- if (m_command_options.m_long_help.OptionWasSet())
- alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError ("Unable to create requested alias.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
+ bool HandleAliasingNormalCommand(Args &args, CommandReturnObject &result) {
+ size_t argc = args.GetArgumentCount();
- return result.Succeeded();
+ if (argc < 2) {
+ result.AppendError("'command alias' requires at least two arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-};
-OptionDefinition
-CommandObjectCommandsAlias::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Help text for this command"},
- { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Long help text for this command"},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ // Save these in std::strings since we're going to shift them off.
+ const std::string alias_command(args[0].ref);
+ const std::string actual_command(args[1].ref);
+
+ args.Shift(); // Shift the alias command word off the argument vector.
+ args.Shift(); // Shift the old command word off the argument vector.
+
+ // Verify that the command is alias'able, and get the appropriate command
+ // object.
+
+ if (m_interpreter.CommandExists(alias_command)) {
+ result.AppendErrorWithFormat(
+ "'%s' is a permanent debugger command and cannot be redefined.\n",
+ alias_command.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ CommandObjectSP command_obj_sp(
+ m_interpreter.GetCommandSPExact(actual_command, true));
+ CommandObjectSP subcommand_obj_sp;
+ bool use_subcommand = false;
+ if (!command_obj_sp) {
+ result.AppendErrorWithFormat("'%s' is not an existing command.\n",
+ actual_command.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ CommandObject *cmd_obj = command_obj_sp.get();
+ CommandObject *sub_cmd_obj = nullptr;
+ OptionArgVectorSP option_arg_vector_sp =
+ OptionArgVectorSP(new OptionArgVector);
+
+ while (cmd_obj->IsMultiwordObject() && !args.empty()) {
+ auto sub_command = args[0].ref;
+ assert(!sub_command.empty());
+ subcommand_obj_sp = cmd_obj->GetSubcommandSP(sub_command);
+ if (!subcommand_obj_sp) {
+ result.AppendErrorWithFormat(
+ "'%s' is not a valid sub-command of '%s'. "
+ "Unable to create alias.\n",
+ args[0].c_str(), actual_command.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ sub_cmd_obj = subcommand_obj_sp.get();
+ use_subcommand = true;
+ args.Shift(); // Shift the sub_command word off the argument vector.
+ cmd_obj = sub_cmd_obj;
+ }
+
+ // Verify & handle any options/arguments passed to the alias command
+
+ std::string args_string;
+
+ if (!args.empty()) {
+ CommandObjectSP tmp_sp =
+ m_interpreter.GetCommandSPExact(cmd_obj->GetCommandName(), false);
+ if (use_subcommand)
+ tmp_sp = m_interpreter.GetCommandSPExact(sub_cmd_obj->GetCommandName(),
+ false);
+
+ args.GetCommandString(args_string);
+ }
+
+ if (m_interpreter.AliasExists(alias_command) ||
+ m_interpreter.UserCommandExists(alias_command)) {
+ result.AppendWarningWithFormat(
+ "Overwriting existing definition for '%s'.\n", alias_command.c_str());
+ }
+
+ if (CommandAlias *alias = m_interpreter.AddAlias(
+ alias_command, use_subcommand ? subcommand_obj_sp : command_obj_sp,
+ args_string)) {
+ if (m_command_options.m_help.OptionWasSet())
+ alias->SetHelp(m_command_options.m_help.GetCurrentValue());
+ if (m_command_options.m_long_help.OptionWasSet())
+ alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("Unable to create requested alias.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectCommandsUnalias
@@ -917,87 +799,82 @@ CommandObjectCommandsAlias::CommandOptions::g_option_table[] =
// CommandObjectCommandsUnalias
//-------------------------------------------------------------------------
-class CommandObjectCommandsUnalias : public CommandObjectParsed
-{
+class CommandObjectCommandsUnalias : public CommandObjectParsed {
public:
- CommandObjectCommandsUnalias(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "command unalias",
- "Delete one or more custom commands defined by 'command alias'.", nullptr)
- {
- CommandArgumentEntry arg;
- CommandArgumentData alias_arg;
-
- // Define the first (and only) variant of this arg.
- alias_arg.arg_type = eArgTypeAliasName;
- alias_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (alias_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectCommandsUnalias() override = default;
+ CommandObjectCommandsUnalias(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "command unalias",
+ "Delete one or more custom commands defined by 'command alias'.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData alias_arg;
+
+ // Define the first (and only) variant of this arg.
+ alias_arg.arg_type = eArgTypeAliasName;
+ alias_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(alias_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectCommandsUnalias() override = default;
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- CommandObject::CommandMap::iterator pos;
- CommandObject *cmd_obj;
-
- if (args.GetArgumentCount() != 0)
- {
- const char *command_name = args.GetArgumentAtIndex(0);
- cmd_obj = m_interpreter.GetCommandObject(command_name);
- if (cmd_obj)
- {
- if (m_interpreter.CommandExists (command_name))
- {
- if (cmd_obj->IsRemovable())
- {
- result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
- command_name);
- }
- else
- {
- result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
- command_name);
- }
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- if (!m_interpreter.RemoveAlias(command_name))
- {
- if (m_interpreter.AliasExists (command_name))
- result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
- command_name);
- else
- result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
- result.SetStatus (eReturnStatusFailed);
- }
- else
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
- "current list of commands.\n",
- command_name);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("must call 'unalias' with a valid alias");
- result.SetStatus (eReturnStatusFailed);
- }
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ CommandObject::CommandMap::iterator pos;
+ CommandObject *cmd_obj;
+
+ if (args.empty()) {
+ result.AppendError("must call 'unalias' with a valid alias");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ auto command_name = args[0].ref;
+ cmd_obj = m_interpreter.GetCommandObject(command_name);
+ if (!cmd_obj) {
+ result.AppendErrorWithFormat(
+ "'%s' is not a known command.\nTry 'help' to see a "
+ "current list of commands.\n",
+ args[0].c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_interpreter.CommandExists(command_name)) {
+ if (cmd_obj->IsRemovable()) {
+ result.AppendErrorWithFormat(
+ "'%s' is not an alias, it is a debugger command which can be "
+ "removed using the 'command delete' command.\n",
+ args[0].c_str());
+ } else {
+ result.AppendErrorWithFormat(
+ "'%s' is a permanent debugger command and cannot be removed.\n",
+ args[0].c_str());
+ }
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- return result.Succeeded();
+ if (!m_interpreter.RemoveAlias(command_name)) {
+ if (m_interpreter.AliasExists(command_name))
+ result.AppendErrorWithFormat(
+ "Error occurred while attempting to unalias '%s'.\n",
+ args[0].c_str());
+ else
+ result.AppendErrorWithFormat("'%s' is not an existing alias.\n",
+ args[0].c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectCommandsDelete
@@ -1005,1249 +882,1016 @@ protected:
// CommandObjectCommandsDelete
//-------------------------------------------------------------------------
-class CommandObjectCommandsDelete : public CommandObjectParsed
-{
+class CommandObjectCommandsDelete : public CommandObjectParsed {
public:
- CommandObjectCommandsDelete(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "command delete",
- "Delete one or more custom commands defined by 'command regex'.", nullptr)
- {
- CommandArgumentEntry arg;
- CommandArgumentData alias_arg;
+ CommandObjectCommandsDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "command delete",
+ "Delete one or more custom commands defined by 'command regex'.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData alias_arg;
- // Define the first (and only) variant of this arg.
- alias_arg.arg_type = eArgTypeCommandName;
- alias_arg.arg_repetition = eArgRepeatPlain;
+ // Define the first (and only) variant of this arg.
+ alias_arg.arg_type = eArgTypeCommandName;
+ alias_arg.arg_repetition = eArgRepeatPlain;
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (alias_arg);
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(alias_arg);
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
- ~CommandObjectCommandsDelete() override = default;
+ ~CommandObjectCommandsDelete() override = default;
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- CommandObject::CommandMap::iterator pos;
-
- if (args.GetArgumentCount() != 0)
- {
- const char *command_name = args.GetArgumentAtIndex(0);
- if (m_interpreter.CommandExists (command_name))
- {
- if (m_interpreter.RemoveCommand (command_name))
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
- command_name);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- StreamString error_msg_stream;
- const bool generate_apropos = true;
- const bool generate_type_lookup = false;
- CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
- command_name,
- nullptr,
- nullptr,
- generate_apropos,
- generate_type_lookup);
- result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat(
- "must call '%s' with one or more valid user defined regular expression command names",
- GetCommandName());
- result.SetStatus (eReturnStatusFailed);
- }
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ CommandObject::CommandMap::iterator pos;
+
+ if (args.empty()) {
+ result.AppendErrorWithFormat("must call '%s' with one or more valid user "
+ "defined regular expression command names",
+ GetCommandName().str().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ }
- return result.Succeeded();
+ auto command_name = args[0].ref;
+ if (!m_interpreter.CommandExists(command_name)) {
+ StreamString error_msg_stream;
+ const bool generate_apropos = true;
+ const bool generate_type_lookup = false;
+ CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(
+ &error_msg_stream, command_name, llvm::StringRef(), llvm::StringRef(),
+ generate_apropos, generate_type_lookup);
+ result.AppendError(error_msg_stream.GetString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ if (!m_interpreter.RemoveCommand(command_name)) {
+ result.AppendErrorWithFormat(
+ "'%s' is a permanent debugger command and cannot be removed.\n",
+ args[0].c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
+ }
};
//-------------------------------------------------------------------------
// CommandObjectCommandsAddRegex
//-------------------------------------------------------------------------
+
+static OptionDefinition g_regex_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command." },
+ { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax." },
+ // clang-format on
+};
+
#pragma mark CommandObjectCommandsAddRegex
-class CommandObjectCommandsAddRegex :
- public CommandObjectParsed,
- public IOHandlerDelegateMultiline
-{
+class CommandObjectCommandsAddRegex : public CommandObjectParsed,
+ public IOHandlerDelegateMultiline {
public:
- CommandObjectCommandsAddRegex(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "command regex",
- "Define a custom command in terms of existing commands by matching regular expressions.",
- "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
- IOHandlerDelegateMultiline("", IOHandlerDelegate::Completion::LLDBCommand),
- m_options(interpreter)
- {
- SetHelpLong(R"(
-)" "This command allows the user to create powerful regular expression commands \
+ CommandObjectCommandsAddRegex(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "command regex", "Define a custom command in terms of "
+ "existing commands by matching "
+ "regular expressions.",
+ "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
+ IOHandlerDelegateMultiline("",
+ IOHandlerDelegate::Completion::LLDBCommand),
+ m_options() {
+ SetHelpLong(
+ R"(
+)"
+ "This command allows the user to create powerful regular expression commands \
with substitutions. The regular expressions and substitutions are specified \
-using the regular expression substitution format of:" R"(
+using the regular expression substitution format of:"
+ R"(
s/<regex>/<subst>/
-)" "<regex> is a regular expression that can use parenthesis to capture regular \
+)"
+ "<regex> is a regular expression that can use parenthesis to capture regular \
expression input and substitute the captured matches in the output using %1 \
-for the first match, %2 for the second, and so on." R"(
+for the first match, %2 for the second, and so on."
+ R"(
-)" "The regular expressions can all be specified on the command line if more than \
+)"
+ "The regular expressions can all be specified on the command line if more than \
one argument is provided. If just the command name is provided on the command \
line, then the regular expressions and substitutions can be entered on separate \
-lines, followed by an empty line to terminate the command definition." R"(
+lines, followed by an empty line to terminate the command definition."
+ R"(
EXAMPLES
-)" "The following example will define a regular expression command named 'f' that \
+)"
+ "The following example will define a regular expression command named 'f' that \
will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
-a number follows 'f':" R"(
+a number follows 'f':"
+ R"(
- (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
- );
- }
+ (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')");
+ }
- ~CommandObjectCommandsAddRegex() override = default;
+ ~CommandObjectCommandsAddRegex() override = default;
protected:
- void
- IOHandlerActivated (IOHandler &io_handler) override
- {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- if (output_sp)
- {
- output_sp->PutCString("Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\nTerminate the substitution list with an empty line.\n");
- output_sp->Flush();
- }
+ void IOHandlerActivated(IOHandler &io_handler) override {
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp) {
+ output_sp->PutCString("Enter one of more sed substitution commands in "
+ "the form: 's/<regex>/<subst>/'.\nTerminate the "
+ "substitution list with an empty line.\n");
+ output_sp->Flush();
}
-
- void
- IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
- {
- io_handler.SetIsDone(true);
- if (m_regex_cmd_ap)
- {
- StringList lines;
- if (lines.SplitIntoLines (data))
- {
- const size_t num_lines = lines.GetSize();
- bool check_only = false;
- for (size_t i=0; i<num_lines; ++i)
- {
- llvm::StringRef bytes_strref (lines[i]);
- Error error = AppendRegexSubstitution (bytes_strref, check_only);
- if (error.Fail())
- {
- if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
- {
- StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
- out_stream->Printf("error: %s\n", error.AsCString());
- }
- }
- }
- }
- if (m_regex_cmd_ap->HasRegexEntries())
- {
- CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
- m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
+ }
+
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) override {
+ io_handler.SetIsDone(true);
+ if (m_regex_cmd_ap) {
+ StringList lines;
+ if (lines.SplitIntoLines(data)) {
+ const size_t num_lines = lines.GetSize();
+ bool check_only = false;
+ for (size_t i = 0; i < num_lines; ++i) {
+ llvm::StringRef bytes_strref(lines[i]);
+ Error error = AppendRegexSubstitution(bytes_strref, check_only);
+ if (error.Fail()) {
+ if (!m_interpreter.GetDebugger()
+ .GetCommandInterpreter()
+ .GetBatchCommandMode()) {
+ StreamSP out_stream =
+ m_interpreter.GetDebugger().GetAsyncOutputStream();
+ out_stream->Printf("error: %s\n", error.AsCString());
}
+ }
}
+ }
+ if (m_regex_cmd_ap->HasRegexEntries()) {
+ CommandObjectSP cmd_sp(m_regex_cmd_ap.release());
+ m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
+ }
+ }
+ }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ result.AppendError("usage: 'command regex <command-name> "
+ "[s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- Error error;
- const char *name = command.GetArgumentAtIndex(0);
- m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
- name,
- m_options.GetHelp (),
- m_options.GetSyntax (),
- 10,
- 0,
- true));
-
- if (argc == 1)
- {
- Debugger &debugger = m_interpreter.GetDebugger();
- bool color_prompt = debugger.GetUseColor();
- const bool multiple_lines = true; // Get multiple lines
- IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
- IOHandler::Type::Other,
- "lldb-regex", // Name of input reader for history
- "> ", // Prompt
- nullptr, // Continuation prompt
- multiple_lines,
- color_prompt,
- 0, // Don't show line numbers
- *this));
-
- if (io_handler_sp)
- {
- debugger.PushIOHandler(io_handler_sp);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- }
- else
- {
- for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
- {
- llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
- bool check_only = false;
- error = AppendRegexSubstitution (arg_strref, check_only);
- if (error.Fail())
- break;
- }
-
- if (error.Success())
- {
- AddRegexCommandToInterpreter();
- }
- }
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
+ Error error;
+ auto name = command[0].ref;
+ m_regex_cmd_ap = llvm::make_unique<CommandObjectRegexCommand>(
+ m_interpreter, name, m_options.GetHelp(), m_options.GetSyntax(), 10, 0,
+ true);
+
+ if (argc == 1) {
+ Debugger &debugger = m_interpreter.GetDebugger();
+ bool color_prompt = debugger.GetUseColor();
+ const bool multiple_lines = true; // Get multiple lines
+ IOHandlerSP io_handler_sp(new IOHandlerEditline(
+ debugger, IOHandler::Type::Other,
+ "lldb-regex", // Name of input reader for history
+ llvm::StringRef("> "), // Prompt
+ llvm::StringRef(), // Continuation prompt
+ multiple_lines, color_prompt,
+ 0, // Don't show line numbers
+ *this));
+
+ if (io_handler_sp) {
+ debugger.PushIOHandler(io_handler_sp);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+ } else {
+ for (auto &entry : command.entries().drop_front()) {
+ bool check_only = false;
+ error = AppendRegexSubstitution(entry.ref, check_only);
+ if (error.Fail())
+ break;
+ }
+
+ if (error.Success()) {
+ AddRegexCommandToInterpreter();
+ }
+ }
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
- return result.Succeeded();
- }
-
- Error
- AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
- {
- Error error;
-
- if (!m_regex_cmd_ap)
- {
- error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
- (int)regex_sed.size(),
- regex_sed.data());
- return error;
- }
-
- size_t regex_sed_size = regex_sed.size();
-
- if (regex_sed_size <= 1)
- {
- error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
- (int)regex_sed.size(),
- regex_sed.data());
- return error;
- }
+ return result.Succeeded();
+ }
- if (regex_sed[0] != 's')
- {
- error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
- (int)regex_sed.size(),
- regex_sed.data());
- return error;
- }
- const size_t first_separator_char_pos = 1;
- // use the char that follows 's' as the regex separator character
- // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
- const char separator_char = regex_sed[first_separator_char_pos];
- const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
-
- if (second_separator_char_pos == std::string::npos)
- {
- error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
- separator_char,
- (int)(regex_sed.size() - first_separator_char_pos - 1),
- regex_sed.data() + (first_separator_char_pos + 1),
- (int)regex_sed.size(),
- regex_sed.data());
- return error;
- }
+ Error AppendRegexSubstitution(const llvm::StringRef &regex_sed,
+ bool check_only) {
+ Error error;
- const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
-
- if (third_separator_char_pos == std::string::npos)
- {
- error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
- separator_char,
- (int)(regex_sed.size() - second_separator_char_pos - 1),
- regex_sed.data() + (second_separator_char_pos + 1),
- (int)regex_sed.size(),
- regex_sed.data());
- return error;
- }
+ if (!m_regex_cmd_ap) {
+ error.SetErrorStringWithFormat(
+ "invalid regular expression command object for: '%.*s'",
+ (int)regex_sed.size(), regex_sed.data());
+ return error;
+ }
- if (third_separator_char_pos != regex_sed_size - 1)
- {
- // Make sure that everything that follows the last regex
- // separator char
- if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
- {
- error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
- (int)third_separator_char_pos + 1,
- regex_sed.data(),
- (int)(regex_sed.size() - third_separator_char_pos - 1),
- regex_sed.data() + (third_separator_char_pos + 1));
- return error;
- }
- }
- else if (first_separator_char_pos + 1 == second_separator_char_pos)
- {
- error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
- separator_char,
- separator_char,
- separator_char,
- (int)regex_sed.size(),
- regex_sed.data());
- return error;
- }
- else if (second_separator_char_pos + 1 == third_separator_char_pos)
- {
- error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
- separator_char,
- separator_char,
- separator_char,
- (int)regex_sed.size(),
- regex_sed.data());
- return error;
- }
+ size_t regex_sed_size = regex_sed.size();
- if (!check_only)
- {
- std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
- std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
- m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
- subst.c_str());
- }
- return error;
+ if (regex_sed_size <= 1) {
+ error.SetErrorStringWithFormat(
+ "regular expression substitution string is too short: '%.*s'",
+ (int)regex_sed.size(), regex_sed.data());
+ return error;
}
-
- void
- AddRegexCommandToInterpreter()
- {
- if (m_regex_cmd_ap)
- {
- if (m_regex_cmd_ap->HasRegexEntries())
- {
- CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
- m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
- }
- }
+
+ if (regex_sed[0] != 's') {
+ error.SetErrorStringWithFormat("regular expression substitution string "
+ "doesn't start with 's': '%.*s'",
+ (int)regex_sed.size(), regex_sed.data());
+ return error;
+ }
+ const size_t first_separator_char_pos = 1;
+ // use the char that follows 's' as the regex separator character
+ // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
+ const char separator_char = regex_sed[first_separator_char_pos];
+ const size_t second_separator_char_pos =
+ regex_sed.find(separator_char, first_separator_char_pos + 1);
+
+ if (second_separator_char_pos == std::string::npos) {
+ error.SetErrorStringWithFormat(
+ "missing second '%c' separator char after '%.*s' in '%.*s'",
+ separator_char,
+ (int)(regex_sed.size() - first_separator_char_pos - 1),
+ regex_sed.data() + (first_separator_char_pos + 1),
+ (int)regex_sed.size(), regex_sed.data());
+ return error;
}
-private:
- std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'h':
- m_help.assign (option_arg);
- break;
- case 's':
- m_syntax.assign (option_arg);
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_help.clear();
- m_syntax.clear();
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- const char *
- GetHelp()
- {
- return (m_help.empty() ? nullptr : m_help.c_str());
- }
-
- const char *
- GetSyntax ()
- {
- return (m_syntax.empty() ? nullptr : m_syntax.c_str());
- }
-
- protected:
- // Instance variables to hold the values for command options.
-
- std::string m_help;
- std::string m_syntax;
- };
-
- Options *
- GetOptions () override
- {
- return &m_options;
- }
-
- CommandOptions m_options;
-};
+ const size_t third_separator_char_pos =
+ regex_sed.find(separator_char, second_separator_char_pos + 1);
+
+ if (third_separator_char_pos == std::string::npos) {
+ error.SetErrorStringWithFormat(
+ "missing third '%c' separator char after '%.*s' in '%.*s'",
+ separator_char,
+ (int)(regex_sed.size() - second_separator_char_pos - 1),
+ regex_sed.data() + (second_separator_char_pos + 1),
+ (int)regex_sed.size(), regex_sed.data());
+ return error;
+ }
-OptionDefinition
-CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command."},
-{ LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
-{ 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
-};
+ if (third_separator_char_pos != regex_sed_size - 1) {
+ // Make sure that everything that follows the last regex
+ // separator char
+ if (regex_sed.find_first_not_of("\t\n\v\f\r ",
+ third_separator_char_pos + 1) !=
+ std::string::npos) {
+ error.SetErrorStringWithFormat(
+ "extra data found after the '%.*s' regular expression substitution "
+ "string: '%.*s'",
+ (int)third_separator_char_pos + 1, regex_sed.data(),
+ (int)(regex_sed.size() - third_separator_char_pos - 1),
+ regex_sed.data() + (third_separator_char_pos + 1));
+ return error;
+ }
+ } else if (first_separator_char_pos + 1 == second_separator_char_pos) {
+ error.SetErrorStringWithFormat(
+ "<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
+ separator_char, separator_char, separator_char, (int)regex_sed.size(),
+ regex_sed.data());
+ return error;
+ } else if (second_separator_char_pos + 1 == third_separator_char_pos) {
+ error.SetErrorStringWithFormat(
+ "<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
+ separator_char, separator_char, separator_char, (int)regex_sed.size(),
+ regex_sed.data());
+ return error;
+ }
-class CommandObjectPythonFunction : public CommandObjectRaw
-{
-public:
- CommandObjectPythonFunction (CommandInterpreter &interpreter,
- std::string name,
- std::string funct,
- std::string help,
- ScriptedCommandSynchronicity synch) :
- CommandObjectRaw(interpreter,
- name.c_str(),
- nullptr,
- nullptr),
- m_function_name(funct),
- m_synchro(synch),
- m_fetched_help_long(false)
- {
- if (!help.empty())
- SetHelp(help.c_str());
- else
- {
- StreamString stream;
- stream.Printf("For more information run 'help %s'",name.c_str());
- SetHelp(stream.GetData());
- }
+ if (!check_only) {
+ std::string regex(regex_sed.substr(first_separator_char_pos + 1,
+ second_separator_char_pos -
+ first_separator_char_pos - 1));
+ std::string subst(regex_sed.substr(second_separator_char_pos + 1,
+ third_separator_char_pos -
+ second_separator_char_pos - 1));
+ m_regex_cmd_ap->AddRegexCommand(regex.c_str(), subst.c_str());
+ }
+ return error;
+ }
+
+ void AddRegexCommandToInterpreter() {
+ if (m_regex_cmd_ap) {
+ if (m_regex_cmd_ap->HasRegexEntries()) {
+ CommandObjectSP cmd_sp(m_regex_cmd_ap.release());
+ m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
+ }
}
+ }
- ~CommandObjectPythonFunction() override = default;
+private:
+ std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'h':
+ m_help.assign(option_arg);
+ break;
+ case 's':
+ m_syntax.assign(option_arg);
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
- bool
- IsRemovable () const override
- {
- return true;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_help.clear();
+ m_syntax.clear();
}
- const std::string&
- GetFunctionName ()
- {
- return m_function_name;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_regex_options);
}
- ScriptedCommandSynchronicity
- GetSynchronicity ()
- {
- return m_synchro;
+ // TODO: Convert these functions to return StringRefs.
+ const char *GetHelp() {
+ return (m_help.empty() ? nullptr : m_help.c_str());
}
-
- const char *
- GetHelpLong () override
- {
- if (!m_fetched_help_long)
- {
- ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
- if (scripter)
- {
- std::string docstring;
- m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
- if (!docstring.empty())
- SetHelpLong(docstring.c_str());
- }
- }
- return CommandObjectRaw::GetHelpLong();
+
+ const char *GetSyntax() {
+ return (m_syntax.empty() ? nullptr : m_syntax.c_str());
}
-
+
+ protected:
+ // Instance variables to hold the values for command options.
+
+ std::string m_help;
+ std::string m_syntax;
+ };
+
+ Options *GetOptions() override { return &m_options; }
+
+ CommandOptions m_options;
+};
+
+class CommandObjectPythonFunction : public CommandObjectRaw {
+public:
+ CommandObjectPythonFunction(CommandInterpreter &interpreter, std::string name,
+ std::string funct, std::string help,
+ ScriptedCommandSynchronicity synch)
+ : CommandObjectRaw(interpreter, name),
+ m_function_name(funct), m_synchro(synch), m_fetched_help_long(false) {
+ if (!help.empty())
+ SetHelp(help);
+ else {
+ StreamString stream;
+ stream.Printf("For more information run 'help %s'", name.c_str());
+ SetHelp(stream.GetString());
+ }
+ }
+
+ ~CommandObjectPythonFunction() override = default;
+
+ bool IsRemovable() const override { return true; }
+
+ const std::string &GetFunctionName() { return m_function_name; }
+
+ ScriptedCommandSynchronicity GetSynchronicity() { return m_synchro; }
+
+ llvm::StringRef GetHelpLong() override {
+ if (m_fetched_help_long)
+ return CommandObjectRaw::GetHelpLong();
+
+ ScriptInterpreter *scripter = m_interpreter.GetScriptInterpreter();
+ if (!scripter)
+ return CommandObjectRaw::GetHelpLong();
+
+ std::string docstring;
+ m_fetched_help_long =
+ scripter->GetDocumentationForItem(m_function_name.c_str(), docstring);
+ if (!docstring.empty())
+ SetHelpLong(docstring);
+ return CommandObjectRaw::GetHelpLong();
+ }
+
protected:
- bool
- DoExecute (const char *raw_command_line, CommandReturnObject &result) override
- {
- ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
-
- Error error;
-
- result.SetStatus(eReturnStatusInvalid);
-
- if (!scripter || !scripter->RunScriptBasedCommand(m_function_name.c_str(),
- raw_command_line,
- m_synchro,
- result,
- error,
- m_exe_ctx))
- {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- }
+ bool DoExecute(const char *raw_command_line,
+ CommandReturnObject &result) override {
+ ScriptInterpreter *scripter = m_interpreter.GetScriptInterpreter();
+
+ Error error;
+
+ result.SetStatus(eReturnStatusInvalid);
+
+ if (!scripter ||
+ !scripter->RunScriptBasedCommand(m_function_name.c_str(),
+ raw_command_line, m_synchro, result,
+ error, m_exe_ctx)) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ // Don't change the status if the command already set it...
+ if (result.GetStatus() == eReturnStatusInvalid) {
+ if (result.GetOutputData().empty())
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
else
- {
- // Don't change the status if the command already set it...
- if (result.GetStatus() == eReturnStatusInvalid)
- {
- if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- else
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- }
-
- return result.Succeeded();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
}
+ return result.Succeeded();
+ }
+
private:
- std::string m_function_name;
- ScriptedCommandSynchronicity m_synchro;
- bool m_fetched_help_long;
+ std::string m_function_name;
+ ScriptedCommandSynchronicity m_synchro;
+ bool m_fetched_help_long;
};
-class CommandObjectScriptingObject : public CommandObjectRaw
-{
+class CommandObjectScriptingObject : public CommandObjectRaw {
public:
- CommandObjectScriptingObject (CommandInterpreter &interpreter,
- std::string name,
- StructuredData::GenericSP cmd_obj_sp,
- ScriptedCommandSynchronicity synch) :
- CommandObjectRaw(interpreter,
- name.c_str(),
- nullptr,
- nullptr),
- m_cmd_obj_sp(cmd_obj_sp),
- m_synchro(synch),
- m_fetched_help_short(false),
- m_fetched_help_long(false)
- {
- StreamString stream;
- stream.Printf("For more information run 'help %s'",name.c_str());
- SetHelp(stream.GetData());
- if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
- GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
- }
-
- ~CommandObjectScriptingObject() override = default;
-
- bool
- IsRemovable () const override
- {
- return true;
- }
-
- StructuredData::GenericSP
- GetImplementingObject ()
- {
- return m_cmd_obj_sp;
- }
-
- ScriptedCommandSynchronicity
- GetSynchronicity ()
- {
- return m_synchro;
- }
-
- const char *
- GetHelp () override
- {
- if (!m_fetched_help_short)
- {
- ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
- if (scripter)
- {
- std::string docstring;
- m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
- if (!docstring.empty())
- SetHelp(docstring.c_str());
- }
- }
- return CommandObjectRaw::GetHelp();
- }
-
- const char *
- GetHelpLong () override
- {
- if (!m_fetched_help_long)
- {
- ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
- if (scripter)
- {
- std::string docstring;
- m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
- if (!docstring.empty())
- SetHelpLong(docstring.c_str());
- }
- }
- return CommandObjectRaw::GetHelpLong();
- }
-
+ CommandObjectScriptingObject(CommandInterpreter &interpreter,
+ std::string name,
+ StructuredData::GenericSP cmd_obj_sp,
+ ScriptedCommandSynchronicity synch)
+ : CommandObjectRaw(interpreter, name),
+ m_cmd_obj_sp(cmd_obj_sp), m_synchro(synch), m_fetched_help_short(false),
+ m_fetched_help_long(false) {
+ StreamString stream;
+ stream.Printf("For more information run 'help %s'", name.c_str());
+ SetHelp(stream.GetString());
+ if (ScriptInterpreter *scripter = m_interpreter.GetScriptInterpreter())
+ GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
+ }
+
+ ~CommandObjectScriptingObject() override = default;
+
+ bool IsRemovable() const override { return true; }
+
+ StructuredData::GenericSP GetImplementingObject() { return m_cmd_obj_sp; }
+
+ ScriptedCommandSynchronicity GetSynchronicity() { return m_synchro; }
+
+ llvm::StringRef GetHelp() override {
+ if (m_fetched_help_short)
+ return CommandObjectRaw::GetHelp();
+ ScriptInterpreter *scripter = m_interpreter.GetScriptInterpreter();
+ if (!scripter)
+ return CommandObjectRaw::GetHelp();
+ std::string docstring;
+ m_fetched_help_short =
+ scripter->GetShortHelpForCommandObject(m_cmd_obj_sp, docstring);
+ if (!docstring.empty())
+ SetHelp(docstring);
+
+ return CommandObjectRaw::GetHelp();
+ }
+
+ llvm::StringRef GetHelpLong() override {
+ if (m_fetched_help_long)
+ return CommandObjectRaw::GetHelpLong();
+
+ ScriptInterpreter *scripter = m_interpreter.GetScriptInterpreter();
+ if (!scripter)
+ return CommandObjectRaw::GetHelpLong();
+
+ std::string docstring;
+ m_fetched_help_long =
+ scripter->GetLongHelpForCommandObject(m_cmd_obj_sp, docstring);
+ if (!docstring.empty())
+ SetHelpLong(docstring);
+ return CommandObjectRaw::GetHelpLong();
+ }
+
protected:
- bool
- DoExecute (const char *raw_command_line, CommandReturnObject &result) override
- {
- ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
-
- Error error;
-
- result.SetStatus(eReturnStatusInvalid);
-
- if (!scripter || !scripter->RunScriptBasedCommand(m_cmd_obj_sp,
- raw_command_line,
- m_synchro,
- result,
- error,
- m_exe_ctx))
- {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- }
+ bool DoExecute(const char *raw_command_line,
+ CommandReturnObject &result) override {
+ ScriptInterpreter *scripter = m_interpreter.GetScriptInterpreter();
+
+ Error error;
+
+ result.SetStatus(eReturnStatusInvalid);
+
+ if (!scripter ||
+ !scripter->RunScriptBasedCommand(m_cmd_obj_sp, raw_command_line,
+ m_synchro, result, error, m_exe_ctx)) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ // Don't change the status if the command already set it...
+ if (result.GetStatus() == eReturnStatusInvalid) {
+ if (result.GetOutputData().empty())
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
else
- {
- // Don't change the status if the command already set it...
- if (result.GetStatus() == eReturnStatusInvalid)
- {
- if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- else
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- }
-
- return result.Succeeded();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
}
+ return result.Succeeded();
+ }
+
private:
- StructuredData::GenericSP m_cmd_obj_sp;
- ScriptedCommandSynchronicity m_synchro;
- bool m_fetched_help_short: 1;
- bool m_fetched_help_long: 1;
+ StructuredData::GenericSP m_cmd_obj_sp;
+ ScriptedCommandSynchronicity m_synchro;
+ bool m_fetched_help_short : 1;
+ bool m_fetched_help_long : 1;
};
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptImport
//-------------------------------------------------------------------------
-class CommandObjectCommandsScriptImport : public CommandObjectParsed
-{
+OptionDefinition g_script_import_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not." },
+ // clang-format on
+};
+
+class CommandObjectCommandsScriptImport : public CommandObjectParsed {
public:
- CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "command script import",
- "Import a scripting module in LLDB.",
- nullptr),
- m_options(interpreter)
- {
- CommandArgumentEntry arg1;
- CommandArgumentData cmd_arg;
-
- // Define the first (and only) variant of this arg.
- cmd_arg.arg_type = eArgTypeFilename;
- cmd_arg.arg_repetition = eArgRepeatPlus;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (cmd_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- }
-
- ~CommandObjectCommandsScriptImport() override = default;
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
- }
-
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ CommandObjectCommandsScriptImport(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "command script import",
+ "Import a scripting module in LLDB.", nullptr),
+ m_options() {
+ CommandArgumentEntry arg1;
+ CommandArgumentData cmd_arg;
+
+ // Define the first (and only) variant of this arg.
+ cmd_arg.arg_type = eArgTypeFilename;
+ cmd_arg.arg_repetition = eArgRepeatPlus;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(cmd_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectCommandsScriptImport() override = default;
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ llvm::StringRef completion_str = input[cursor_index].ref;
+ completion_str = completion_str.take_front(cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ completion_str, match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
+
+ Options *GetOptions() override { return &m_options; }
protected:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'r':
+ m_allow_reload = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'r':
- m_allow_reload = true;
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_allow_reload = true;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool m_allow_reload;
- };
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
- {
- result.AppendError ("only scripting language supported for module importing is currently Python");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- size_t argc = command.GetArgumentCount();
- if (0 == argc)
- {
- result.AppendError("command script import needs one or more arguments");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- for (size_t i = 0;
- i < argc;
- i++)
- {
- std::string path = command.GetArgumentAtIndex(i);
- Error error;
-
- const bool init_session = true;
- // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
- // commands won't ever be recursively invoked, but it's actually possible to craft
- // a Python script that does other "command script imports" in __lldb_init_module
- // the real fix is to have recursive commands possible with a CommandInvocation object
- // separate from the CommandObject itself, so that recursive command invocations
- // won't stomp on each other (wrt to execution contents, options, and more)
- m_exe_ctx.Clear();
- if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
- m_options.m_allow_reload,
- init_session,
- error))
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
-
- return result.Succeeded();
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_allow_reload = true;
}
-
- CommandOptions m_options;
-};
-OptionDefinition
-CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_script_import_options);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ bool m_allow_reload;
+ };
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (m_interpreter.GetDebugger().GetScriptLanguage() !=
+ lldb::eScriptLanguagePython) {
+ result.AppendError("only scripting language supported for module "
+ "importing is currently Python");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (command.empty()) {
+ result.AppendError("command script import needs one or more arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ for (auto &entry : command.entries()) {
+ Error error;
+
+ const bool init_session = true;
+ // FIXME: this is necessary because CommandObject::CheckRequirements()
+ // assumes that commands won't ever be recursively invoked, but it's
+ // actually possible to craft a Python script that does other "command
+ // script imports" in __lldb_init_module the real fix is to have recursive
+ // commands possible with a CommandInvocation object separate from the
+ // CommandObject itself, so that recursive command invocations won't stomp
+ // on each other (wrt to execution contents, options, and more)
+ m_exe_ctx.Clear();
+ if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(
+ entry.c_str(), m_options.m_allow_reload, init_session, error)) {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendErrorWithFormat("module importing failed: %s",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+
+ return result.Succeeded();
+ }
+
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptAdd
//-------------------------------------------------------------------------
-class CommandObjectCommandsScriptAdd :
- public CommandObjectParsed,
- public IOHandlerDelegateMultiline
-{
+static OptionEnumValueElement g_script_synchro_type[] = {
+ {eScriptedCommandSynchronicitySynchronous, "synchronous",
+ "Run synchronous"},
+ {eScriptedCommandSynchronicityAsynchronous, "asynchronous",
+ "Run asynchronous"},
+ {eScriptedCommandSynchronicityCurrentValue, "current",
+ "Do not alter current setting"},
+ {0, nullptr, nullptr}};
+
+static OptionDefinition g_script_add_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name." },
+ { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name." },
+ { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command." },
+ { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system." },
+ // clang-format on
+};
+
+class CommandObjectCommandsScriptAdd : public CommandObjectParsed,
+ public IOHandlerDelegateMultiline {
public:
- CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "command script add",
+ CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "command script add",
"Add a scripted function as an LLDB command.",
nullptr),
- IOHandlerDelegateMultiline ("DONE"),
- m_options (interpreter)
- {
- CommandArgumentEntry arg1;
- CommandArgumentData cmd_arg;
-
- // Define the first (and only) variant of this arg.
- cmd_arg.arg_type = eArgTypeCommandName;
- cmd_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (cmd_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- }
-
- ~CommandObjectCommandsScriptAdd() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
- }
-
+ IOHandlerDelegateMultiline("DONE"), m_options() {
+ CommandArgumentEntry arg1;
+ CommandArgumentData cmd_arg;
+
+ // Define the first (and only) variant of this arg.
+ cmd_arg.arg_type = eArgTypeCommandName;
+ cmd_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(cmd_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectCommandsScriptAdd() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
protected:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_class_name(),
- m_funct_name(),
- m_short_help(),
- m_synchronicity(eScriptedCommandSynchronicitySynchronous)
- {
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_class_name(), m_funct_name(), m_short_help(),
+ m_synchronicity(eScriptedCommandSynchronicitySynchronous) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ if (!option_arg.empty())
+ m_funct_name = option_arg;
+ break;
+ case 'c':
+ if (!option_arg.empty())
+ m_class_name = option_arg;
+ break;
+ case 'h':
+ if (!option_arg.empty())
+ m_short_help = option_arg;
+ break;
+ case 's':
+ m_synchronicity =
+ (ScriptedCommandSynchronicity)Args::StringToOptionEnum(
+ option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
+ if (!error.Success())
+ error.SetErrorStringWithFormat(
+ "unrecognized value for synchronicity '%s'",
+ option_arg.str().c_str());
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'f':
- if (option_arg)
- m_funct_name.assign(option_arg);
- break;
- case 'c':
- if (option_arg)
- m_class_name.assign(option_arg);
- break;
- case 'h':
- if (option_arg)
- m_short_help.assign(option_arg);
- break;
- case 's':
- m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
- if (!error.Success())
- error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_class_name.clear();
- m_funct_name.clear();
- m_short_help.clear();
- m_synchronicity = eScriptedCommandSynchronicitySynchronous;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- std::string m_class_name;
- std::string m_funct_name;
- std::string m_short_help;
- ScriptedCommandSynchronicity m_synchronicity;
- };
-
- void
- IOHandlerActivated (IOHandler &io_handler) override
- {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- if (output_sp)
- {
- output_sp->PutCString(g_python_command_instructions);
- output_sp->Flush();
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_class_name.clear();
+ m_funct_name.clear();
+ m_short_help.clear();
+ m_synchronicity = eScriptedCommandSynchronicitySynchronous;
}
-
-
- void
- IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
- {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
-
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (interpreter)
- {
-
- StringList lines;
- lines.SplitIntoLines(data);
- if (lines.GetSize() > 0)
- {
- std::string funct_name_str;
- if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
- {
- if (funct_name_str.empty())
- {
- error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
- error_sp->Flush();
- }
- else
- {
- // everything should be fine now, let's add this alias
-
- CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
- m_cmd_name,
- funct_name_str.c_str(),
- m_short_help,
- m_synchronicity));
-
- if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
- {
- error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
- error_sp->Flush();
- }
- }
- }
- else
- {
- error_sp->Printf ("error: unable to create function, didn't add python command.\n");
- error_sp->Flush();
- }
- }
- else
- {
- error_sp->Printf ("error: empty function, didn't add python command.\n");
- error_sp->Flush();
- }
- }
- else
- {
- error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
- error_sp->Flush();
- }
- io_handler.SetIsDone(true);
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_script_add_options);
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
- {
- result.AppendError ("only scripting language supported for scripted commands is currently Python");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- size_t argc = command.GetArgumentCount();
-
- if (argc != 1)
- {
- result.AppendError ("'command script add' requires one argument");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- // Store the options in case we get multi-line input
- m_cmd_name = command.GetArgumentAtIndex(0);
- m_short_help.assign(m_options.m_short_help);
- m_synchronicity = m_options.m_synchronicity;
-
- if (m_options.m_class_name.empty())
- {
- if (m_options.m_funct_name.empty())
- {
- m_interpreter.GetPythonCommandsFromIOHandler(" ", // Prompt
- *this, // IOHandlerDelegate
- true, // Run IOHandler in async mode
- nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
- }
- else
- {
- CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
- m_cmd_name,
- m_options.m_funct_name,
- m_options.m_short_help,
- m_synchronicity));
- if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError("cannot add command");
- result.SetStatus (eReturnStatusFailed);
- }
- }
- }
- else
- {
- ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
- if (!interpreter)
- {
- result.AppendError("cannot find ScriptInterpreter");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
- if (!cmd_obj_sp)
- {
- result.AppendError("cannot create helper object");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
- m_cmd_name,
- cmd_obj_sp,
- m_synchronicity));
- if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError("cannot add command");
- result.SetStatus (eReturnStatusFailed);
- }
- }
+ // Instance variables to hold the values for command options.
- return result.Succeeded();
- }
-
- CommandOptions m_options;
- std::string m_cmd_name;
+ std::string m_class_name;
+ std::string m_funct_name;
std::string m_short_help;
ScriptedCommandSynchronicity m_synchronicity;
-};
+ };
-static OptionEnumValueElement g_script_synchro_type[] =
-{
- { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"},
- { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"},
- { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"},
- { 0, nullptr, nullptr }
-};
+ void IOHandlerActivated(IOHandler &io_handler) override {
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp) {
+ output_sp->PutCString(g_python_command_instructions);
+ output_sp->Flush();
+ }
+ }
+
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) override {
+ StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (interpreter) {
+
+ StringList lines;
+ lines.SplitIntoLines(data);
+ if (lines.GetSize() > 0) {
+ std::string funct_name_str;
+ if (interpreter->GenerateScriptAliasFunction(lines, funct_name_str)) {
+ if (funct_name_str.empty()) {
+ error_sp->Printf("error: unable to obtain a function name, didn't "
+ "add python command.\n");
+ error_sp->Flush();
+ } else {
+ // everything should be fine now, let's add this alias
+
+ CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(
+ m_interpreter, m_cmd_name, funct_name_str, m_short_help,
+ m_synchronicity));
+
+ if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp,
+ true)) {
+ error_sp->Printf("error: unable to add selected command, didn't "
+ "add python command.\n");
+ error_sp->Flush();
+ }
+ }
+ } else {
+ error_sp->Printf(
+ "error: unable to create function, didn't add python command.\n");
+ error_sp->Flush();
+ }
+ } else {
+ error_sp->Printf("error: empty function, didn't add python command.\n");
+ error_sp->Flush();
+ }
+ } else {
+ error_sp->Printf(
+ "error: script interpreter missing, didn't add python command.\n");
+ error_sp->Flush();
+ }
+
+ io_handler.SetIsDone(true);
+ }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (m_interpreter.GetDebugger().GetScriptLanguage() !=
+ lldb::eScriptLanguagePython) {
+ result.AppendError("only scripting language supported for scripted "
+ "commands is currently Python");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (command.GetArgumentCount() != 1) {
+ result.AppendError("'command script add' requires one argument");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Store the options in case we get multi-line input
+ m_cmd_name = command[0].ref;
+ m_short_help.assign(m_options.m_short_help);
+ m_synchronicity = m_options.m_synchronicity;
+
+ if (m_options.m_class_name.empty()) {
+ if (m_options.m_funct_name.empty()) {
+ m_interpreter.GetPythonCommandsFromIOHandler(
+ " ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ nullptr); // Baton for the "io_handler" that will be passed back
+ // into our IOHandlerDelegate functions
+ } else {
+ CommandObjectSP new_cmd(new CommandObjectPythonFunction(
+ m_interpreter, m_cmd_name, m_options.m_funct_name,
+ m_options.m_short_help, m_synchronicity));
+ if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("cannot add command");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+ } else {
+ ScriptInterpreter *interpreter =
+ GetCommandInterpreter().GetScriptInterpreter();
+ if (!interpreter) {
+ result.AppendError("cannot find ScriptInterpreter");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ auto cmd_obj_sp = interpreter->CreateScriptCommandObject(
+ m_options.m_class_name.c_str());
+ if (!cmd_obj_sp) {
+ result.AppendError("cannot create helper object");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ CommandObjectSP new_cmd(new CommandObjectScriptingObject(
+ m_interpreter, m_cmd_name, cmd_obj_sp, m_synchronicity));
+ if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("cannot add command");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."},
- { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."},
- { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command."},
- { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
+ std::string m_cmd_name;
+ std::string m_short_help;
+ ScriptedCommandSynchronicity m_synchronicity;
};
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptList
//-------------------------------------------------------------------------
-class CommandObjectCommandsScriptList : public CommandObjectParsed
-{
+class CommandObjectCommandsScriptList : public CommandObjectParsed {
public:
- CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "command script list",
- "List defined scripted commands.",
- nullptr)
- {
- }
-
- ~CommandObjectCommandsScriptList() override = default;
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- m_interpreter.GetHelp(result,
- CommandInterpreter::eCommandTypesUserDef);
-
- result.SetStatus (eReturnStatusSuccessFinishResult);
-
- return true;
- }
+ CommandObjectCommandsScriptList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "command script list",
+ "List defined scripted commands.", nullptr) {}
+
+ ~CommandObjectCommandsScriptList() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ m_interpreter.GetHelp(result, CommandInterpreter::eCommandTypesUserDef);
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ return true;
+ }
};
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptClear
//-------------------------------------------------------------------------
-class CommandObjectCommandsScriptClear : public CommandObjectParsed
-{
+class CommandObjectCommandsScriptClear : public CommandObjectParsed {
public:
- CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "command script clear",
- "Delete all scripted commands.",
- nullptr)
- {
- }
+ CommandObjectCommandsScriptClear(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "command script clear",
+ "Delete all scripted commands.", nullptr) {}
- ~CommandObjectCommandsScriptClear() override = default;
+ ~CommandObjectCommandsScriptClear() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- m_interpreter.RemoveAllUser();
-
- result.SetStatus (eReturnStatusSuccessFinishResult);
-
- return true;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ m_interpreter.RemoveAllUser();
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ return true;
+ }
};
//-------------------------------------------------------------------------
// CommandObjectCommandsScriptDelete
//-------------------------------------------------------------------------
-class CommandObjectCommandsScriptDelete : public CommandObjectParsed
-{
+class CommandObjectCommandsScriptDelete : public CommandObjectParsed {
public:
- CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "command script delete",
- "Delete a scripted command.",
- nullptr)
- {
- CommandArgumentEntry arg1;
- CommandArgumentData cmd_arg;
-
- // Define the first (and only) variant of this arg.
- cmd_arg.arg_type = eArgTypeCommandName;
- cmd_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (cmd_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- }
-
- ~CommandObjectCommandsScriptDelete() override = default;
+ CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "command script delete",
+ "Delete a scripted command.", nullptr) {
+ CommandArgumentEntry arg1;
+ CommandArgumentData cmd_arg;
+
+ // Define the first (and only) variant of this arg.
+ cmd_arg.arg_type = eArgTypeCommandName;
+ cmd_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(cmd_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectCommandsScriptDelete() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
-
- size_t argc = command.GetArgumentCount();
-
- if (argc != 1)
- {
- result.AppendError ("'command script delete' requires one argument");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- const char* cmd_name = command.GetArgumentAtIndex(0);
-
- if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
- {
- m_interpreter.RemoveUser(cmd_name);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("command %s not found", cmd_name);
- result.SetStatus (eReturnStatusFailed);
- }
-
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+
+ if (command.GetArgumentCount() != 1) {
+ result.AppendError("'command script delete' requires one argument");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ auto cmd_name = command[0].ref;
+
+ if (cmd_name.empty() || !m_interpreter.HasUserCommands() ||
+ !m_interpreter.UserCommandExists(cmd_name)) {
+ result.AppendErrorWithFormat("command %s not found", command[0].c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ m_interpreter.RemoveUser(cmd_name);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
};
#pragma mark CommandObjectMultiwordCommandsScript
@@ -2256,22 +1900,30 @@ protected:
// CommandObjectMultiwordCommandsScript
//-------------------------------------------------------------------------
-class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
-{
+class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword {
public:
- CommandObjectMultiwordCommandsScript(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "command script",
- "Commands for managing custom commands implemented by interpreter scripts.",
- "command script <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
- LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
- LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
- }
-
- ~CommandObjectMultiwordCommandsScript() override = default;
+ CommandObjectMultiwordCommandsScript(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "command script", "Commands for managing custom "
+ "commands implemented by "
+ "interpreter scripts.",
+ "command script <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("add", CommandObjectSP(
+ new CommandObjectCommandsScriptAdd(interpreter)));
+ LoadSubCommand(
+ "delete",
+ CommandObjectSP(new CommandObjectCommandsScriptDelete(interpreter)));
+ LoadSubCommand(
+ "clear",
+ CommandObjectSP(new CommandObjectCommandsScriptClear(interpreter)));
+ LoadSubCommand("list", CommandObjectSP(new CommandObjectCommandsScriptList(
+ interpreter)));
+ LoadSubCommand(
+ "import",
+ CommandObjectSP(new CommandObjectCommandsScriptImport(interpreter)));
+ }
+
+ ~CommandObjectMultiwordCommandsScript() override = default;
};
#pragma mark CommandObjectMultiwordCommands
@@ -2280,17 +1932,26 @@ public:
// CommandObjectMultiwordCommands
//-------------------------------------------------------------------------
-CommandObjectMultiwordCommands::CommandObjectMultiwordCommands(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "command", "Commands for managing custom LLDB commands.",
- "command <subcommand> [<subcommand-options>]")
-{
- LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
- LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
- LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
- LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
- LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
- LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
+CommandObjectMultiwordCommands::CommandObjectMultiwordCommands(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "command",
+ "Commands for managing custom LLDB commands.",
+ "command <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("source",
+ CommandObjectSP(new CommandObjectCommandsSource(interpreter)));
+ LoadSubCommand("alias",
+ CommandObjectSP(new CommandObjectCommandsAlias(interpreter)));
+ LoadSubCommand("unalias", CommandObjectSP(
+ new CommandObjectCommandsUnalias(interpreter)));
+ LoadSubCommand("delete",
+ CommandObjectSP(new CommandObjectCommandsDelete(interpreter)));
+ LoadSubCommand(
+ "regex", CommandObjectSP(new CommandObjectCommandsAddRegex(interpreter)));
+ LoadSubCommand("history", CommandObjectSP(
+ new CommandObjectCommandsHistory(interpreter)));
+ LoadSubCommand(
+ "script",
+ CommandObjectSP(new CommandObjectMultiwordCommandsScript(interpreter)));
}
CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands() = default;
diff --git a/source/Commands/CommandObjectCommands.h b/source/Commands/CommandObjectCommands.h
index c12c71051ffe..a5ef777aa982 100644
--- a/source/Commands/CommandObjectCommands.h
+++ b/source/Commands/CommandObjectCommands.h
@@ -1,4 +1,5 @@
-//===-- CommandObjectCommands.h -----------------------------------*- C++ -*-===//
+//===-- CommandObjectCommands.h -----------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,9 +15,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Core/STLUtils.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
-#include "lldb/Core/STLUtils.h"
namespace lldb_private {
@@ -24,13 +25,11 @@ namespace lldb_private {
// CommandObjectMultiwordCommands
//-------------------------------------------------------------------------
-class CommandObjectMultiwordCommands : public CommandObjectMultiword
-{
+class CommandObjectMultiwordCommands : public CommandObjectMultiword {
public:
+ CommandObjectMultiwordCommands(CommandInterpreter &interpreter);
- CommandObjectMultiwordCommands (CommandInterpreter &interpreter);
-
- ~CommandObjectMultiwordCommands() override;
+ ~CommandObjectMultiwordCommands() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp
index 07a847aaebae..fa3a1440ffc0 100644
--- a/source/Commands/CommandObjectDisassemble.cpp
+++ b/source/Commands/CommandObjectDisassemble.cpp
@@ -29,585 +29,535 @@
#include "lldb/Target/Target.h"
#define DEFAULT_DISASM_BYTE_SIZE 32
-#define DEFAULT_DISASM_NUM_INS 4
+#define DEFAULT_DISASM_NUM_INS 4
using namespace lldb;
using namespace lldb_private;
-CommandObjectDisassemble::CommandOptions::CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter),
- num_lines_context(0),
- num_instructions (0),
- func_name(),
- current_function (false),
- start_addr(),
- end_addr (),
- at_pc (false),
- frame_line (false),
- plugin_name (),
- flavor_string(),
- arch(),
- some_location_specified (false),
- symbol_containing_addr ()
-{
- OptionParsingStarting();
+static OptionDefinition g_disassemble_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "bytes", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show opcode bytes when disassembling." },
+ { LLDB_OPT_SET_ALL, false, "context", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNumLines, "Number of context lines of source to show." },
+ { LLDB_OPT_SET_ALL, false, "mixed", 'm', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable mixed source and assembly display." },
+ { LLDB_OPT_SET_ALL, false, "raw", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Print raw disassembly with no symbol information." },
+ { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use." },
+ { LLDB_OPT_SET_ALL, false, "flavor", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. "
+ "Currently the only valid options are default, and for Intel "
+ "architectures, att and intel." },
+ { LLDB_OPT_SET_ALL, false, "arch", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeArchitecture, "Specify the architecture to use from cross disassembly." },
+ { LLDB_OPT_SET_1 |
+ LLDB_OPT_SET_2, true, "start-address", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Address at which to start disassembling." },
+ { LLDB_OPT_SET_1, false, "end-address", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling." },
+ { LLDB_OPT_SET_2 |
+ LLDB_OPT_SET_3 |
+ LLDB_OPT_SET_4 |
+ LLDB_OPT_SET_5, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNumLines, "Number of instructions to display." },
+ { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name." },
+ { LLDB_OPT_SET_4, false, "frame", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disassemble from the start of the current frame's function." },
+ { LLDB_OPT_SET_5, false, "pc", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disassemble around the current pc." },
+ { LLDB_OPT_SET_6, false, "line", 'l', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line "
+ "table information, else disassemble around the pc." },
+ { LLDB_OPT_SET_7, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address." },
+ // clang-format on
+};
+
+CommandObjectDisassemble::CommandOptions::CommandOptions()
+ : Options(), num_lines_context(0), num_instructions(0), func_name(),
+ current_function(false), start_addr(), end_addr(), at_pc(false),
+ frame_line(false), plugin_name(), flavor_string(), arch(),
+ some_location_specified(false), symbol_containing_addr() {
+ OptionParsingStarting(nullptr);
}
CommandObjectDisassemble::CommandOptions::~CommandOptions() = default;
-Error
-CommandObjectDisassemble::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
-{
- Error error;
-
- const int short_option = m_getopt_table[option_idx].val;
-
- bool success;
-
- switch (short_option)
- {
- case 'm':
- show_mixed = true;
- break;
-
- case 'C':
- num_lines_context = StringConvert::ToUInt32(option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat ("invalid num context lines string: \"%s\"", option_arg);
- break;
-
- case 'c':
- num_instructions = StringConvert::ToUInt32(option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat ("invalid num of instructions string: \"%s\"", option_arg);
- break;
-
- case 'b':
- show_bytes = true;
- break;
-
- case 's':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- start_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- if (start_addr != LLDB_INVALID_ADDRESS)
- some_location_specified = true;
- }
- break;
- case 'e':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- end_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- if (end_addr != LLDB_INVALID_ADDRESS)
- some_location_specified = true;
- }
- break;
-
- case 'n':
- func_name.assign (option_arg);
- some_location_specified = true;
- break;
-
- case 'p':
- at_pc = true;
- some_location_specified = true;
- break;
-
- case 'l':
- frame_line = true;
- // Disassemble the current source line kind of implies showing mixed
- // source code context.
- show_mixed = true;
- some_location_specified = true;
- break;
-
- case 'P':
- plugin_name.assign (option_arg);
- break;
-
- case 'F':
- {
- Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
- if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86
- || target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64)
- {
- flavor_string.assign (option_arg);
- }
- else
- error.SetErrorStringWithFormat("Disassembler flavors are currently only supported for x86 and x86_64 targets.");
- break;
- }
-
- case 'r':
- raw = true;
- break;
-
- case 'f':
- current_function = true;
- some_location_specified = true;
- break;
-
- case 'A':
- if (!arch.SetTriple (option_arg, m_interpreter.GetPlatform (true).get()))
- arch.SetTriple (option_arg);
- break;
-
- case 'a':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- symbol_containing_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- if (symbol_containing_addr != LLDB_INVALID_ADDRESS)
- {
- some_location_specified = true;
- }
- }
- break;
+Error CommandObjectDisassemble::CommandOptions::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Error error;
+
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'm':
+ show_mixed = true;
+ break;
+
+ case 'C':
+ if (option_arg.getAsInteger(0, num_lines_context))
+ error.SetErrorStringWithFormat("invalid num context lines string: \"%s\"",
+ option_arg.str().c_str());
+ break;
+
+ case 'c':
+ if (option_arg.getAsInteger(0, num_instructions))
+ error.SetErrorStringWithFormat(
+ "invalid num of instructions string: \"%s\"",
+ option_arg.str().c_str());
+ break;
+
+ case 'b':
+ show_bytes = true;
+ break;
+
+ case 's': {
+ start_addr = Args::StringToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
+ if (start_addr != LLDB_INVALID_ADDRESS)
+ some_location_specified = true;
+ } break;
+ case 'e': {
+ end_addr = Args::StringToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
+ if (end_addr != LLDB_INVALID_ADDRESS)
+ some_location_specified = true;
+ } break;
+
+ case 'n':
+ func_name.assign(option_arg);
+ some_location_specified = true;
+ break;
+
+ case 'p':
+ at_pc = true;
+ some_location_specified = true;
+ break;
+
+ case 'l':
+ frame_line = true;
+ // Disassemble the current source line kind of implies showing mixed
+ // source code context.
+ show_mixed = true;
+ some_location_specified = true;
+ break;
+
+ case 'P':
+ plugin_name.assign(option_arg);
+ break;
+
+ case 'F': {
+ TargetSP target_sp =
+ execution_context ? execution_context->GetTargetSP() : TargetSP();
+ if (target_sp && (target_sp->GetArchitecture().GetTriple().getArch() ==
+ llvm::Triple::x86 ||
+ target_sp->GetArchitecture().GetTriple().getArch() ==
+ llvm::Triple::x86_64)) {
+ flavor_string.assign(option_arg);
+ } else
+ error.SetErrorStringWithFormat("Disassembler flavors are currently only "
+ "supported for x86 and x86_64 targets.");
+ break;
+ }
+
+ case 'r':
+ raw = true;
+ break;
+
+ case 'f':
+ current_function = true;
+ some_location_specified = true;
+ break;
+
+ case 'A':
+ if (execution_context) {
+ auto target_sp =
+ execution_context ? execution_context->GetTargetSP() : TargetSP();
+ auto platform_sp = target_sp ? target_sp->GetPlatform() : PlatformSP();
+ if (!arch.SetTriple(option_arg, platform_sp.get()))
+ arch.SetTriple(option_arg);
+ }
+ break;
- default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
- break;
+ case 'a': {
+ symbol_containing_addr = Args::StringToAddress(
+ execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
+ if (symbol_containing_addr != LLDB_INVALID_ADDRESS) {
+ some_location_specified = true;
}
+ } break;
- return error;
-}
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'",
+ short_option);
+ break;
+ }
-void
-CommandObjectDisassemble::CommandOptions::OptionParsingStarting ()
-{
- show_mixed = false;
- show_bytes = false;
- num_lines_context = 0;
- num_instructions = 0;
- func_name.clear();
- current_function = false;
- at_pc = false;
- frame_line = false;
- start_addr = LLDB_INVALID_ADDRESS;
- end_addr = LLDB_INVALID_ADDRESS;
- symbol_containing_addr = LLDB_INVALID_ADDRESS;
- raw = false;
- plugin_name.clear();
-
- Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
-
- // This is a hack till we get the ability to specify features based on architecture. For now GetDisassemblyFlavor
- // is really only valid for x86 (and for the llvm assembler plugin, but I'm papering over that since that is the
- // only disassembler plugin we have...
- if (target)
- {
- if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86
- || target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64)
- {
- flavor_string.assign(target->GetDisassemblyFlavor());
- }
- else
- flavor_string.assign ("default");
-
- }
- else
- flavor_string.assign("default");
-
- arch.Clear();
- some_location_specified = false;
+ return error;
}
-Error
-CommandObjectDisassemble::CommandOptions::OptionParsingFinished ()
-{
- if (!some_location_specified)
- current_function = true;
- return Error();
+void CommandObjectDisassemble::CommandOptions::OptionParsingStarting(
+ ExecutionContext *execution_context) {
+ show_mixed = false;
+ show_bytes = false;
+ num_lines_context = 0;
+ num_instructions = 0;
+ func_name.clear();
+ current_function = false;
+ at_pc = false;
+ frame_line = false;
+ start_addr = LLDB_INVALID_ADDRESS;
+ end_addr = LLDB_INVALID_ADDRESS;
+ symbol_containing_addr = LLDB_INVALID_ADDRESS;
+ raw = false;
+ plugin_name.clear();
+
+ Target *target =
+ execution_context ? execution_context->GetTargetPtr() : nullptr;
+
+ // This is a hack till we get the ability to specify features based on
+ // architecture. For now GetDisassemblyFlavor
+ // is really only valid for x86 (and for the llvm assembler plugin, but I'm
+ // papering over that since that is the
+ // only disassembler plugin we have...
+ if (target) {
+ if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86 ||
+ target->GetArchitecture().GetTriple().getArch() ==
+ llvm::Triple::x86_64) {
+ flavor_string.assign(target->GetDisassemblyFlavor());
+ } else
+ flavor_string.assign("default");
+
+ } else
+ flavor_string.assign("default");
+
+ arch.Clear();
+ some_location_specified = false;
}
-const OptionDefinition*
-CommandObjectDisassemble::CommandOptions::GetDefinitions ()
-{
- return g_option_table;
+Error CommandObjectDisassemble::CommandOptions::OptionParsingFinished(
+ ExecutionContext *execution_context) {
+ if (!some_location_specified)
+ current_function = true;
+ return Error();
}
-OptionDefinition
-CommandObjectDisassemble::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_ALL, false, "bytes" , 'b', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Show opcode bytes when disassembling."},
-{ LLDB_OPT_SET_ALL, false, "context" , 'C', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeNumLines, "Number of context lines of source to show."},
-{ LLDB_OPT_SET_ALL, false, "mixed" , 'm', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Enable mixed source and assembly display."},
-{ LLDB_OPT_SET_ALL, false, "raw" , 'r', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Print raw disassembly with no symbol information."},
-{ LLDB_OPT_SET_ALL, false, "plugin" , 'P', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."},
-{ LLDB_OPT_SET_ALL, false, "flavor" , 'F', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. "
- "Currently the only valid options are default, and for Intel"
- " architectures, att and intel."},
-{ LLDB_OPT_SET_ALL, false, "arch" , 'A', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."},
-{ LLDB_OPT_SET_1 |
- LLDB_OPT_SET_2 , true , "start-address", 's', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeAddressOrExpression,"Address at which to start disassembling."},
-{ LLDB_OPT_SET_1 , false, "end-address" , 'e', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling."},
-{ LLDB_OPT_SET_2 |
- LLDB_OPT_SET_3 |
- LLDB_OPT_SET_4 |
- LLDB_OPT_SET_5 , false, "count" , 'c', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeNumLines, "Number of instructions to display."},
-{ LLDB_OPT_SET_3 , false, "name" , 'n', OptionParser::eRequiredArgument , nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "Disassemble entire contents of the given function name."},
-{ LLDB_OPT_SET_4 , false, "frame" , 'f', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."},
-{ LLDB_OPT_SET_5 , false, "pc" , 'p', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Disassemble around the current pc."},
-{ LLDB_OPT_SET_6 , false, "line" , 'l', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line table information, else disassemble around the pc."},
-{ LLDB_OPT_SET_7 , false, "address" , 'a', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address."},
-{ 0 , false, nullptr , 0, 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
-};
+llvm::ArrayRef<OptionDefinition>
+CommandObjectDisassemble::CommandOptions::GetDefinitions() {
+ return llvm::makeArrayRef(g_disassemble_options);
+}
//-------------------------------------------------------------------------
// CommandObjectDisassemble
//-------------------------------------------------------------------------
-CommandObjectDisassemble::CommandObjectDisassemble(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "disassemble", "Disassemble specified instructions in the current target. "
- "Defaults to the current function for the current thread and "
- "stack frame.",
- "disassemble [<cmd-options>]"),
- m_options(interpreter)
-{
-}
+CommandObjectDisassemble::CommandObjectDisassemble(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "disassemble",
+ "Disassemble specified instructions in the current target. "
+ "Defaults to the current function for the current thread and "
+ "stack frame.",
+ "disassemble [<cmd-options>]"),
+ m_options() {}
CommandObjectDisassemble::~CommandObjectDisassemble() = default;
-bool
-CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
-{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
+bool CommandObjectDisassemble::DoExecute(Args &command,
+ CommandReturnObject &result) {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ if (!m_options.arch.IsValid())
+ m_options.arch = target->GetArchitecture();
+
+ if (!m_options.arch.IsValid()) {
+ result.AppendError(
+ "use the --arch option or set the target architecture to disassemble");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const char *plugin_name = m_options.GetPluginName();
+ const char *flavor_string = m_options.GetFlavorString();
+
+ DisassemblerSP disassembler =
+ Disassembler::FindPlugin(m_options.arch, flavor_string, plugin_name);
+
+ if (!disassembler) {
+ if (plugin_name) {
+ result.AppendErrorWithFormat(
+ "Unable to find Disassembler plug-in named '%s' that supports the "
+ "'%s' architecture.\n",
+ plugin_name, m_options.arch.GetArchitectureName());
+ } else
+ result.AppendErrorWithFormat(
+ "Unable to find Disassembler plug-in for the '%s' architecture.\n",
+ m_options.arch.GetArchitectureName());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (flavor_string != nullptr &&
+ !disassembler->FlavorValidForArchSpec(m_options.arch,
+ flavor_string))
+ result.AppendWarningWithFormat(
+ "invalid disassembler flavor \"%s\", using default.\n", flavor_string);
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ if (!command.empty()) {
+ result.AppendErrorWithFormat(
+ "\"disassemble\" arguments are specified as options.\n");
+ const int terminal_width =
+ GetCommandInterpreter().GetDebugger().GetTerminalWidth();
+ GetOptions()->GenerateOptionUsage(result.GetErrorStream(), this,
+ terminal_width);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_options.show_mixed && m_options.num_lines_context == 0)
+ m_options.num_lines_context = 2;
+
+ // Always show the PC in the disassembly
+ uint32_t options = Disassembler::eOptionMarkPCAddress;
+
+ // Mark the source line for the current PC only if we are doing mixed source
+ // and assembly
+ if (m_options.show_mixed)
+ options |= Disassembler::eOptionMarkPCSourceLine;
+
+ if (m_options.show_bytes)
+ options |= Disassembler::eOptionShowBytes;
+
+ if (m_options.raw)
+ options |= Disassembler::eOptionRawOuput;
+
+ if (!m_options.func_name.empty()) {
+ ConstString name(m_options.func_name.c_str());
+
+ if (Disassembler::Disassemble(
+ m_interpreter.GetDebugger(), m_options.arch, plugin_name,
+ flavor_string, m_exe_ctx, name,
+ nullptr, // Module *
+ m_options.num_instructions, m_options.show_mixed,
+ m_options.show_mixed ? m_options.num_lines_context : 0, options,
+ result.GetOutputStream())) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Unable to find symbol with name '%s'.\n",
+ name.GetCString());
+ result.SetStatus(eReturnStatusFailed);
}
- if (!m_options.arch.IsValid())
- m_options.arch = target->GetArchitecture();
-
- if (!m_options.arch.IsValid())
- {
- result.AppendError ("use the --arch option or set the target architecture to disassemble");
- result.SetStatus (eReturnStatusFailed);
+ } else {
+ std::vector<AddressRange> ranges;
+ AddressRange range;
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
+ if (m_options.frame_line) {
+ if (frame == nullptr) {
+ result.AppendError("Cannot disassemble around the current line without "
+ "a selected frame.\n");
+ result.SetStatus(eReturnStatusFailed);
return false;
- }
-
- const char *plugin_name = m_options.GetPluginName ();
- const char *flavor_string = m_options.GetFlavorString();
-
- DisassemblerSP disassembler = Disassembler::FindPlugin(m_options.arch, flavor_string, plugin_name);
-
- if (!disassembler)
- {
- if (plugin_name)
- {
- result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n",
- plugin_name,
- m_options.arch.GetArchitectureName());
- }
- else
- result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for the '%s' architecture.\n",
- m_options.arch.GetArchitectureName());
- result.SetStatus (eReturnStatusFailed);
+ }
+ LineEntry pc_line_entry(
+ frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
+ if (pc_line_entry.IsValid()) {
+ range = pc_line_entry.range;
+ } else {
+ m_options.at_pc =
+ true; // No line entry, so just disassemble around the current pc
+ m_options.show_mixed = false;
+ }
+ } else if (m_options.current_function) {
+ if (frame == nullptr) {
+ result.AppendError("Cannot disassemble around the current function "
+ "without a selected frame.\n");
+ result.SetStatus(eReturnStatusFailed);
return false;
+ }
+ Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
+ if (symbol) {
+ range.GetBaseAddress() = symbol->GetAddress();
+ range.SetByteSize(symbol->GetByteSize());
+ }
}
- else if (flavor_string != nullptr && !disassembler->FlavorValidForArchSpec(m_options.arch, flavor_string))
- result.AppendWarningWithFormat("invalid disassembler flavor \"%s\", using default.\n", flavor_string);
- result.SetStatus (eReturnStatusSuccessFinishResult);
-
- if (command.GetArgumentCount() != 0)
- {
- result.AppendErrorWithFormat ("\"disassemble\" arguments are specified as options.\n");
- GetOptions()->GenerateOptionUsage (result.GetErrorStream(), this);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- if (m_options.show_mixed && m_options.num_lines_context == 0)
- m_options.num_lines_context = 1;
-
- // Always show the PC in the disassembly
- uint32_t options = Disassembler::eOptionMarkPCAddress;
-
- // Mark the source line for the current PC only if we are doing mixed source and assembly
- if (m_options.show_mixed)
- options |= Disassembler::eOptionMarkPCSourceLine;
-
- if (m_options.show_bytes)
- options |= Disassembler::eOptionShowBytes;
-
- if (m_options.raw)
- options |= Disassembler::eOptionRawOuput;
-
- if (!m_options.func_name.empty())
- {
- ConstString name(m_options.func_name.c_str());
-
- if (Disassembler::Disassemble(m_interpreter.GetDebugger(),
- m_options.arch,
- plugin_name,
- flavor_string,
- m_exe_ctx,
- name,
- nullptr, // Module *
- m_options.num_instructions,
- m_options.show_mixed ? m_options.num_lines_context : 0,
- options,
- result.GetOutputStream()))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
+ // Did the "m_options.frame_line" find a valid range already? If so
+ // skip the rest...
+ if (range.GetByteSize() == 0) {
+ if (m_options.at_pc) {
+ if (frame == nullptr) {
+ result.AppendError("Cannot disassemble around the current PC without "
+ "a selected frame.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else
- {
- result.AppendErrorWithFormat ("Unable to find symbol with name '%s'.\n", name.GetCString());
- result.SetStatus (eReturnStatusFailed);
+ range.GetBaseAddress() = frame->GetFrameCodeAddress();
+ if (m_options.num_instructions == 0) {
+ // Disassembling at the PC always disassembles some number of
+ // instructions (not the whole function).
+ m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
}
- }
- else
- {
- std::vector<AddressRange> ranges;
- AddressRange range;
- StackFrame *frame = m_exe_ctx.GetFramePtr();
- if (m_options.frame_line)
- {
- if (frame == nullptr)
- {
- result.AppendError ("Cannot disassemble around the current line without a selected frame.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- LineEntry pc_line_entry (frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
- if (pc_line_entry.IsValid())
- {
- range = pc_line_entry.range;
+ ranges.push_back(range);
+ } else {
+ range.GetBaseAddress().SetOffset(m_options.start_addr);
+ if (range.GetBaseAddress().IsValid()) {
+ if (m_options.end_addr != LLDB_INVALID_ADDRESS) {
+ if (m_options.end_addr <= m_options.start_addr) {
+ result.AppendErrorWithFormat(
+ "End address before start address.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else
- {
- m_options.at_pc = true; // No line entry, so just disassemble around the current pc
- m_options.show_mixed = false;
- }
- }
- else if (m_options.current_function)
- {
- if (frame == nullptr)
- {
- result.AppendError ("Cannot disassemble around the current function without a selected frame.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
- if (symbol)
- {
- range.GetBaseAddress() = symbol->GetAddress();
- range.SetByteSize(symbol->GetByteSize());
- }
- }
-
- // Did the "m_options.frame_line" find a valid range already? If so
- // skip the rest...
- if (range.GetByteSize() == 0)
- {
- if (m_options.at_pc)
- {
- if (frame == nullptr)
- {
- result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ range.SetByteSize(m_options.end_addr - m_options.start_addr);
+ }
+ ranges.push_back(range);
+ } else {
+ if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS &&
+ target) {
+ if (!target->GetSectionLoadList().IsEmpty()) {
+ bool failed = false;
+ Address symbol_containing_address;
+ if (target->GetSectionLoadList().ResolveLoadAddress(
+ m_options.symbol_containing_addr,
+ symbol_containing_address)) {
+ ModuleSP module_sp(symbol_containing_address.GetModule());
+ SymbolContext sc;
+ bool resolve_tail_call_address = true; // PC can be one past the
+ // address range of the
+ // function.
+ module_sp->ResolveSymbolContextForAddress(
+ symbol_containing_address, eSymbolContextEverything, sc,
+ resolve_tail_call_address);
+ if (sc.function || sc.symbol) {
+ sc.GetAddressRange(eSymbolContextFunction |
+ eSymbolContextSymbol,
+ 0, false, range);
+ } else {
+ failed = true;
}
- range.GetBaseAddress() = frame->GetFrameCodeAddress();
- if (m_options.num_instructions == 0)
- {
- // Disassembling at the PC always disassembles some number of instructions (not the whole function).
- m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
- }
- ranges.push_back(range);
- }
- else
- {
- range.GetBaseAddress().SetOffset (m_options.start_addr);
- if (range.GetBaseAddress().IsValid())
- {
- if (m_options.end_addr != LLDB_INVALID_ADDRESS)
- {
- if (m_options.end_addr <= m_options.start_addr)
- {
- result.AppendErrorWithFormat ("End address before start address.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- range.SetByteSize (m_options.end_addr - m_options.start_addr);
- }
+ } else {
+ failed = true;
+ }
+ if (failed) {
+ result.AppendErrorWithFormat(
+ "Could not find function bounds for address 0x%" PRIx64
+ "\n",
+ m_options.symbol_containing_addr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ ranges.push_back(range);
+ } else {
+ for (lldb::ModuleSP module_sp : target->GetImages().Modules()) {
+ lldb::addr_t file_addr = m_options.symbol_containing_addr;
+ Address file_address;
+ if (module_sp->ResolveFileAddress(file_addr, file_address)) {
+ SymbolContext sc;
+ bool resolve_tail_call_address = true; // PC can be one past
+ // the address range of
+ // the function.
+ module_sp->ResolveSymbolContextForAddress(
+ file_address, eSymbolContextEverything, sc,
+ resolve_tail_call_address);
+ if (sc.function || sc.symbol) {
+ sc.GetAddressRange(eSymbolContextFunction |
+ eSymbolContextSymbol,
+ 0, false, range);
ranges.push_back(range);
+ }
}
- else
- {
- if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS
- && target)
- {
- if (!target->GetSectionLoadList().IsEmpty())
- {
- bool failed = false;
- Address symbol_containing_address;
- if (target->GetSectionLoadList().ResolveLoadAddress (m_options.symbol_containing_addr, symbol_containing_address))
- {
- ModuleSP module_sp (symbol_containing_address.GetModule());
- SymbolContext sc;
- bool resolve_tail_call_address = true; // PC can be one past the address range of the function.
- module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc,
- resolve_tail_call_address);
- if (sc.function || sc.symbol)
- {
- sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range);
- }
- else
- {
- failed = true;
- }
- }
- else
- {
- failed = true;
- }
- if (failed)
- {
- result.AppendErrorWithFormat ("Could not find function bounds for address 0x%" PRIx64 "\n", m_options.symbol_containing_addr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- ranges.push_back(range);
- }
- else
- {
- for (lldb::ModuleSP module_sp : target->GetImages().Modules())
- {
- lldb::addr_t file_addr = m_options.symbol_containing_addr;
- Address file_address;
- if (module_sp->ResolveFileAddress(file_addr, file_address))
- {
- SymbolContext sc;
- bool resolve_tail_call_address = true; // PC can be one past the address range of the function.
- module_sp->ResolveSymbolContextForAddress (file_address, eSymbolContextEverything, sc, resolve_tail_call_address);
- if (sc.function || sc.symbol)
- {
- sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range);
- ranges.push_back(range);
- }
- }
- }
- }
- }
- }
+ }
}
+ }
}
- else
- ranges.push_back(range);
-
- if (m_options.num_instructions != 0)
- {
- if (ranges.empty())
- {
- // The default action is to disassemble the current frame function.
- if (frame)
- {
- SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
- if (sc.function)
- range.GetBaseAddress() = sc.function->GetAddressRange().GetBaseAddress();
- else if (sc.symbol && sc.symbol->ValueIsAddress())
- range.GetBaseAddress() = sc.symbol->GetAddress();
- else
- range.GetBaseAddress() = frame->GetFrameCodeAddress();
- }
-
- if (!range.GetBaseAddress().IsValid())
- {
- result.AppendError ("invalid frame");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
-
- bool print_sc_header = ranges.size() > 1;
- for (AddressRange cur_range : ranges)
- {
- if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
- m_options.arch,
- plugin_name,
- flavor_string,
- m_exe_ctx,
- cur_range.GetBaseAddress(),
- m_options.num_instructions,
- m_options.show_mixed ? m_options.num_lines_context : 0,
- options,
- result.GetOutputStream()))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- if (m_options.start_addr != LLDB_INVALID_ADDRESS)
- result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr);
- else if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS)
- result.AppendErrorWithFormat ("Failed to disassemble memory in function at 0x%8.8" PRIx64 ".\n", m_options.symbol_containing_addr);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- if (print_sc_header)
- result.AppendMessage("\n");
+ }
+ } else
+ ranges.push_back(range);
+
+ if (m_options.num_instructions != 0) {
+ if (ranges.empty()) {
+ // The default action is to disassemble the current frame function.
+ if (frame) {
+ SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
+ eSymbolContextSymbol));
+ if (sc.function)
+ range.GetBaseAddress() =
+ sc.function->GetAddressRange().GetBaseAddress();
+ else if (sc.symbol && sc.symbol->ValueIsAddress())
+ range.GetBaseAddress() = sc.symbol->GetAddress();
+ else
+ range.GetBaseAddress() = frame->GetFrameCodeAddress();
}
- else
- {
- if (ranges.empty())
- {
- // The default action is to disassemble the current frame function.
- if (frame)
- {
- SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
- if (sc.function)
- range = sc.function->GetAddressRange();
- else if (sc.symbol && sc.symbol->ValueIsAddress())
- {
- range.GetBaseAddress() = sc.symbol->GetAddress();
- range.SetByteSize (sc.symbol->GetByteSize());
- }
- else
- range.GetBaseAddress() = frame->GetFrameCodeAddress();
- }
- else
- {
- result.AppendError ("invalid frame");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- ranges.push_back(range);
- }
-
- bool print_sc_header = ranges.size() > 1;
- for (AddressRange cur_range : ranges)
- {
- if (cur_range.GetByteSize() == 0)
- cur_range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
-
- if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
- m_options.arch,
- plugin_name,
- flavor_string,
- m_exe_ctx,
- cur_range,
- m_options.num_instructions,
- m_options.show_mixed ? m_options.num_lines_context : 0,
- options,
- result.GetOutputStream()))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr);
- result.SetStatus (eReturnStatusFailed);
- }
- if (print_sc_header)
- result.AppendMessage("\n");
- }
+
+ if (!range.GetBaseAddress().IsValid()) {
+ result.AppendError("invalid frame");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ bool print_sc_header = ranges.size() > 1;
+ for (AddressRange cur_range : ranges) {
+ if (Disassembler::Disassemble(
+ m_interpreter.GetDebugger(), m_options.arch, plugin_name,
+ flavor_string, m_exe_ctx, cur_range.GetBaseAddress(),
+ m_options.num_instructions, m_options.show_mixed,
+ m_options.show_mixed ? m_options.num_lines_context : 0, options,
+ result.GetOutputStream())) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ if (m_options.start_addr != LLDB_INVALID_ADDRESS)
+ result.AppendErrorWithFormat(
+ "Failed to disassemble memory at 0x%8.8" PRIx64 ".\n",
+ m_options.start_addr);
+ else if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS)
+ result.AppendErrorWithFormat(
+ "Failed to disassemble memory in function at 0x%8.8" PRIx64
+ ".\n",
+ m_options.symbol_containing_addr);
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+ if (print_sc_header)
+ result.AppendMessage("\n");
+ } else {
+ if (ranges.empty()) {
+ // The default action is to disassemble the current frame function.
+ if (frame) {
+ SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
+ eSymbolContextSymbol));
+ if (sc.function)
+ range = sc.function->GetAddressRange();
+ else if (sc.symbol && sc.symbol->ValueIsAddress()) {
+ range.GetBaseAddress() = sc.symbol->GetAddress();
+ range.SetByteSize(sc.symbol->GetByteSize());
+ } else
+ range.GetBaseAddress() = frame->GetFrameCodeAddress();
+ } else {
+ result.AppendError("invalid frame");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ ranges.push_back(range);
+ }
+
+ bool print_sc_header = ranges.size() > 1;
+ for (AddressRange cur_range : ranges) {
+ if (cur_range.GetByteSize() == 0)
+ cur_range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
+
+ if (Disassembler::Disassemble(
+ m_interpreter.GetDebugger(), m_options.arch, plugin_name,
+ flavor_string, m_exe_ctx, cur_range, m_options.num_instructions,
+ m_options.show_mixed,
+ m_options.show_mixed ? m_options.num_lines_context : 0, options,
+ result.GetOutputStream())) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat(
+ "Failed to disassemble memory at 0x%8.8" PRIx64 ".\n",
+ m_options.start_addr);
+ result.SetStatus(eReturnStatusFailed);
}
+ if (print_sc_header)
+ result.AppendMessage("\n");
+ }
}
+ }
- return result.Succeeded();
+ return result.Succeeded();
}
diff --git a/source/Commands/CommandObjectDisassemble.h b/source/Commands/CommandObjectDisassemble.h
index ef19b3cf316a..db89aa24d6a0 100644
--- a/source/Commands/CommandObjectDisassemble.h
+++ b/source/Commands/CommandObjectDisassemble.h
@@ -24,78 +24,64 @@ namespace lldb_private {
// CommandObjectDisassemble
//-------------------------------------------------------------------------
-class CommandObjectDisassemble : public CommandObjectParsed
-{
+class CommandObjectDisassemble : public CommandObjectParsed {
public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter);
-
- ~CommandOptions() override;
-
- Error
- SetOptionValue(uint32_t option_idx, const char *option_arg) override;
-
- void
- OptionParsingStarting() override;
-
- const OptionDefinition*
- GetDefinitions() override;
-
- const char *
- GetPluginName ()
- {
- return (plugin_name.empty() ? nullptr : plugin_name.c_str());
- }
-
- const char *
- GetFlavorString ()
- {
- if (flavor_string.empty() || flavor_string == "default")
- return nullptr;
- return flavor_string.c_str();
- }
-
- Error
- OptionParsingFinished() override;
-
- bool show_mixed; // Show mixed source/assembly
- bool show_bytes;
- uint32_t num_lines_context;
- uint32_t num_instructions;
- bool raw;
- std::string func_name;
- bool current_function;
- lldb::addr_t start_addr;
- lldb::addr_t end_addr;
- bool at_pc;
- bool frame_line;
- std::string plugin_name;
- std::string flavor_string;
- ArchSpec arch;
- bool some_location_specified; // If no location was specified, we'll select "at_pc". This should be set
- // in SetOptionValue if anything the selects a location is set.
- lldb::addr_t symbol_containing_addr;
- static OptionDefinition g_option_table[];
- };
-
- CommandObjectDisassemble (CommandInterpreter &interpreter);
-
- ~CommandObjectDisassemble() override;
-
- Options *
- GetOptions() override
- {
- return &m_options;
+ class CommandOptions : public Options {
+ public:
+ CommandOptions();
+
+ ~CommandOptions() override;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ const char *GetPluginName() {
+ return (plugin_name.empty() ? nullptr : plugin_name.c_str());
+ }
+
+ const char *GetFlavorString() {
+ if (flavor_string.empty() || flavor_string == "default")
+ return nullptr;
+ return flavor_string.c_str();
}
+ Error OptionParsingFinished(ExecutionContext *execution_context) override;
+
+ bool show_mixed; // Show mixed source/assembly
+ bool show_bytes;
+ uint32_t num_lines_context;
+ uint32_t num_instructions;
+ bool raw;
+ std::string func_name;
+ bool current_function;
+ lldb::addr_t start_addr;
+ lldb::addr_t end_addr;
+ bool at_pc;
+ bool frame_line;
+ std::string plugin_name;
+ std::string flavor_string;
+ ArchSpec arch;
+ bool some_location_specified; // If no location was specified, we'll select
+ // "at_pc". This should be set
+ // in SetOptionValue if anything the selects a location is set.
+ lldb::addr_t symbol_containing_addr;
+ static OptionDefinition g_option_table[];
+ };
+
+ CommandObjectDisassemble(CommandInterpreter &interpreter);
+
+ ~CommandObjectDisassemble() override;
+
+ Options *GetOptions() override { return &m_options; }
+
protected:
- bool
- DoExecute(Args& command,
- CommandReturnObject &result) override;
+ bool DoExecute(Args &command, CommandReturnObject &result) override;
- CommandOptions m_options;
+ CommandOptions m_options;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index f2bd3ed367ca..cfb3a6dd5117 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -15,21 +15,21 @@
// Project includes
#include "CommandObjectExpression.h"
+#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
-#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
-#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Expression/REPL.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Target/Language.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Variable.h"
+#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
@@ -38,627 +38,603 @@
using namespace lldb;
using namespace lldb_private;
-CommandObjectExpression::CommandOptions::CommandOptions () :
- OptionGroup()
-{
-}
+CommandObjectExpression::CommandOptions::CommandOptions() : OptionGroup() {}
CommandObjectExpression::CommandOptions::~CommandOptions() = default;
-static OptionEnumValueElement g_description_verbosity_type[] =
-{
- { eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"},
- { eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", "Show the full output, including persistent variable's name and type"},
- { 0, nullptr, nullptr }
-};
-
-OptionDefinition
-CommandObjectExpression::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language setting is used." },
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "If true, simple fix-it hints will be automatically applied to the expression." },
- { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level", 'p', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "Interpret the expression as top-level definitions rather than code to be immediately executed."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "allow-jit", 'j', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Controls whether the expression can fall back to being JITted if it's not supported by the interpreter (defaults to true)."}
+static OptionEnumValueElement g_description_verbosity_type[] = {
+ {eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact",
+ "Only show the description string"},
+ {eLanguageRuntimeDescriptionDisplayVerbosityFull, "full",
+ "Show the full output, including persistent variable's name and type"},
+ {0, nullptr, nullptr}};
+
+static OptionDefinition g_expression_options[] = {
+ // clang-format off
+ {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."},
+ {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
+ {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."},
+ {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. "
+ "Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
+ {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction "
+ "and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
+ {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language "
+ "setting is used." },
+ {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "If true, simple fix-it hints will be automatically applied to the expression." },
+ {LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."},
+ {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Interpret the expression as a complete translation unit, without injecting it into the local "
+ "context. Allows declaration of persistent, top-level entities without a $ prefix."},
+ {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "allow-jit", 'j', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Controls whether the expression can fall back to being JITted if it's not supported by "
+ "the interpreter (defaults to true)."}
+ // clang-format on
};
-uint32_t
-CommandObjectExpression::CommandOptions::GetNumDefinitions ()
-{
- return llvm::array_lengthof(g_option_table);
-}
-
-Error
-CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg)
-{
- Error error;
-
- const int short_option = g_option_table[option_idx].short_option;
-
- switch (short_option)
- {
- case 'l':
- language = Language::GetLanguageTypeFromString (option_arg);
- if (language == eLanguageTypeUnknown)
- error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", option_arg);
- break;
-
- case 'a':
- {
- bool success;
- bool result;
- result = Args::StringToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
- else
- try_all_threads = result;
- }
- break;
-
- case 'i':
- {
- bool success;
- bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
- if (success)
- ignore_breakpoints = tmp_value;
- else
- error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
- break;
- }
-
- case 'j':
- {
- bool success;
- bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
- if (success)
- allow_jit = tmp_value;
- else
- error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
- break;
- }
-
- case 't':
- {
- bool success;
- uint32_t result;
- result = StringConvert::ToUInt32(option_arg, 0, 0, &success);
- if (success)
- timeout = result;
- else
- error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
- }
- break;
-
- case 'u':
- {
- bool success;
- bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
- if (success)
- unwind_on_error = tmp_value;
- else
- error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
- break;
- }
-
- case 'v':
- if (!option_arg)
- {
- m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
- break;
- }
- m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
- if (!error.Success())
- error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
- break;
-
- case 'g':
- debug = true;
- unwind_on_error = false;
- ignore_breakpoints = false;
- break;
-
- case 'p':
- top_level = true;
- break;
-
- case 'X':
- {
- bool success;
- bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
- if (success)
- auto_apply_fixits = tmp_value ? eLazyBoolYes : eLazyBoolNo;
- else
- error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
- break;
- }
-
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
+Error CommandObjectExpression::CommandOptions::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Error error;
+
+ const int short_option = GetDefinitions()[option_idx].short_option;
+
+ switch (short_option) {
+ case 'l':
+ language = Language::GetLanguageTypeFromString(option_arg);
+ if (language == eLanguageTypeUnknown)
+ error.SetErrorStringWithFormat(
+ "unknown language type: '%s' for expression",
+ option_arg.str().c_str());
+ break;
+
+ case 'a': {
+ bool success;
+ bool result;
+ result = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid all-threads value setting: \"%s\"",
+ option_arg.str().c_str());
+ else
+ try_all_threads = result;
+ } break;
+
+ case 'i': {
+ bool success;
+ bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ if (success)
+ ignore_breakpoints = tmp_value;
+ else
+ error.SetErrorStringWithFormat(
+ "could not convert \"%s\" to a boolean value.",
+ option_arg.str().c_str());
+ break;
+ }
+
+ case 'j': {
+ bool success;
+ bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ if (success)
+ allow_jit = tmp_value;
+ else
+ error.SetErrorStringWithFormat(
+ "could not convert \"%s\" to a boolean value.",
+ option_arg.str().c_str());
+ break;
+ }
+
+ case 't':
+ if (option_arg.getAsInteger(0, timeout)) {
+ timeout = 0;
+ error.SetErrorStringWithFormat("invalid timeout setting \"%s\"",
+ option_arg.str().c_str());
}
+ break;
- return error;
-}
-
-void
-CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
-{
- Process *process = interpreter.GetExecutionContext().GetProcessPtr();
- if (process != nullptr)
- {
- ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
- unwind_on_error = process->GetUnwindOnErrorInExpressions();
- }
+ case 'u': {
+ bool success;
+ bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ if (success)
+ unwind_on_error = tmp_value;
else
- {
- ignore_breakpoints = true;
- unwind_on_error = true;
+ error.SetErrorStringWithFormat(
+ "could not convert \"%s\" to a boolean value.",
+ option_arg.str().c_str());
+ break;
+ }
+
+ case 'v':
+ if (option_arg.empty()) {
+ m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
+ break;
}
-
- show_summary = true;
- try_all_threads = true;
- timeout = 0;
- debug = false;
- language = eLanguageTypeUnknown;
- m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
- auto_apply_fixits = eLazyBoolCalculate;
- top_level = false;
- allow_jit = true;
+ m_verbosity =
+ (LanguageRuntimeDescriptionDisplayVerbosity)Args::StringToOptionEnum(
+ option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
+ if (!error.Success())
+ error.SetErrorStringWithFormat(
+ "unrecognized value for description-verbosity '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'g':
+ debug = true;
+ unwind_on_error = false;
+ ignore_breakpoints = false;
+ break;
+
+ case 'p':
+ top_level = true;
+ break;
+
+ case 'X': {
+ bool success;
+ bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ if (success)
+ auto_apply_fixits = tmp_value ? eLazyBoolYes : eLazyBoolNo;
+ else
+ error.SetErrorStringWithFormat(
+ "could not convert \"%s\" to a boolean value.",
+ option_arg.str().c_str());
+ break;
+ }
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+}
+
+void CommandObjectExpression::CommandOptions::OptionParsingStarting(
+ ExecutionContext *execution_context) {
+ auto process_sp =
+ execution_context ? execution_context->GetProcessSP() : ProcessSP();
+ if (process_sp) {
+ ignore_breakpoints = process_sp->GetIgnoreBreakpointsInExpressions();
+ unwind_on_error = process_sp->GetUnwindOnErrorInExpressions();
+ } else {
+ ignore_breakpoints = true;
+ unwind_on_error = true;
+ }
+
+ show_summary = true;
+ try_all_threads = true;
+ timeout = 0;
+ debug = false;
+ language = eLanguageTypeUnknown;
+ m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
+ auto_apply_fixits = eLazyBoolCalculate;
+ top_level = false;
+ allow_jit = true;
}
-const OptionDefinition*
-CommandObjectExpression::CommandOptions::GetDefinitions ()
-{
- return g_option_table;
+llvm::ArrayRef<OptionDefinition>
+CommandObjectExpression::CommandOptions::GetDefinitions() {
+ return llvm::makeArrayRef(g_expression_options);
}
-CommandObjectExpression::CommandObjectExpression(CommandInterpreter &interpreter)
+CommandObjectExpression::CommandObjectExpression(
+ CommandInterpreter &interpreter)
: CommandObjectRaw(
- interpreter, "expression",
- "Evaluate an expression on the current thread. Displays any returned value with LLDB's default formatting.",
- nullptr, eCommandProcessMustBePaused | eCommandTryTargetAPILock),
+ interpreter, "expression", "Evaluate an expression on the current "
+ "thread. Displays any returned value "
+ "with LLDB's default formatting.",
+ "", eCommandProcessMustBePaused | eCommandTryTargetAPILock),
IOHandlerDelegate(IOHandlerDelegate::Completion::Expression),
- m_option_group(interpreter),
- m_format_options(eFormatDefault),
- m_repl_option(LLDB_OPT_SET_1, false, "repl", 'r', "Drop into REPL", false, true),
- m_command_options(),
- m_expr_line_count(0),
- m_expr_lines()
-{
- SetHelpLong(
-R"(
+ m_option_group(), m_format_options(eFormatDefault),
+ m_repl_option(LLDB_OPT_SET_1, false, "repl", 'r', "Drop into REPL", false,
+ true),
+ m_command_options(), m_expr_line_count(0), m_expr_lines() {
+ SetHelpLong(
+ R"(
Timeouts:
-)" " If the expression can be evaluated statically (without running code) then it will be. \
+)"
+ " If the expression can be evaluated statically (without running code) then it will be. \
Otherwise, by default the expression will run on the current thread with a short timeout: \
currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted \
and resumed with all threads running. You can use the -a option to disable retrying on all \
-threads. You can use the -t option to set a shorter timeout." R"(
+threads. You can use the -t option to set a shorter timeout."
+ R"(
User defined variables:
-)" " You can define your own variables for convenience or to be used in subsequent expressions. \
+)"
+ " You can define your own variables for convenience or to be used in subsequent expressions. \
You define them the same way you would define variables in C. If the first character of \
your user defined variable is a $, then the variable's value will be available in future \
-expressions, otherwise it will just be available in the current expression." R"(
+expressions, otherwise it will just be available in the current expression."
+ R"(
Continuing evaluation after a breakpoint:
-)" " If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \
+)"
+ " If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \
you are done with your investigation, you can either remove the expression execution frames \
from the stack with \"thread return -x\" or if you are still interested in the expression result \
you can issue the \"continue\" command and the expression evaluation will complete and the \
expression result will be available using the \"thread.completed-expression\" key in the thread \
-format." R"(
+format."
+ R"(
Examples:
expr my_struct->a = my_array[3]
expr -f bin -- (index * 8) + 5
expr unsigned int $foo = 5
- expr char c[] = \"foo\"; c[0])"
- );
-
- CommandArgumentEntry arg;
- CommandArgumentData expression_arg;
-
- // Define the first (and only) variant of this arg.
- expression_arg.arg_type = eArgTypeExpression;
- expression_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (expression_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
-
- // Add the "--format" and "--gdb-format"
- m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
- m_option_group.Append (&m_command_options);
- m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
- m_option_group.Append (&m_repl_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
- m_option_group.Finalize();
+ expr char c[] = \"foo\"; c[0])");
+
+ CommandArgumentEntry arg;
+ CommandArgumentData expression_arg;
+
+ // Define the first (and only) variant of this arg.
+ expression_arg.arg_type = eArgTypeExpression;
+ expression_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the argument
+ // entry.
+ arg.push_back(expression_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+
+ // Add the "--format" and "--gdb-format"
+ m_option_group.Append(&m_format_options,
+ OptionGroupFormat::OPTION_GROUP_FORMAT |
+ OptionGroupFormat::OPTION_GROUP_GDB_FMT,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_command_options);
+ m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
+ m_option_group.Append(&m_repl_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
+ m_option_group.Finalize();
}
CommandObjectExpression::~CommandObjectExpression() = default;
-Options *
-CommandObjectExpression::GetOptions ()
-{
- return &m_option_group;
-}
+Options *CommandObjectExpression::GetOptions() { return &m_option_group; }
static lldb_private::Error
-CanBeUsedForElementCountPrinting (ValueObject& valobj)
-{
- CompilerType type(valobj.GetCompilerType());
- CompilerType pointee;
- if (!type.IsPointerType(&pointee))
- return Error("as it does not refer to a pointer");
- if (pointee.IsVoidType())
- return Error("as it refers to a pointer to void");
- return Error();
+CanBeUsedForElementCountPrinting(ValueObject &valobj) {
+ CompilerType type(valobj.GetCompilerType());
+ CompilerType pointee;
+ if (!type.IsPointerType(&pointee))
+ return Error("as it does not refer to a pointer");
+ if (pointee.IsVoidType())
+ return Error("as it refers to a pointer to void");
+ return Error();
}
-bool
-CommandObjectExpression::EvaluateExpression(const char *expr,
- Stream *output_stream,
- Stream *error_stream,
- CommandReturnObject *result)
-{
- // Don't use m_exe_ctx as this might be called asynchronously
- // after the command object DoExecute has finished when doing
- // multi-line expression that use an input reader...
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
-
- Target *target = exe_ctx.GetTargetPtr();
-
- if (!target)
- target = GetDummyTarget();
-
- if (target)
- {
- lldb::ValueObjectSP result_valobj_sp;
- bool keep_in_memory = true;
- StackFrame *frame = exe_ctx.GetFramePtr();
-
- EvaluateExpressionOptions options;
- options.SetCoerceToId(m_varobj_options.use_objc);
- options.SetUnwindOnError(m_command_options.unwind_on_error);
- options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
- options.SetKeepInMemory(keep_in_memory);
- options.SetUseDynamic(m_varobj_options.use_dynamic);
- options.SetTryAllThreads(m_command_options.try_all_threads);
- options.SetDebug(m_command_options.debug);
- options.SetLanguage(m_command_options.language);
- options.SetExecutionPolicy(m_command_options.allow_jit ?
- EvaluateExpressionOptions::default_execution_policy :
- lldb_private::eExecutionPolicyNever);
-
- bool auto_apply_fixits;
- if (m_command_options.auto_apply_fixits == eLazyBoolCalculate)
- auto_apply_fixits = target->GetEnableAutoApplyFixIts();
- else
- auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes ? true : false;
-
- options.SetAutoApplyFixIts(auto_apply_fixits);
-
- if (m_command_options.top_level)
- options.SetExecutionPolicy(eExecutionPolicyTopLevel);
-
- // If there is any chance we are going to stop and want to see
- // what went wrong with our expression, we should generate debug info
- if (!m_command_options.ignore_breakpoints ||
- !m_command_options.unwind_on_error)
- options.SetGenerateDebugInfo(true);
-
- if (m_command_options.timeout > 0)
- options.SetTimeoutUsec(m_command_options.timeout);
- else
- options.SetTimeoutUsec(0);
-
- ExpressionResults success = target->EvaluateExpression(expr, frame, result_valobj_sp, options, &m_fixed_expression);
-
- // We only tell you about the FixIt if we applied it. The compiler errors will suggest the FixIt if it parsed.
- if (error_stream && !m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts())
- {
- if (success == eExpressionCompleted)
- error_stream->Printf (" Fix-it applied, fixed expression was: \n %s\n", m_fixed_expression.c_str());
- }
+bool CommandObjectExpression::EvaluateExpression(const char *expr,
+ Stream *output_stream,
+ Stream *error_stream,
+ CommandReturnObject *result) {
+ // Don't use m_exe_ctx as this might be called asynchronously
+ // after the command object DoExecute has finished when doing
+ // multi-line expression that use an input reader...
+ ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
+
+ Target *target = exe_ctx.GetTargetPtr();
+
+ if (!target)
+ target = GetDummyTarget();
+
+ if (target) {
+ lldb::ValueObjectSP result_valobj_sp;
+ bool keep_in_memory = true;
+ StackFrame *frame = exe_ctx.GetFramePtr();
+
+ EvaluateExpressionOptions options;
+ options.SetCoerceToId(m_varobj_options.use_objc);
+ options.SetUnwindOnError(m_command_options.unwind_on_error);
+ options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints);
+ options.SetKeepInMemory(keep_in_memory);
+ options.SetUseDynamic(m_varobj_options.use_dynamic);
+ options.SetTryAllThreads(m_command_options.try_all_threads);
+ options.SetDebug(m_command_options.debug);
+ options.SetLanguage(m_command_options.language);
+ options.SetExecutionPolicy(
+ m_command_options.allow_jit
+ ? EvaluateExpressionOptions::default_execution_policy
+ : lldb_private::eExecutionPolicyNever);
+
+ bool auto_apply_fixits;
+ if (m_command_options.auto_apply_fixits == eLazyBoolCalculate)
+ auto_apply_fixits = target->GetEnableAutoApplyFixIts();
+ else
+ auto_apply_fixits =
+ m_command_options.auto_apply_fixits == eLazyBoolYes ? true : false;
- if (result_valobj_sp)
- {
- Format format = m_format_options.GetFormat();
-
- if (result_valobj_sp->GetError().Success())
- {
- if (format != eFormatVoid)
- {
- if (format != eFormatDefault)
- result_valobj_sp->SetFormat (format);
-
- if (m_varobj_options.elem_count > 0)
- {
- Error error(CanBeUsedForElementCountPrinting(*result_valobj_sp));
- if (error.Fail())
- {
- result->AppendErrorWithFormat("expression cannot be used with --element-count %s\n", error.AsCString(""));
- result->SetStatus(eReturnStatusFailed);
- return false;
- }
- }
-
- DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
- options.SetVariableFormatDisplayLanguage(result_valobj_sp->GetPreferredDisplayLanguage());
-
- result_valobj_sp->Dump(*output_stream,options);
-
- if (result)
- result->SetStatus (eReturnStatusSuccessFinishResult);
- }
- }
- else
- {
- if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult)
- {
- if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
- {
- error_stream->PutCString("(void)\n");
- }
-
- if (result)
- result->SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- const char *error_cstr = result_valobj_sp->GetError().AsCString();
- if (error_cstr && error_cstr[0])
- {
- const size_t error_cstr_len = strlen (error_cstr);
- const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
- if (strstr(error_cstr, "error:") != error_cstr)
- error_stream->PutCString ("error: ");
- error_stream->Write(error_cstr, error_cstr_len);
- if (!ends_with_newline)
- error_stream->EOL();
- }
- else
- {
- error_stream->PutCString ("error: unknown error\n");
- }
-
- if (result)
- result->SetStatus (eReturnStatusFailed);
- }
- }
- }
- }
+ options.SetAutoApplyFixIts(auto_apply_fixits);
+
+ if (m_command_options.top_level)
+ options.SetExecutionPolicy(eExecutionPolicyTopLevel);
+
+ // If there is any chance we are going to stop and want to see
+ // what went wrong with our expression, we should generate debug info
+ if (!m_command_options.ignore_breakpoints ||
+ !m_command_options.unwind_on_error)
+ options.SetGenerateDebugInfo(true);
+
+ if (m_command_options.timeout > 0)
+ options.SetTimeout(std::chrono::microseconds(m_command_options.timeout));
else
- {
- error_stream->Printf ("error: invalid execution context for expression\n");
- return false;
+ options.SetTimeout(llvm::None);
+
+ ExpressionResults success = target->EvaluateExpression(
+ expr, frame, result_valobj_sp, options, &m_fixed_expression);
+
+ // We only tell you about the FixIt if we applied it. The compiler errors
+ // will suggest the FixIt if it parsed.
+ if (error_stream && !m_fixed_expression.empty() &&
+ target->GetEnableNotifyAboutFixIts()) {
+ if (success == eExpressionCompleted)
+ error_stream->Printf(
+ " Fix-it applied, fixed expression was: \n %s\n",
+ m_fixed_expression.c_str());
}
-
- return true;
-}
-void
-CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
-{
- io_handler.SetIsDone(true);
-// StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
-// StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- StreamFileSP error_sp(io_handler.GetErrorStreamFile());
-
- EvaluateExpression (line.c_str(),
- output_sp.get(),
- error_sp.get());
- if (output_sp)
- output_sp->Flush();
- if (error_sp)
- error_sp->Flush();
-}
+ if (result_valobj_sp) {
+ Format format = m_format_options.GetFormat();
+
+ if (result_valobj_sp->GetError().Success()) {
+ if (format != eFormatVoid) {
+ if (format != eFormatDefault)
+ result_valobj_sp->SetFormat(format);
+
+ if (m_varobj_options.elem_count > 0) {
+ Error error(CanBeUsedForElementCountPrinting(*result_valobj_sp));
+ if (error.Fail()) {
+ result->AppendErrorWithFormat(
+ "expression cannot be used with --element-count %s\n",
+ error.AsCString(""));
+ result->SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
+ m_command_options.m_verbosity, format));
+ options.SetVariableFormatDisplayLanguage(
+ result_valobj_sp->GetPreferredDisplayLanguage());
+
+ result_valobj_sp->Dump(*output_stream, options);
-bool
-CommandObjectExpression::IOHandlerIsInputComplete (IOHandler &io_handler,
- StringList &lines)
-{
- // An empty lines is used to indicate the end of input
- const size_t num_lines = lines.GetSize();
- if (num_lines > 0 && lines[num_lines - 1].empty())
- {
- // Remove the last empty line from "lines" so it doesn't appear
- // in our resulting input and return true to indicate we are done
- // getting lines
- lines.PopBack();
- return true;
+ if (result)
+ result->SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ } else {
+ if (result_valobj_sp->GetError().GetError() ==
+ UserExpression::kNoResult) {
+ if (format != eFormatVoid &&
+ m_interpreter.GetDebugger().GetNotifyVoid()) {
+ error_stream->PutCString("(void)\n");
+ }
+
+ if (result)
+ result->SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ const char *error_cstr = result_valobj_sp->GetError().AsCString();
+ if (error_cstr && error_cstr[0]) {
+ const size_t error_cstr_len = strlen(error_cstr);
+ const bool ends_with_newline =
+ error_cstr[error_cstr_len - 1] == '\n';
+ if (strstr(error_cstr, "error:") != error_cstr)
+ error_stream->PutCString("error: ");
+ error_stream->Write(error_cstr, error_cstr_len);
+ if (!ends_with_newline)
+ error_stream->EOL();
+ } else {
+ error_stream->PutCString("error: unknown error\n");
+ }
+
+ if (result)
+ result->SetStatus(eReturnStatusFailed);
+ }
+ }
}
+ } else {
+ error_stream->Printf("error: invalid execution context for expression\n");
return false;
+ }
+
+ return true;
}
-void
-CommandObjectExpression::GetMultilineExpression ()
-{
- m_expr_lines.clear();
- m_expr_line_count = 0;
-
- Debugger &debugger = GetCommandInterpreter().GetDebugger();
- bool color_prompt = debugger.GetUseColor();
- const bool multiple_lines = true; // Get multiple lines
- IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
- IOHandler::Type::Expression,
- "lldb-expr", // Name of input reader for history
- nullptr, // No prompt
- nullptr, // Continuation prompt
- multiple_lines,
- color_prompt,
- 1, // Show line numbers starting at 1
- *this));
-
- StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
- if (output_sp)
- {
- output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
- output_sp->Flush();
- }
- debugger.PushIOHandler(io_handler_sp);
+void CommandObjectExpression::IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &line) {
+ io_handler.SetIsDone(true);
+ // StreamSP output_stream =
+ // io_handler.GetDebugger().GetAsyncOutputStream();
+ // StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ StreamFileSP error_sp(io_handler.GetErrorStreamFile());
+
+ EvaluateExpression(line.c_str(), output_sp.get(), error_sp.get());
+ if (output_sp)
+ output_sp->Flush();
+ if (error_sp)
+ error_sp->Flush();
}
-bool
-CommandObjectExpression::DoExecute(const char *command,
- CommandReturnObject &result)
-{
- m_fixed_expression.clear();
- m_option_group.NotifyOptionParsingStarting();
+bool CommandObjectExpression::IOHandlerIsInputComplete(IOHandler &io_handler,
+ StringList &lines) {
+ // An empty lines is used to indicate the end of input
+ const size_t num_lines = lines.GetSize();
+ if (num_lines > 0 && lines[num_lines - 1].empty()) {
+ // Remove the last empty line from "lines" so it doesn't appear
+ // in our resulting input and return true to indicate we are done
+ // getting lines
+ lines.PopBack();
+ return true;
+ }
+ return false;
+}
- const char * expr = nullptr;
+void CommandObjectExpression::GetMultilineExpression() {
+ m_expr_lines.clear();
+ m_expr_line_count = 0;
+
+ Debugger &debugger = GetCommandInterpreter().GetDebugger();
+ bool color_prompt = debugger.GetUseColor();
+ const bool multiple_lines = true; // Get multiple lines
+ IOHandlerSP io_handler_sp(
+ new IOHandlerEditline(debugger, IOHandler::Type::Expression,
+ "lldb-expr", // Name of input reader for history
+ llvm::StringRef(), // No prompt
+ llvm::StringRef(), // Continuation prompt
+ multiple_lines, color_prompt,
+ 1, // Show line numbers starting at 1
+ *this));
+
+ StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
+ if (output_sp) {
+ output_sp->PutCString(
+ "Enter expressions, then terminate with an empty line to evaluate:\n");
+ output_sp->Flush();
+ }
+ debugger.PushIOHandler(io_handler_sp);
+}
- if (command[0] == '\0')
- {
- GetMultilineExpression ();
- return result.Succeeded();
+bool CommandObjectExpression::DoExecute(const char *command,
+ CommandReturnObject &result) {
+ m_fixed_expression.clear();
+ auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
+ m_option_group.NotifyOptionParsingStarting(&exe_ctx);
+
+ const char *expr = nullptr;
+
+ if (command[0] == '\0') {
+ GetMultilineExpression();
+ return result.Succeeded();
+ }
+
+ if (command[0] == '-') {
+ // We have some options and these options MUST end with --.
+ const char *end_options = nullptr;
+ const char *s = command;
+ while (s && s[0]) {
+ end_options = ::strstr(s, "--");
+ if (end_options) {
+ end_options += 2; // Get past the "--"
+ if (::isspace(end_options[0])) {
+ expr = end_options;
+ while (::isspace(*expr))
+ ++expr;
+ break;
+ }
+ }
+ s = end_options;
}
- if (command[0] == '-')
- {
- // We have some options and these options MUST end with --.
- const char *end_options = nullptr;
- const char *s = command;
- while (s && s[0])
- {
- end_options = ::strstr (s, "--");
- if (end_options)
- {
- end_options += 2; // Get past the "--"
- if (::isspace (end_options[0]))
- {
- expr = end_options;
- while (::isspace (*expr))
- ++expr;
- break;
- }
- }
- s = end_options;
- }
+ if (end_options) {
+ Args args(llvm::StringRef(command, end_options - command));
+ if (!ParseOptions(args, result))
+ return false;
- if (end_options)
- {
- Args args (llvm::StringRef(command, end_options - command));
- if (!ParseOptions (args, result))
- return false;
-
- Error error (m_option_group.NotifyOptionParsingFinished());
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- if (m_repl_option.GetOptionValue().GetCurrentValue())
- {
- Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
- if (target)
- {
- // Drop into REPL
- m_expr_lines.clear();
- m_expr_line_count = 0;
-
- Debugger &debugger = target->GetDebugger();
-
- // Check if the LLDB command interpreter is sitting on top of a REPL that
- // launched it...
- if (debugger.CheckTopIOHandlerTypes(IOHandler::Type::CommandInterpreter, IOHandler::Type::REPL))
- {
- // the LLDB command interpreter is sitting on top of a REPL that launched it,
- // so just say the command interpreter is done and fall back to the existing REPL
- m_interpreter.GetIOHandler(false)->SetIsDone(true);
- }
- else
- {
- // We are launching the REPL on top of the current LLDB command interpreter,
- // so just push one
- bool initialize = false;
- Error repl_error;
- REPLSP repl_sp (target->GetREPL(repl_error, m_command_options.language, nullptr, false));
-
- if (!repl_sp)
- {
- initialize = true;
- repl_sp = target->GetREPL(repl_error, m_command_options.language, nullptr, true);
- if (!repl_error.Success())
- {
- result.SetError(repl_error);
- return result.Succeeded();
- }
- }
-
- if (repl_sp)
- {
- if (initialize)
- {
- repl_sp->SetCommandOptions(m_command_options);
- repl_sp->SetFormatOptions(m_format_options);
- repl_sp->SetValueObjectDisplayOptions(m_varobj_options);
- }
-
- IOHandlerSP io_handler_sp (repl_sp->GetIOHandler());
-
- io_handler_sp->SetIsDone(false);
-
- debugger.PushIOHandler(io_handler_sp);
- }
- else
- {
- repl_error.SetErrorStringWithFormat("Couldn't create a REPL for %s", Language::GetNameForLanguageType(m_command_options.language));
- result.SetError(repl_error);
- return result.Succeeded();
- }
- }
- }
- }
- // No expression following options
- else if (expr == nullptr || expr[0] == '\0')
- {
- GetMultilineExpression ();
+ Error error(m_option_group.NotifyOptionParsingFinished(&exe_ctx));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_repl_option.GetOptionValue().GetCurrentValue()) {
+ Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
+ if (target) {
+ // Drop into REPL
+ m_expr_lines.clear();
+ m_expr_line_count = 0;
+
+ Debugger &debugger = target->GetDebugger();
+
+ // Check if the LLDB command interpreter is sitting on top of a REPL
+ // that
+ // launched it...
+ if (debugger.CheckTopIOHandlerTypes(
+ IOHandler::Type::CommandInterpreter, IOHandler::Type::REPL)) {
+ // the LLDB command interpreter is sitting on top of a REPL that
+ // launched it,
+ // so just say the command interpreter is done and fall back to the
+ // existing REPL
+ m_interpreter.GetIOHandler(false)->SetIsDone(true);
+ } else {
+ // We are launching the REPL on top of the current LLDB command
+ // interpreter,
+ // so just push one
+ bool initialize = false;
+ Error repl_error;
+ REPLSP repl_sp(target->GetREPL(
+ repl_error, m_command_options.language, nullptr, false));
+
+ if (!repl_sp) {
+ initialize = true;
+ repl_sp = target->GetREPL(repl_error, m_command_options.language,
+ nullptr, true);
+ if (!repl_error.Success()) {
+ result.SetError(repl_error);
return result.Succeeded();
+ }
}
- }
- }
- if (expr == nullptr)
- expr = command;
-
- if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
- {
- Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
- if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts())
- {
- CommandHistory &history = m_interpreter.GetCommandHistory();
- // FIXME: Can we figure out what the user actually typed (e.g. some alias for expr???)
- // If we can it would be nice to show that.
- std::string fixed_command("expression ");
- if (expr == command)
- fixed_command.append(m_fixed_expression);
- else
- {
- // Add in any options that might have been in the original command:
- fixed_command.append(command, expr - command);
- fixed_command.append(m_fixed_expression);
+ if (repl_sp) {
+ if (initialize) {
+ repl_sp->SetCommandOptions(m_command_options);
+ repl_sp->SetFormatOptions(m_format_options);
+ repl_sp->SetValueObjectDisplayOptions(m_varobj_options);
+ }
+
+ IOHandlerSP io_handler_sp(repl_sp->GetIOHandler());
+
+ io_handler_sp->SetIsDone(false);
+
+ debugger.PushIOHandler(io_handler_sp);
+ } else {
+ repl_error.SetErrorStringWithFormat(
+ "Couldn't create a REPL for %s",
+ Language::GetNameForLanguageType(m_command_options.language));
+ result.SetError(repl_error);
+ return result.Succeeded();
}
- history.AppendString(fixed_command);
+ }
}
- return true;
+ }
+ // No expression following options
+ else if (expr == nullptr || expr[0] == '\0') {
+ GetMultilineExpression();
+ return result.Succeeded();
+ }
}
+ }
- result.SetStatus (eReturnStatusFailed);
- return false;
+ if (expr == nullptr)
+ expr = command;
+
+ if (EvaluateExpression(expr, &(result.GetOutputStream()),
+ &(result.GetErrorStream()), &result)) {
+ Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
+ if (!target)
+ target = GetDummyTarget();
+
+ if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) {
+ CommandHistory &history = m_interpreter.GetCommandHistory();
+ // FIXME: Can we figure out what the user actually typed (e.g. some alias
+ // for expr???)
+ // If we can it would be nice to show that.
+ std::string fixed_command("expression ");
+ if (expr == command)
+ fixed_command.append(m_fixed_expression);
+ else {
+ // Add in any options that might have been in the original command:
+ fixed_command.append(command, expr - command);
+ fixed_command.append(m_fixed_expression);
+ }
+ history.AppendString(fixed_command);
+ }
+ return true;
+ }
+
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
diff --git a/source/Commands/CommandObjectExpression.h b/source/Commands/CommandObjectExpression.h
index 3445aef27665..7c21adcc26fe 100644
--- a/source/Commands/CommandObjectExpression.h
+++ b/source/Commands/CommandObjectExpression.h
@@ -14,101 +14,80 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private-enumerations.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/lldb-private-enumerations.h"
namespace lldb_private {
-class CommandObjectExpression :
- public CommandObjectRaw,
- public IOHandlerDelegate
-{
+class CommandObjectExpression : public CommandObjectRaw,
+ public IOHandlerDelegate {
public:
+ class CommandOptions : public OptionGroup {
+ public:
+ CommandOptions();
+
+ ~CommandOptions() override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+ bool top_level;
+ bool unwind_on_error;
+ bool ignore_breakpoints;
+ bool allow_jit;
+ bool show_types;
+ bool show_summary;
+ bool debug;
+ uint32_t timeout;
+ bool try_all_threads;
+ lldb::LanguageType language;
+ LanguageRuntimeDescriptionDisplayVerbosity m_verbosity;
+ LazyBool auto_apply_fixits;
+ };
+
+ CommandObjectExpression(CommandInterpreter &interpreter);
+
+ ~CommandObjectExpression() override;
- class CommandOptions : public OptionGroup
- {
- public:
-
- CommandOptions ();
-
- ~CommandOptions() override;
-
- uint32_t
- GetNumDefinitions() override;
-
- const OptionDefinition*
- GetDefinitions() override;
-
- Error
- SetOptionValue(CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_value) override;
-
- void
- OptionParsingStarting(CommandInterpreter &interpreter) override;
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
- bool top_level;
- bool unwind_on_error;
- bool ignore_breakpoints;
- bool allow_jit;
- bool show_types;
- bool show_summary;
- bool debug;
- uint32_t timeout;
- bool try_all_threads;
- lldb::LanguageType language;
- LanguageRuntimeDescriptionDisplayVerbosity m_verbosity;
- LazyBool auto_apply_fixits;
- };
-
- CommandObjectExpression (CommandInterpreter &interpreter);
-
- ~CommandObjectExpression() override;
-
- Options *
- GetOptions() override;
+ Options *GetOptions() override;
protected:
-
- //------------------------------------------------------------------
- // IOHandler::Delegate functions
- //------------------------------------------------------------------
- void
- IOHandlerInputComplete(IOHandler &io_handler,
- std::string &line) override;
-
- bool
- IOHandlerIsInputComplete (IOHandler &io_handler,
- StringList &lines) override;
-
- bool
- DoExecute(const char *command,
- CommandReturnObject &result) override;
-
- bool
- EvaluateExpression (const char *expr,
- Stream *output_stream,
- Stream *error_stream,
- CommandReturnObject *result = NULL);
-
- void
- GetMultilineExpression ();
-
- OptionGroupOptions m_option_group;
- OptionGroupFormat m_format_options;
- OptionGroupValueObjectDisplay m_varobj_options;
- OptionGroupBoolean m_repl_option;
- CommandOptions m_command_options;
- uint32_t m_expr_line_count;
- std::string m_expr_lines; // Multi-line expression support
- std::string m_fixed_expression; // Holds the current expression's fixed text.
+ //------------------------------------------------------------------
+ // IOHandler::Delegate functions
+ //------------------------------------------------------------------
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &line) override;
+
+ bool IOHandlerIsInputComplete(IOHandler &io_handler,
+ StringList &lines) override;
+
+ bool DoExecute(const char *command, CommandReturnObject &result) override;
+
+ bool EvaluateExpression(const char *expr, Stream *output_stream,
+ Stream *error_stream,
+ CommandReturnObject *result = NULL);
+
+ void GetMultilineExpression();
+
+ OptionGroupOptions m_option_group;
+ OptionGroupFormat m_format_options;
+ OptionGroupValueObjectDisplay m_varobj_options;
+ OptionGroupBoolean m_repl_option;
+ CommandOptions m_command_options;
+ uint32_t m_expr_line_count;
+ std::string m_expr_lines; // Multi-line expression support
+ std::string m_fixed_expression; // Holds the current expression's fixed text.
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index cd436dfdb97a..5a350545763d 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -29,12 +29,12 @@
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Interpreter/OptionGroupVariable.h"
-#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -43,39 +43,205 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Thread.h"
+#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/LLDBAssert.h"
using namespace lldb;
using namespace lldb_private;
-#pragma mark CommandObjectFrameInfo
+#pragma mark CommandObjectFrameDiagnose
//-------------------------------------------------------------------------
// CommandObjectFrameInfo
//-------------------------------------------------------------------------
-class CommandObjectFrameInfo : public CommandObjectParsed
-{
+//-------------------------------------------------------------------------
+// CommandObjectFrameDiagnose
+//-------------------------------------------------------------------------
+
+static OptionDefinition g_frame_diag_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "register", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegisterName, "A register to diagnose." },
+ { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "An address to diagnose." },
+ { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "An optional offset. Requires --register." }
+ // clang-format on
+};
+
+class CommandObjectFrameDiagnose : public CommandObjectParsed {
public:
- CommandObjectFrameInfo(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "frame info",
- "List information about the current stack frame in the current thread.", "frame info",
- eCommandRequiresFrame | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused)
- {
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option) {
+ case 'r':
+ reg = ConstString(option_arg);
+ break;
+
+ case 'a': {
+ address.emplace();
+ if (option_arg.getAsInteger(0, *address)) {
+ address.reset();
+ error.SetErrorStringWithFormat("invalid address argument '%s'",
+ option_arg.str().c_str());
+ }
+ } break;
+
+ case 'o': {
+ offset.emplace();
+ if (option_arg.getAsInteger(0, *offset)) {
+ offset.reset();
+ error.SetErrorStringWithFormat("invalid offset argument '%s'",
+ option_arg.str().c_str());
+ }
+ } break;
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ address.reset();
+ reg.reset();
+ offset.reset();
}
- ~CommandObjectFrameInfo() override = default;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_frame_diag_options);
+ }
+
+ // Options.
+ llvm::Optional<lldb::addr_t> address;
+ llvm::Optional<ConstString> reg;
+ llvm::Optional<int64_t> offset;
+ };
+
+ CommandObjectFrameDiagnose(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "frame diagnose",
+ "Try to determine what path path the current stop "
+ "location used to get to a register or address",
+ nullptr,
+ eCommandRequiresThread | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData index_arg;
+
+ // Define the first (and only) variant of this arg.
+ index_arg.arg_type = eArgTypeFrameIndex;
+ index_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectFrameDiagnose() override = default;
+
+ Options *GetOptions() override { return &m_options; }
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- m_exe_ctx.GetFrameRef().DumpUsingSettingsFormat (&result.GetOutputStream());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ StackFrameSP frame_sp = thread->GetSelectedFrame();
+
+ ValueObjectSP valobj_sp;
+
+ if (m_options.address.hasValue()) {
+ if (m_options.reg.hasValue() || m_options.offset.hasValue()) {
+ result.AppendError(
+ "`frame diagnose --address` is incompatible with other arguments.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ valobj_sp = frame_sp->GuessValueForAddress(m_options.address.getValue());
+ } else if (m_options.reg.hasValue()) {
+ valobj_sp = frame_sp->GuessValueForRegisterAndOffset(
+ m_options.reg.getValue(), m_options.offset.getValueOr(0));
+ } else {
+ StopInfoSP stop_info_sp = thread->GetStopInfo();
+ if (!stop_info_sp) {
+ result.AppendError("No arguments provided, and no stop info.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ valobj_sp = StopInfo::GetCrashingDereference(stop_info_sp);
}
+
+ if (!valobj_sp) {
+ result.AppendError("No diagnosis available.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const bool qualify_cxx_base_classes = false;
+
+ DumpValueObjectOptions::DeclPrintingHelper helper =
+ [&valobj_sp, qualify_cxx_base_classes](
+ ConstString type, ConstString var,
+ const DumpValueObjectOptions &opts, Stream &stream) -> bool {
+ const ValueObject::GetExpressionPathFormat format = ValueObject::
+ GetExpressionPathFormat::eGetExpressionPathFormatHonorPointers;
+ valobj_sp->GetExpressionPath(stream, qualify_cxx_base_classes, format);
+ stream.PutCString(" =");
+ return true;
+ };
+
+ DumpValueObjectOptions options;
+ options.SetDeclPrintingHelper(helper);
+ ValueObjectPrinter printer(valobj_sp.get(), &result.GetOutputStream(),
+ options);
+ printer.PrintValueObject();
+
+ return true;
+ }
+
+protected:
+ CommandOptions m_options;
+};
+
+#pragma mark CommandObjectFrameInfo
+
+//-------------------------------------------------------------------------
+// CommandObjectFrameInfo
+//-------------------------------------------------------------------------
+
+class CommandObjectFrameInfo : public CommandObjectParsed {
+public:
+ CommandObjectFrameInfo(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "frame info", "List information about the current "
+ "stack frame in the current thread.",
+ "frame info",
+ eCommandRequiresFrame | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
+
+ ~CommandObjectFrameInfo() override = default;
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ m_exe_ctx.GetFrameRef().DumpUsingSettingsFormat(&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectFrameSelect
@@ -84,515 +250,470 @@ protected:
// CommandObjectFrameSelect
//-------------------------------------------------------------------------
-class CommandObjectFrameSelect : public CommandObjectParsed
-{
+static OptionDefinition g_frame_select_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "A relative frame index offset from the current frame index." },
+ // clang-format on
+};
+
+class CommandObjectFrameSelect : public CommandObjectParsed {
public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- OptionParsingStarting ();
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option) {
+ case 'r':
+ if (option_arg.getAsInteger(0, relative_frame_offset)) {
+ relative_frame_offset = INT32_MIN;
+ error.SetErrorStringWithFormat("invalid frame offset argument '%s'",
+ option_arg.str().c_str());
}
+ break;
- ~CommandOptions() override = default;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- bool success = false;
- const int short_option = m_getopt_table[option_idx].val;
- switch (short_option)
- {
- case 'r':
- relative_frame_offset = StringConvert::ToSInt32 (option_arg, INT32_MIN, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat ("invalid frame offset argument '%s'", option_arg);
- break;
-
- default:
- error.SetErrorStringWithFormat ("invalid short option character '%c'", short_option);
- break;
- }
+ return error;
+ }
- return error;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ relative_frame_offset = INT32_MIN;
+ }
- void
- OptionParsingStarting () override
- {
- relative_frame_offset = INT32_MIN;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_frame_select_options);
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ int32_t relative_frame_offset;
+ };
- // Options table: Required for subclasses of Options.
+ CommandObjectFrameSelect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "frame select", "Select the current stack frame by "
+ "index from within the current thread "
+ "(see 'thread backtrace'.)",
+ nullptr,
+ eCommandRequiresThread | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData index_arg;
- static OptionDefinition g_option_table[];
- int32_t relative_frame_offset;
- };
+ // Define the first (and only) variant of this arg.
+ index_arg.arg_type = eArgTypeFrameIndex;
+ index_arg.arg_repetition = eArgRepeatOptional;
- CommandObjectFrameSelect(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "frame select",
- "Select the current stack frame by index from within the current thread (see 'thread backtrace'.)",
- nullptr, eCommandRequiresThread | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused),
- m_options(interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData index_arg;
-
- // Define the first (and only) variant of this arg.
- index_arg.arg_type = eArgTypeFrameIndex;
- index_arg.arg_repetition = eArgRepeatOptional;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (index_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(index_arg);
- ~CommandObjectFrameSelect() override = default;
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ ~CommandObjectFrameSelect() override = default;
+
+ Options *GetOptions() override { return &m_options; }
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- // No need to check "thread" for validity as eCommandRequiresThread ensures it is valid
- Thread *thread = m_exe_ctx.GetThreadPtr();
-
- uint32_t frame_idx = UINT32_MAX;
- if (m_options.relative_frame_offset != INT32_MIN)
- {
- // The one and only argument is a signed relative frame index
- frame_idx = thread->GetSelectedFrameIndex ();
- if (frame_idx == UINT32_MAX)
- frame_idx = 0;
-
- if (m_options.relative_frame_offset < 0)
- {
- if (static_cast<int32_t>(frame_idx) >= -m_options.relative_frame_offset)
- frame_idx += m_options.relative_frame_offset;
- else
- {
- if (frame_idx == 0)
- {
- //If you are already at the bottom of the stack, then just warn and don't reset the frame.
- result.AppendError("Already at the bottom of the stack.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else
- frame_idx = 0;
- }
- }
- else if (m_options.relative_frame_offset > 0)
- {
- // I don't want "up 20" where "20" takes you past the top of the stack to produce
- // an error, but rather to just go to the top. So I have to count the stack here...
- const uint32_t num_frames = thread->GetStackFrameCount();
- if (static_cast<int32_t>(num_frames - frame_idx) > m_options.relative_frame_offset)
- frame_idx += m_options.relative_frame_offset;
- else
- {
- if (frame_idx == num_frames - 1)
- {
- //If we are already at the top of the stack, just warn and don't reset the frame.
- result.AppendError("Already at the top of the stack.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else
- frame_idx = num_frames - 1;
- }
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ // No need to check "thread" for validity as eCommandRequiresThread ensures
+ // it is valid
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+
+ uint32_t frame_idx = UINT32_MAX;
+ if (m_options.relative_frame_offset != INT32_MIN) {
+ // The one and only argument is a signed relative frame index
+ frame_idx = thread->GetSelectedFrameIndex();
+ if (frame_idx == UINT32_MAX)
+ frame_idx = 0;
+
+ if (m_options.relative_frame_offset < 0) {
+ if (static_cast<int32_t>(frame_idx) >= -m_options.relative_frame_offset)
+ frame_idx += m_options.relative_frame_offset;
+ else {
+ if (frame_idx == 0) {
+ // If you are already at the bottom of the stack, then just warn and
+ // don't reset the frame.
+ result.AppendError("Already at the bottom of the stack.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else
+ frame_idx = 0;
}
- else
- {
- if (command.GetArgumentCount() == 1)
- {
- const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
- bool success = false;
- frame_idx = StringConvert::ToUInt32 (frame_idx_cstr, UINT32_MAX, 0, &success);
- if (!success)
- {
- result.AppendErrorWithFormat("invalid frame index argument '%s'.", frame_idx_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else if (command.GetArgumentCount() == 0)
- {
- frame_idx = thread->GetSelectedFrameIndex ();
- if (frame_idx == UINT32_MAX)
- {
- frame_idx = 0;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("too many arguments; expected frame-index, saw '%s'.\n",
- command.GetArgumentAtIndex(0));
- m_options.GenerateOptionUsage (result.GetErrorStream(), this);
- return false;
- }
+ } else if (m_options.relative_frame_offset > 0) {
+ // I don't want "up 20" where "20" takes you past the top of the stack
+ // to produce
+ // an error, but rather to just go to the top. So I have to count the
+ // stack here...
+ const uint32_t num_frames = thread->GetStackFrameCount();
+ if (static_cast<int32_t>(num_frames - frame_idx) >
+ m_options.relative_frame_offset)
+ frame_idx += m_options.relative_frame_offset;
+ else {
+ if (frame_idx == num_frames - 1) {
+ // If we are already at the top of the stack, just warn and don't
+ // reset the frame.
+ result.AppendError("Already at the top of the stack.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else
+ frame_idx = num_frames - 1;
}
-
- bool success = thread->SetSelectedFrameByIndexNoisily (frame_idx, result.GetOutputStream());
- if (success)
- {
- m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
- result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
+ } else {
+ if (command.GetArgumentCount() > 1) {
+ result.AppendErrorWithFormat(
+ "too many arguments; expected frame-index, saw '%s'.\n",
+ command[0].c_str());
+ m_options.GenerateOptionUsage(
+ result.GetErrorStream(), this,
+ GetCommandInterpreter().GetDebugger().GetTerminalWidth());
+ return false;
+ }
+
+ if (command.GetArgumentCount() == 1) {
+ if (command[0].ref.getAsInteger(0, frame_idx)) {
+ result.AppendErrorWithFormat("invalid frame index argument '%s'.",
+ command[0].c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else
- {
- result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
- result.SetStatus (eReturnStatusFailed);
+ } else if (command.GetArgumentCount() == 0) {
+ frame_idx = thread->GetSelectedFrameIndex();
+ if (frame_idx == UINT32_MAX) {
+ frame_idx = 0;
}
-
- return result.Succeeded();
+ }
}
-protected:
- CommandOptions m_options;
-};
+ bool success = thread->SetSelectedFrameByIndexNoisily(
+ frame_idx, result.GetOutputStream());
+ if (success) {
+ m_exe_ctx.SetFrameSP(thread->GetSelectedFrame());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Frame index (%u) out of range.\n",
+ frame_idx);
+ result.SetStatus(eReturnStatusFailed);
+ }
-OptionDefinition
-CommandObjectFrameSelect::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "A relative frame index offset from the current frame index."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ return result.Succeeded();
+ }
+
+protected:
+ CommandOptions m_options;
};
#pragma mark CommandObjectFrameVariable
//----------------------------------------------------------------------
// List images with associated information
//----------------------------------------------------------------------
-class CommandObjectFrameVariable : public CommandObjectParsed
-{
+class CommandObjectFrameVariable : public CommandObjectParsed {
public:
- CommandObjectFrameVariable(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "frame variable", "Show variables for the current stack frame. Defaults to all "
- "arguments and local variables in scope. Names of argument, "
- "local, file static and file global variables can be specified. "
- "Children of aggregate variables can be specified such as "
- "'var->child.x'.",
- nullptr, eCommandRequiresFrame | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused | eCommandRequiresProcess),
- m_option_group(interpreter),
- m_option_variable(true), // Include the frame specific options by passing "true"
- m_option_format(eFormatDefault),
- m_varobj_options()
- {
- CommandArgumentEntry arg;
- CommandArgumentData var_name_arg;
-
- // Define the first (and only) variant of this arg.
- var_name_arg.arg_type = eArgTypeVarName;
- var_name_arg.arg_repetition = eArgRepeatStar;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (var_name_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
-
- m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
- m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
+ CommandObjectFrameVariable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "frame variable",
+ "Show variables for the current stack frame. Defaults to all "
+ "arguments and local variables in scope. Names of argument, "
+ "local, file static and file global variables can be specified. "
+ "Children of aggregate variables can be specified such as "
+ "'var->child.x'.",
+ nullptr, eCommandRequiresFrame | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused | eCommandRequiresProcess),
+ m_option_group(),
+ m_option_variable(
+ true), // Include the frame specific options by passing "true"
+ m_option_format(eFormatDefault),
+ m_varobj_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData var_name_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeVarName;
+ var_name_arg.arg_repetition = eArgRepeatStar;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(var_name_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+
+ m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_option_format,
+ OptionGroupFormat::OPTION_GROUP_FORMAT |
+ OptionGroupFormat::OPTION_GROUP_GDB_FMT,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectFrameVariable() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ // Arguments are the standard source file completer.
+ auto completion_str = input[cursor_index].ref;
+ completion_str = completion_str.take_front(cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion,
+ completion_str, match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
- ~CommandObjectFrameVariable() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- // Arguments are the standard source file completer.
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eVariablePathCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
+protected:
+ llvm::StringRef GetScopeString(VariableSP var_sp) {
+ if (!var_sp)
+ return llvm::StringRef::withNullAsEmpty(nullptr);
+
+ switch (var_sp->GetScope()) {
+ case eValueTypeVariableGlobal:
+ return "GLOBAL: ";
+ case eValueTypeVariableStatic:
+ return "STATIC: ";
+ case eValueTypeVariableArgument:
+ return "ARG: ";
+ case eValueTypeVariableLocal:
+ return "LOCAL: ";
+ case eValueTypeVariableThreadLocal:
+ return "THREAD: ";
+ default:
+ break;
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- // No need to check "frame" for validity as eCommandRequiresFrame ensures it is valid
- StackFrame *frame = m_exe_ctx.GetFramePtr();
-
- Stream &s = result.GetOutputStream();
-
- // Be careful about the stack frame, if any summary formatter runs code, it might clear the StackFrameList
- // for the thread. So hold onto a shared pointer to the frame so it stays alive.
-
- VariableList *variable_list = frame->GetVariableList (m_option_variable.show_globals);
-
- VariableSP var_sp;
- ValueObjectSP valobj_sp;
-
- const char *name_cstr = nullptr;
- size_t idx;
-
- TypeSummaryImplSP summary_format_sp;
- if (!m_option_variable.summary.IsCurrentValueEmpty())
- DataVisualization::NamedSummaryFormats::GetSummaryFormat(ConstString(m_option_variable.summary.GetCurrentValue()), summary_format_sp);
- else if (!m_option_variable.summary_string.IsCurrentValueEmpty())
- summary_format_sp.reset(new StringSummaryFormat(TypeSummaryImpl::Flags(),m_option_variable.summary_string.GetCurrentValue()));
-
- DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(eLanguageRuntimeDescriptionDisplayVerbosityFull,eFormatDefault,summary_format_sp));
-
- const SymbolContext& sym_ctx = frame->GetSymbolContext(eSymbolContextFunction);
- if (sym_ctx.function && sym_ctx.function->IsTopLevelFunction())
- m_option_variable.show_globals = true;
-
- if (variable_list)
- {
- const Format format = m_option_format.GetFormat();
- options.SetFormat(format);
-
- if (command.GetArgumentCount() > 0)
- {
- VariableList regex_var_list;
-
- // If we have any args to the variable command, we will make
- // variable objects from them...
- for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != nullptr; ++idx)
- {
- if (m_option_variable.use_regex)
- {
- const size_t regex_start_index = regex_var_list.GetSize();
- RegularExpression regex (name_cstr);
- if (regex.Compile(name_cstr))
- {
- size_t num_matches = 0;
- const size_t num_new_regex_vars = variable_list->AppendVariablesIfUnique(regex,
- regex_var_list,
- num_matches);
- if (num_new_regex_vars > 0)
- {
- for (size_t regex_idx = regex_start_index, end_index = regex_var_list.GetSize();
- regex_idx < end_index;
- ++regex_idx)
- {
- var_sp = regex_var_list.GetVariableAtIndex (regex_idx);
- if (var_sp)
- {
- valobj_sp = frame->GetValueObjectForFrameVariable (var_sp, m_varobj_options.use_dynamic);
- if (valobj_sp)
- {
-// if (format != eFormatDefault)
-// valobj_sp->SetFormat (format);
-
- if (m_option_variable.show_decl && var_sp->GetDeclaration ().GetFile())
- {
- bool show_fullpaths = false;
- bool show_module = true;
- if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
- s.PutCString (": ");
- }
- valobj_sp->Dump(result.GetOutputStream(),options);
- }
- }
- }
- }
- else if (num_matches == 0)
- {
- result.GetErrorStream().Printf ("error: no variables matched the regular expression '%s'.\n", name_cstr);
- }
- }
- else
- {
- char regex_error[1024];
- if (regex.GetErrorAsCString(regex_error, sizeof(regex_error)))
- result.GetErrorStream().Printf ("error: %s\n", regex_error);
- else
- result.GetErrorStream().Printf ("error: unknown regex error when compiling '%s'\n", name_cstr);
- }
- }
- else // No regex, either exact variable names or variable expressions.
- {
- Error error;
- uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
- StackFrame::eExpressionPathOptionsAllowDirectIVarAccess |
- StackFrame::eExpressionPathOptionsInspectAnonymousUnions;
- lldb::VariableSP var_sp;
- valobj_sp = frame->GetValueForVariableExpressionPath (name_cstr,
- m_varobj_options.use_dynamic,
- expr_path_options,
- var_sp,
- error);
- if (valobj_sp)
- {
-// if (format != eFormatDefault)
-// valobj_sp->SetFormat (format);
- if (m_option_variable.show_decl && var_sp && var_sp->GetDeclaration ().GetFile())
- {
- var_sp->GetDeclaration ().DumpStopContext (&s, false);
- s.PutCString (": ");
- }
-
- options.SetFormat(format);
- options.SetVariableFormatDisplayLanguage(valobj_sp->GetPreferredDisplayLanguage());
-
- Stream &output_stream = result.GetOutputStream();
- options.SetRootValueObjectName(valobj_sp->GetParent() ? name_cstr : nullptr);
- valobj_sp->Dump(output_stream,options);
- }
- else
- {
- const char *error_cstr = error.AsCString(nullptr);
- if (error_cstr)
- result.GetErrorStream().Printf("error: %s\n", error_cstr);
- else
- result.GetErrorStream().Printf(
- "error: unable to find any variable expression path that matches '%s'.\n",
- name_cstr);
- }
+ return llvm::StringRef::withNullAsEmpty(nullptr);
+ }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ // No need to check "frame" for validity as eCommandRequiresFrame ensures it
+ // is valid
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
+
+ Stream &s = result.GetOutputStream();
+
+ // Be careful about the stack frame, if any summary formatter runs code, it
+ // might clear the StackFrameList
+ // for the thread. So hold onto a shared pointer to the frame so it stays
+ // alive.
+
+ VariableList *variable_list =
+ frame->GetVariableList(m_option_variable.show_globals);
+
+ VariableSP var_sp;
+ ValueObjectSP valobj_sp;
+
+ TypeSummaryImplSP summary_format_sp;
+ if (!m_option_variable.summary.IsCurrentValueEmpty())
+ DataVisualization::NamedSummaryFormats::GetSummaryFormat(
+ ConstString(m_option_variable.summary.GetCurrentValue()),
+ summary_format_sp);
+ else if (!m_option_variable.summary_string.IsCurrentValueEmpty())
+ summary_format_sp.reset(new StringSummaryFormat(
+ TypeSummaryImpl::Flags(),
+ m_option_variable.summary_string.GetCurrentValue()));
+
+ DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
+ eLanguageRuntimeDescriptionDisplayVerbosityFull, eFormatDefault,
+ summary_format_sp));
+
+ const SymbolContext &sym_ctx =
+ frame->GetSymbolContext(eSymbolContextFunction);
+ if (sym_ctx.function && sym_ctx.function->IsTopLevelFunction())
+ m_option_variable.show_globals = true;
+
+ if (variable_list) {
+ const Format format = m_option_format.GetFormat();
+ options.SetFormat(format);
+
+ if (!command.empty()) {
+ VariableList regex_var_list;
+
+ // If we have any args to the variable command, we will make
+ // variable objects from them...
+ for (auto &entry : command) {
+ if (m_option_variable.use_regex) {
+ const size_t regex_start_index = regex_var_list.GetSize();
+ llvm::StringRef name_str = entry.ref;
+ RegularExpression regex(name_str);
+ if (regex.Compile(name_str)) {
+ size_t num_matches = 0;
+ const size_t num_new_regex_vars =
+ variable_list->AppendVariablesIfUnique(regex, regex_var_list,
+ num_matches);
+ if (num_new_regex_vars > 0) {
+ for (size_t regex_idx = regex_start_index,
+ end_index = regex_var_list.GetSize();
+ regex_idx < end_index; ++regex_idx) {
+ var_sp = regex_var_list.GetVariableAtIndex(regex_idx);
+ if (var_sp) {
+ valobj_sp = frame->GetValueObjectForFrameVariable(
+ var_sp, m_varobj_options.use_dynamic);
+ if (valobj_sp) {
+ std::string scope_string;
+ if (m_option_variable.show_scope)
+ scope_string = GetScopeString(var_sp).str();
+
+ if (!scope_string.empty())
+ s.PutCString(scope_string);
+
+ if (m_option_variable.show_decl &&
+ var_sp->GetDeclaration().GetFile()) {
+ bool show_fullpaths = false;
+ bool show_module = true;
+ if (var_sp->DumpDeclaration(&s, show_fullpaths,
+ show_module))
+ s.PutCString(": ");
+ }
+ valobj_sp->Dump(result.GetOutputStream(), options);
}
+ }
}
+ } else if (num_matches == 0) {
+ result.GetErrorStream().Printf("error: no variables matched "
+ "the regular expression '%s'.\n",
+ entry.c_str());
+ }
+ } else {
+ char regex_error[1024];
+ if (regex.GetErrorAsCString(regex_error, sizeof(regex_error)))
+ result.GetErrorStream().Printf("error: %s\n", regex_error);
+ else
+ result.GetErrorStream().Printf(
+ "error: unknown regex error when compiling '%s'\n",
+ entry.c_str());
}
- else // No command arg specified. Use variable_list, instead.
- {
- const size_t num_variables = variable_list->GetSize();
- if (num_variables > 0)
- {
- for (size_t i=0; i<num_variables; i++)
- {
- var_sp = variable_list->GetVariableAtIndex(i);
- bool dump_variable = true;
- std::string scope_string;
- switch (var_sp->GetScope())
- {
- case eValueTypeVariableGlobal:
- // Always dump globals since we only fetched them if
- // m_option_variable.show_scope was true
- if (dump_variable && m_option_variable.show_scope)
- scope_string = "GLOBAL: ";
- break;
-
- case eValueTypeVariableStatic:
- // Always dump globals since we only fetched them if
- // m_option_variable.show_scope was true, or this is
- // a static variable from a block in the current scope
- if (dump_variable && m_option_variable.show_scope)
- scope_string = "STATIC: ";
- break;
-
- case eValueTypeVariableArgument:
- dump_variable = m_option_variable.show_args;
- if (dump_variable && m_option_variable.show_scope)
- scope_string = " ARG: ";
- break;
-
- case eValueTypeVariableLocal:
- dump_variable = m_option_variable.show_locals;
- if (dump_variable && m_option_variable.show_scope)
- scope_string = " LOCAL: ";
- break;
-
- case eValueTypeVariableThreadLocal:
- if (dump_variable && m_option_variable.show_scope)
- scope_string = "THREAD: ";
- break;
- default:
- break;
- }
-
- if (dump_variable)
- {
- // Use the variable object code to make sure we are
- // using the same APIs as the public API will be
- // using...
- valobj_sp = frame->GetValueObjectForFrameVariable (var_sp,
- m_varobj_options.use_dynamic);
- if (valobj_sp)
- {
-// if (format != eFormatDefault)
-// valobj_sp->SetFormat (format);
-
- // When dumping all variables, don't print any variables
- // that are not in scope to avoid extra unneeded output
- if (valobj_sp->IsInScope ())
- {
- if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
- valobj_sp->IsRuntimeSupportValue())
- continue;
-
- if (!scope_string.empty())
- s.PutCString(scope_string.c_str());
-
- if (m_option_variable.show_decl && var_sp->GetDeclaration ().GetFile())
- {
- var_sp->GetDeclaration ().DumpStopContext (&s, false);
- s.PutCString (": ");
- }
-
- options.SetFormat(format);
- options.SetVariableFormatDisplayLanguage(valobj_sp->GetPreferredDisplayLanguage());
- options.SetRootValueObjectName(name_cstr);
- valobj_sp->Dump(result.GetOutputStream(),options);
- }
- }
- }
- }
- }
+ } else // No regex, either exact variable names or variable
+ // expressions.
+ {
+ Error error;
+ uint32_t expr_path_options =
+ StackFrame::eExpressionPathOptionCheckPtrVsMember |
+ StackFrame::eExpressionPathOptionsAllowDirectIVarAccess |
+ StackFrame::eExpressionPathOptionsInspectAnonymousUnions;
+ lldb::VariableSP var_sp;
+ valobj_sp = frame->GetValueForVariableExpressionPath(
+ entry.ref, m_varobj_options.use_dynamic, expr_path_options,
+ var_sp, error);
+ if (valobj_sp) {
+ std::string scope_string;
+ if (m_option_variable.show_scope)
+ scope_string = GetScopeString(var_sp).str();
+
+ if (!scope_string.empty())
+ s.PutCString(scope_string);
+
+ // if (format != eFormatDefault)
+ // valobj_sp->SetFormat (format);
+ if (m_option_variable.show_decl && var_sp &&
+ var_sp->GetDeclaration().GetFile()) {
+ var_sp->GetDeclaration().DumpStopContext(&s, false);
+ s.PutCString(": ");
+ }
+
+ options.SetFormat(format);
+ options.SetVariableFormatDisplayLanguage(
+ valobj_sp->GetPreferredDisplayLanguage());
+
+ Stream &output_stream = result.GetOutputStream();
+ options.SetRootValueObjectName(
+ valobj_sp->GetParent() ? entry.c_str() : nullptr);
+ valobj_sp->Dump(output_stream, options);
+ } else {
+ const char *error_cstr = error.AsCString(nullptr);
+ if (error_cstr)
+ result.GetErrorStream().Printf("error: %s\n", error_cstr);
+ else
+ result.GetErrorStream().Printf("error: unable to find any "
+ "variable expression path that "
+ "matches '%s'.\n",
+ entry.c_str());
}
- result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
}
-
- if (m_interpreter.TruncationWarningNecessary())
- {
- result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
- m_cmd_name.c_str());
- m_interpreter.TruncationWarningGiven();
+ } else // No command arg specified. Use variable_list, instead.
+ {
+ const size_t num_variables = variable_list->GetSize();
+ if (num_variables > 0) {
+ for (size_t i = 0; i < num_variables; i++) {
+ var_sp = variable_list->GetVariableAtIndex(i);
+ bool dump_variable = true;
+ std::string scope_string;
+ if (dump_variable && m_option_variable.show_scope)
+ scope_string = GetScopeString(var_sp).str();
+
+ if (dump_variable) {
+ // Use the variable object code to make sure we are
+ // using the same APIs as the public API will be
+ // using...
+ valobj_sp = frame->GetValueObjectForFrameVariable(
+ var_sp, m_varobj_options.use_dynamic);
+ if (valobj_sp) {
+ // When dumping all variables, don't print any variables
+ // that are not in scope to avoid extra unneeded output
+ if (valobj_sp->IsInScope()) {
+ if (!valobj_sp->GetTargetSP()
+ ->GetDisplayRuntimeSupportValues() &&
+ valobj_sp->IsRuntimeSupportValue())
+ continue;
+
+ if (!scope_string.empty())
+ s.PutCString(scope_string);
+
+ if (m_option_variable.show_decl &&
+ var_sp->GetDeclaration().GetFile()) {
+ var_sp->GetDeclaration().DumpStopContext(&s, false);
+ s.PutCString(": ");
+ }
+
+ options.SetFormat(format);
+ options.SetVariableFormatDisplayLanguage(
+ valobj_sp->GetPreferredDisplayLanguage());
+ options.SetRootValueObjectName(
+ var_sp ? var_sp->GetName().AsCString() : nullptr);
+ valobj_sp->Dump(result.GetOutputStream(), options);
+ }
+ }
+ }
+ }
}
-
- return result.Succeeded();
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
}
+ if (m_interpreter.TruncationWarningNecessary()) {
+ result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
+ m_cmd_name.c_str());
+ m_interpreter.TruncationWarningGiven();
+ }
+
+ return result.Succeeded();
+ }
+
protected:
- OptionGroupOptions m_option_group;
- OptionGroupVariable m_option_variable;
- OptionGroupFormat m_option_format;
- OptionGroupValueObjectDisplay m_varobj_options;
+ OptionGroupOptions m_option_group;
+ OptionGroupVariable m_option_variable;
+ OptionGroupFormat m_option_format;
+ OptionGroupValueObjectDisplay m_varobj_options;
};
#pragma mark CommandObjectMultiwordFrame
@@ -601,14 +722,20 @@ protected:
// CommandObjectMultiwordFrame
//-------------------------------------------------------------------------
-CommandObjectMultiwordFrame::CommandObjectMultiwordFrame(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "frame",
- "Commands for selecting and examing the current thread's stack frames.",
- "frame <subcommand> [<subcommand-options>]")
-{
- LoadSubCommand ("info", CommandObjectSP (new CommandObjectFrameInfo (interpreter)));
- LoadSubCommand ("select", CommandObjectSP (new CommandObjectFrameSelect (interpreter)));
- LoadSubCommand ("variable", CommandObjectSP (new CommandObjectFrameVariable (interpreter)));
+CommandObjectMultiwordFrame::CommandObjectMultiwordFrame(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "frame", "Commands for selecting and "
+ "examing the current "
+ "thread's stack frames.",
+ "frame <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("diagnose",
+ CommandObjectSP(new CommandObjectFrameDiagnose(interpreter)));
+ LoadSubCommand("info",
+ CommandObjectSP(new CommandObjectFrameInfo(interpreter)));
+ LoadSubCommand("select",
+ CommandObjectSP(new CommandObjectFrameSelect(interpreter)));
+ LoadSubCommand("variable",
+ CommandObjectSP(new CommandObjectFrameVariable(interpreter)));
}
CommandObjectMultiwordFrame::~CommandObjectMultiwordFrame() = default;
diff --git a/source/Commands/CommandObjectFrame.h b/source/Commands/CommandObjectFrame.h
index a72988078f6d..875bcc944a38 100644
--- a/source/Commands/CommandObjectFrame.h
+++ b/source/Commands/CommandObjectFrame.h
@@ -14,9 +14,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Options.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/Options.h"
namespace lldb_private {
@@ -24,13 +24,11 @@ namespace lldb_private {
// CommandObjectMultiwordFrame
//-------------------------------------------------------------------------
-class CommandObjectMultiwordFrame : public CommandObjectMultiword
-{
+class CommandObjectMultiwordFrame : public CommandObjectMultiword {
public:
+ CommandObjectMultiwordFrame(CommandInterpreter &interpreter);
- CommandObjectMultiwordFrame (CommandInterpreter &interpreter);
-
- ~CommandObjectMultiwordFrame() override;
+ ~CommandObjectMultiwordFrame() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectGUI.cpp b/source/Commands/CommandObjectGUI.cpp
index 0991c7e84874..d65e12e30982 100644
--- a/source/Commands/CommandObjectGUI.cpp
+++ b/source/Commands/CommandObjectGUI.cpp
@@ -13,9 +13,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
@@ -24,48 +24,35 @@ using namespace lldb_private;
// CommandObjectGUI
//-------------------------------------------------------------------------
-CommandObjectGUI::CommandObjectGUI (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter, "gui", "Switch into the curses based GUI mode.", "gui")
-{
-}
+CommandObjectGUI::CommandObjectGUI(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "gui",
+ "Switch into the curses based GUI mode.", "gui") {}
-CommandObjectGUI::~CommandObjectGUI ()
-{
-}
+CommandObjectGUI::~CommandObjectGUI() {}
-bool
-CommandObjectGUI::DoExecute (Args& args, CommandReturnObject &result)
-{
+bool CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) {
#ifndef LLDB_DISABLE_CURSES
- if (args.GetArgumentCount() == 0)
- {
- Debugger &debugger = m_interpreter.GetDebugger();
-
- lldb::StreamFileSP input_sp = debugger.GetInputFile();
- if (input_sp &&
- input_sp->GetFile().GetIsRealTerminal() &&
- input_sp->GetFile().GetIsInteractive())
- {
- IOHandlerSP io_handler_sp (new IOHandlerCursesGUI (debugger));
- if (io_handler_sp)
- debugger.PushIOHandler(io_handler_sp);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError("the gui command requires an interactive terminal.");
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError("the gui command takes no arguments.");
- result.SetStatus (eReturnStatusFailed);
+ if (args.GetArgumentCount() == 0) {
+ Debugger &debugger = m_interpreter.GetDebugger();
+
+ lldb::StreamFileSP input_sp = debugger.GetInputFile();
+ if (input_sp && input_sp->GetFile().GetIsRealTerminal() &&
+ input_sp->GetFile().GetIsInteractive()) {
+ IOHandlerSP io_handler_sp(new IOHandlerCursesGUI(debugger));
+ if (io_handler_sp)
+ debugger.PushIOHandler(io_handler_sp);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError("the gui command requires an interactive terminal.");
+ result.SetStatus(eReturnStatusFailed);
}
- return true;
+ } else {
+ result.AppendError("the gui command takes no arguments.");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return true;
#else
- result.AppendError("lldb was not build with gui support");
- return false;
+ result.AppendError("lldb was not build with gui support");
+ return false;
#endif
}
-
diff --git a/source/Commands/CommandObjectGUI.h b/source/Commands/CommandObjectGUI.h
index 494bcc48e20e..c71558fa1758 100644
--- a/source/Commands/CommandObjectGUI.h
+++ b/source/Commands/CommandObjectGUI.h
@@ -22,18 +22,14 @@ namespace lldb_private {
// CommandObjectGUI
//-------------------------------------------------------------------------
-class CommandObjectGUI : public CommandObjectParsed
-{
+class CommandObjectGUI : public CommandObjectParsed {
public:
+ CommandObjectGUI(CommandInterpreter &interpreter);
- CommandObjectGUI (CommandInterpreter &interpreter);
-
- ~CommandObjectGUI() override;
+ ~CommandObjectGUI() override;
protected:
- bool
- DoExecute(Args& args,
- CommandReturnObject &result) override;
+ bool DoExecute(Args &args, CommandReturnObject &result) override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectHelp.cpp b/source/Commands/CommandObjectHelp.cpp
index 4cf74885e998..99e9d7b3abd4 100644
--- a/source/Commands/CommandObjectHelp.cpp
+++ b/source/Commands/CommandObjectHelp.cpp
@@ -12,10 +12,10 @@
// Other libraries and framework includes
// Project includes
#include "CommandObjectHelp.h"
-#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
using namespace lldb;
using namespace lldb_private;
@@ -24,252 +24,220 @@ using namespace lldb_private;
// CommandObjectHelp
//-------------------------------------------------------------------------
-void
-CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage (Stream *s,
- const char* command,
- const char* prefix,
- const char* subcommand,
- bool include_apropos,
- bool include_type_lookup)
-{
- if (s && command && *command)
- {
- s->Printf("'%s' is not a known command.\n", command);
- s->Printf("Try '%shelp' to see a current list of commands.\n", prefix ? prefix : "");
- if (include_apropos)
- {
- s->Printf("Try '%sapropos %s' for a list of related commands.\n",
- prefix ? prefix : "", subcommand ? subcommand : command);
- }
- if (include_type_lookup)
- {
- s->Printf("Try '%stype lookup %s' for information on types, methods, functions, modules, etc.",
- prefix ? prefix : "", subcommand ? subcommand : command);
- }
- }
+void CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(
+ Stream *s, llvm::StringRef command, llvm::StringRef prefix, llvm::StringRef subcommand,
+ bool include_apropos, bool include_type_lookup) {
+ if (!s || command.empty())
+ return;
+
+ std::string command_str = command.str();
+ std::string prefix_str = prefix.str();
+ std::string subcommand_str = subcommand.str();
+ const std::string &lookup_str = !subcommand_str.empty() ? subcommand_str : command_str;
+ s->Printf("'%s' is not a known command.\n", command_str.c_str());
+ s->Printf("Try '%shelp' to see a current list of commands.\n",
+ prefix.str().c_str());
+ if (include_apropos) {
+ s->Printf("Try '%sapropos %s' for a list of related commands.\n",
+ prefix_str.c_str(), lookup_str.c_str());
+ }
+ if (include_type_lookup) {
+ s->Printf("Try '%stype lookup %s' for information on types, methods, "
+ "functions, modules, etc.",
+ prefix_str.c_str(), lookup_str.c_str());
+ }
}
CommandObjectHelp::CommandObjectHelp(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "help",
- "Show a list of all debugger commands, or give details about a specific command.",
+ : CommandObjectParsed(interpreter, "help", "Show a list of all debugger "
+ "commands, or give details "
+ "about a specific command.",
"help [<cmd-name>]"),
- m_options(interpreter)
-{
- CommandArgumentEntry arg;
- CommandArgumentData command_arg;
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData command_arg;
- // Define the first (and only) variant of this arg.
- command_arg.arg_type = eArgTypeCommandName;
- command_arg.arg_repetition = eArgRepeatStar;
+ // Define the first (and only) variant of this arg.
+ command_arg.arg_type = eArgTypeCommandName;
+ command_arg.arg_repetition = eArgRepeatStar;
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (command_arg);
+ // There is only one variant this argument could be; put it into the argument
+ // entry.
+ arg.push_back(command_arg);
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
}
CommandObjectHelp::~CommandObjectHelp() = default;
-OptionDefinition
-CommandObjectHelp::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Hide aliases in the command list."},
- { LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Hide user-defined commands from the list."},
- { LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Include commands prefixed with an underscore."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+static OptionDefinition g_help_options[] = {
+ // clang-format off
+ {LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Hide aliases in the command list."},
+ {LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Hide user-defined commands from the list."},
+ {LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Include commands prefixed with an underscore."},
+ // clang-format on
};
-bool
-CommandObjectHelp::DoExecute (Args& command, CommandReturnObject &result)
-{
- CommandObject::CommandMap::iterator pos;
- CommandObject *cmd_obj;
- const size_t argc = command.GetArgumentCount ();
-
- // 'help' doesn't take any arguments, other than command names. If argc is 0, we show the user
- // all commands (aliases and user commands if asked for). Otherwise every argument must be the name of a command or a sub-command.
- if (argc == 0)
- {
- uint32_t cmd_types = CommandInterpreter::eCommandTypesBuiltin;
- if (m_options.m_show_aliases)
- cmd_types |= CommandInterpreter::eCommandTypesAliases;
- if (m_options.m_show_user_defined)
- cmd_types |= CommandInterpreter::eCommandTypesUserDef;
- if (m_options.m_show_hidden)
- cmd_types |= CommandInterpreter::eCommandTypesHidden;
+llvm::ArrayRef<OptionDefinition>
+CommandObjectHelp::CommandOptions::GetDefinitions() {
+ return llvm::makeArrayRef(g_help_options);
+}
+
+bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) {
+ CommandObject::CommandMap::iterator pos;
+ CommandObject *cmd_obj;
+ const size_t argc = command.GetArgumentCount();
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- m_interpreter.GetHelp (result, cmd_types); // General help
- }
- else
- {
- // Get command object for the first command argument. Only search built-in command dictionary.
- StringList matches;
- cmd_obj = m_interpreter.GetCommandObject (command.GetArgumentAtIndex (0), &matches);
- bool is_alias_command = m_interpreter.AliasExists (command.GetArgumentAtIndex (0));
- std::string alias_name = command.GetArgumentAtIndex(0);
-
- if (cmd_obj != nullptr)
- {
- StringList matches;
- bool all_okay = true;
- CommandObject *sub_cmd_obj = cmd_obj;
- // Loop down through sub_command dictionaries until we find the command object that corresponds
- // to the help command entered.
- std::string sub_command;
- for (size_t i = 1; i < argc && all_okay; ++i)
- {
- sub_command = command.GetArgumentAtIndex(i);
- matches.Clear();
- if (sub_cmd_obj->IsAlias())
- sub_cmd_obj = ((CommandAlias*)sub_cmd_obj)->GetUnderlyingCommand().get();
- if (! sub_cmd_obj->IsMultiwordObject ())
- {
- all_okay = false;
- }
- else
- {
- CommandObject *found_cmd;
- found_cmd = sub_cmd_obj->GetSubcommandObject(sub_command.c_str(), &matches);
- if (found_cmd == nullptr)
- all_okay = false;
- else if (matches.GetSize() > 1)
- all_okay = false;
- else
- sub_cmd_obj = found_cmd;
- }
- }
-
- if (!all_okay || (sub_cmd_obj == nullptr))
- {
- std::string cmd_string;
- command.GetCommandString (cmd_string);
- if (matches.GetSize() >= 2)
- {
- StreamString s;
- s.Printf ("ambiguous command %s", cmd_string.c_str());
- size_t num_matches = matches.GetSize();
- for (size_t match_idx = 0; match_idx < num_matches; match_idx++)
- {
- s.Printf ("\n\t%s", matches.GetStringAtIndex(match_idx));
- }
- s.Printf ("\n");
- result.AppendError(s.GetData());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else if (!sub_cmd_obj)
- {
- StreamString error_msg_stream;
- GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
- cmd_string.c_str(),
- m_interpreter.GetCommandPrefix(),
- sub_command.c_str());
- result.AppendErrorWithFormat("%s",error_msg_stream.GetData());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- GenerateAdditionalHelpAvenuesMessage(&result.GetOutputStream(),
- cmd_string.c_str(),
- m_interpreter.GetCommandPrefix(),
- sub_command.c_str());
- result.GetOutputStream().Printf("\nThe closest match is '%s'. Help on it follows.\n\n", sub_cmd_obj->GetCommandName());
- }
- }
-
- sub_cmd_obj->GenerateHelpText(result);
-
- if (is_alias_command)
- {
- StreamString sstr;
- m_interpreter.GetAlias(alias_name.c_str())->GetAliasExpansion(sstr);
- result.GetOutputStream().Printf ("\n'%s' is an abbreviation for %s\n", alias_name.c_str(), sstr.GetData());
- }
- }
- else if (matches.GetSize() > 0)
- {
- Stream &output_strm = result.GetOutputStream();
- output_strm.Printf("Help requested with ambiguous command name, possible completions:\n");
- const size_t match_count = matches.GetSize();
- for (size_t i = 0; i < match_count; i++)
- {
- output_strm.Printf("\t%s\n", matches.GetStringAtIndex(i));
- }
+ // 'help' doesn't take any arguments, other than command names. If argc is 0,
+ // we show the user
+ // all commands (aliases and user commands if asked for). Otherwise every
+ // argument must be the name of a command or a sub-command.
+ if (argc == 0) {
+ uint32_t cmd_types = CommandInterpreter::eCommandTypesBuiltin;
+ if (m_options.m_show_aliases)
+ cmd_types |= CommandInterpreter::eCommandTypesAliases;
+ if (m_options.m_show_user_defined)
+ cmd_types |= CommandInterpreter::eCommandTypesUserDef;
+ if (m_options.m_show_hidden)
+ cmd_types |= CommandInterpreter::eCommandTypesHidden;
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ m_interpreter.GetHelp(result, cmd_types); // General help
+ } else {
+ // Get command object for the first command argument. Only search built-in
+ // command dictionary.
+ StringList matches;
+ auto command_name = command[0].ref;
+ cmd_obj = m_interpreter.GetCommandObject(command_name, &matches);
+
+ if (cmd_obj != nullptr) {
+ StringList matches;
+ bool all_okay = true;
+ CommandObject *sub_cmd_obj = cmd_obj;
+ // Loop down through sub_command dictionaries until we find the command
+ // object that corresponds to the help command entered.
+ std::string sub_command;
+ for (auto &entry : command.entries().drop_front()) {
+ sub_command = entry.ref;
+ matches.Clear();
+ if (sub_cmd_obj->IsAlias())
+ sub_cmd_obj =
+ ((CommandAlias *)sub_cmd_obj)->GetUnderlyingCommand().get();
+ if (!sub_cmd_obj->IsMultiwordObject()) {
+ all_okay = false;
+ break;
+ } else {
+ CommandObject *found_cmd;
+ found_cmd =
+ sub_cmd_obj->GetSubcommandObject(sub_command.c_str(), &matches);
+ if (found_cmd == nullptr || matches.GetSize() > 1) {
+ all_okay = false;
+ break;
+ } else
+ sub_cmd_obj = found_cmd;
}
- else
- {
- // Maybe the user is asking for help about a command argument rather than a command.
- const CommandArgumentType arg_type = CommandObject::LookupArgumentName (command.GetArgumentAtIndex (0));
- if (arg_type != eArgTypeLastArg)
- {
- Stream &output_strm = result.GetOutputStream ();
- CommandObject::GetArgumentHelp (output_strm, arg_type, m_interpreter);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- StreamString error_msg_stream;
- GenerateAdditionalHelpAvenuesMessage(&error_msg_stream, command.GetArgumentAtIndex(0), m_interpreter.GetCommandPrefix());
- result.AppendErrorWithFormat("%s",error_msg_stream.GetData());
- result.SetStatus (eReturnStatusFailed);
- }
+ }
+
+ if (!all_okay || (sub_cmd_obj == nullptr)) {
+ std::string cmd_string;
+ command.GetCommandString(cmd_string);
+ if (matches.GetSize() >= 2) {
+ StreamString s;
+ s.Printf("ambiguous command %s", cmd_string.c_str());
+ size_t num_matches = matches.GetSize();
+ for (size_t match_idx = 0; match_idx < num_matches; match_idx++) {
+ s.Printf("\n\t%s", matches.GetStringAtIndex(match_idx));
+ }
+ s.Printf("\n");
+ result.AppendError(s.GetString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (!sub_cmd_obj) {
+ StreamString error_msg_stream;
+ GenerateAdditionalHelpAvenuesMessage(
+ &error_msg_stream, cmd_string.c_str(),
+ m_interpreter.GetCommandPrefix(), sub_command.c_str());
+ result.AppendError(error_msg_stream.GetString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ GenerateAdditionalHelpAvenuesMessage(
+ &result.GetOutputStream(), cmd_string.c_str(),
+ m_interpreter.GetCommandPrefix(), sub_command.c_str());
+ result.GetOutputStream().Printf(
+ "\nThe closest match is '%s'. Help on it follows.\n\n",
+ sub_cmd_obj->GetCommandName().str().c_str());
}
+ }
+
+ sub_cmd_obj->GenerateHelpText(result);
+
+ if (m_interpreter.AliasExists(command_name)) {
+ StreamString sstr;
+ m_interpreter.GetAlias(command_name)->GetAliasExpansion(sstr);
+ result.GetOutputStream().Printf("\n'%s' is an abbreviation for %s\n",
+ command[0].c_str(), sstr.GetData());
+ }
+ } else if (matches.GetSize() > 0) {
+ Stream &output_strm = result.GetOutputStream();
+ output_strm.Printf("Help requested with ambiguous command name, possible "
+ "completions:\n");
+ const size_t match_count = matches.GetSize();
+ for (size_t i = 0; i < match_count; i++) {
+ output_strm.Printf("\t%s\n", matches.GetStringAtIndex(i));
+ }
+ } else {
+ // Maybe the user is asking for help about a command argument rather than
+ // a command.
+ const CommandArgumentType arg_type =
+ CommandObject::LookupArgumentName(command_name);
+ if (arg_type != eArgTypeLastArg) {
+ Stream &output_strm = result.GetOutputStream();
+ CommandObject::GetArgumentHelp(output_strm, arg_type, m_interpreter);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ StreamString error_msg_stream;
+ GenerateAdditionalHelpAvenuesMessage(&error_msg_stream, command_name,
+ m_interpreter.GetCommandPrefix(),
+ "");
+ result.AppendError(error_msg_stream.GetString());
+ result.SetStatus(eReturnStatusFailed);
+ }
}
-
- return result.Succeeded();
+ }
+
+ return result.Succeeded();
}
-int
-CommandObjectHelp::HandleCompletion(Args &input,
- int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches)
-{
- // Return the completions of the commands in the help system:
- if (cursor_index == 0)
- {
- return m_interpreter.HandleCompletionMatches (input,
- cursor_index,
- cursor_char_position,
- match_start_point,
- max_return_elements,
- word_complete,
- matches);
- }
- else
- {
- CommandObject *cmd_obj = m_interpreter.GetCommandObject (input.GetArgumentAtIndex(0));
-
- // The command that they are getting help on might be ambiguous, in which case we should complete that,
- // otherwise complete with the command the user is getting help on...
-
- if (cmd_obj)
- {
- input.Shift();
- cursor_index--;
- return cmd_obj->HandleCompletion (input,
- cursor_index,
- cursor_char_position,
- match_start_point,
- max_return_elements,
- word_complete,
- matches);
- }
- else
- {
- return m_interpreter.HandleCompletionMatches (input,
- cursor_index,
- cursor_char_position,
- match_start_point,
- max_return_elements,
- word_complete,
- matches);
- }
+int CommandObjectHelp::HandleCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches) {
+ // Return the completions of the commands in the help system:
+ if (cursor_index == 0) {
+ return m_interpreter.HandleCompletionMatches(
+ input, cursor_index, cursor_char_position, match_start_point,
+ max_return_elements, word_complete, matches);
+ } else {
+ CommandObject *cmd_obj = m_interpreter.GetCommandObject(input[0].ref);
+
+ // The command that they are getting help on might be ambiguous, in which
+ // case we should complete that,
+ // otherwise complete with the command the user is getting help on...
+
+ if (cmd_obj) {
+ input.Shift();
+ cursor_index--;
+ return cmd_obj->HandleCompletion(
+ input, cursor_index, cursor_char_position, match_start_point,
+ max_return_elements, word_complete, matches);
+ } else {
+ return m_interpreter.HandleCompletionMatches(
+ input, cursor_index, cursor_char_position, match_start_point,
+ max_return_elements, word_complete, matches);
}
+ }
}
diff --git a/source/Commands/CommandObjectHelp.h b/source/Commands/CommandObjectHelp.h
index a374a10e3e7d..721917a16852 100644
--- a/source/Commands/CommandObjectHelp.h
+++ b/source/Commands/CommandObjectHelp.h
@@ -23,105 +23,74 @@ namespace lldb_private {
// CommandObjectHelp
//-------------------------------------------------------------------------
-class CommandObjectHelp : public CommandObjectParsed
-{
+class CommandObjectHelp : public CommandObjectParsed {
public:
+ CommandObjectHelp(CommandInterpreter &interpreter);
- CommandObjectHelp (CommandInterpreter &interpreter);
-
- ~CommandObjectHelp() override;
-
- int
- HandleCompletion(Args &input,
- int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override;
-
- static void
- GenerateAdditionalHelpAvenuesMessage (Stream *s,
- const char* command,
- const char* prefix = nullptr,
- const char* subcommand = nullptr,
- bool include_apropos = true,
- bool include_type_lookup = true);
-
- class CommandOptions : public Options
- {
- public:
-
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
-
- ~CommandOptions() override {}
-
- Error
- SetOptionValue(uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'a':
- m_show_aliases = false;
- break;
- case 'u':
- m_show_user_defined = false;
- break;
- case 'h':
- m_show_hidden = true;
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting() override
- {
- m_show_aliases = true;
- m_show_user_defined = true;
- m_show_hidden = false;
- }
-
- const OptionDefinition*
- GetDefinitions() override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool m_show_aliases;
- bool m_show_user_defined;
- bool m_show_hidden;
- };
-
- Options *
- GetOptions() override
- {
- return &m_options;
+ ~CommandObjectHelp() override;
+
+ int HandleCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position, int match_start_point,
+ int max_return_elements, bool &word_complete,
+ StringList &matches) override;
+
+ static void GenerateAdditionalHelpAvenuesMessage(
+ Stream *s, llvm::StringRef command, llvm::StringRef prefix,
+ llvm::StringRef subcommand, bool include_apropos = true,
+ bool include_type_lookup = true);
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override {}
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'a':
+ m_show_aliases = false;
+ break;
+ case 'u':
+ m_show_user_defined = false;
+ break;
+ case 'h':
+ m_show_hidden = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
-
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_show_aliases = true;
+ m_show_user_defined = true;
+ m_show_hidden = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ // Instance variables to hold the values for command options.
+
+ bool m_show_aliases;
+ bool m_show_user_defined;
+ bool m_show_hidden;
+ };
+
+ Options *GetOptions() override { return &m_options; }
+
protected:
- bool
- DoExecute(Args& command,
- CommandReturnObject &result) override;
-
+ bool DoExecute(Args &command, CommandReturnObject &result) override;
+
private:
- CommandOptions m_options;
+ CommandOptions m_options;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectLanguage.cpp b/source/Commands/CommandObjectLanguage.cpp
index ebe33765acc6..f0028d65da37 100644
--- a/source/Commands/CommandObjectLanguage.cpp
+++ b/source/Commands/CommandObjectLanguage.cpp
@@ -21,13 +21,11 @@ using namespace lldb;
using namespace lldb_private;
CommandObjectLanguage::CommandObjectLanguage(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "language", "Commands specific to a source language.",
- "language <language-name> <subcommand> [<subcommand-options>]")
-{
- //Let the LanguageRuntime populates this command with subcommands
- LanguageRuntime::InitializeCommands(this);
+ : CommandObjectMultiword(
+ interpreter, "language", "Commands specific to a source language.",
+ "language <language-name> <subcommand> [<subcommand-options>]") {
+ // Let the LanguageRuntime populates this command with subcommands
+ LanguageRuntime::InitializeCommands(this);
}
-CommandObjectLanguage::~CommandObjectLanguage ()
-{
-}
+CommandObjectLanguage::~CommandObjectLanguage() {}
diff --git a/source/Commands/CommandObjectLanguage.h b/source/Commands/CommandObjectLanguage.h
index 6003a590d77d..b796c511b513 100644
--- a/source/Commands/CommandObjectLanguage.h
+++ b/source/Commands/CommandObjectLanguage.h
@@ -16,21 +16,19 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-types.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/lldb-types.h"
namespace lldb_private {
- class CommandObjectLanguage : public CommandObjectMultiword
- {
- public:
- CommandObjectLanguage (CommandInterpreter &interpreter);
-
- ~CommandObjectLanguage() override;
-
- protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result);
- };
+class CommandObjectLanguage : public CommandObjectMultiword {
+public:
+ CommandObjectLanguage(CommandInterpreter &interpreter);
+
+ ~CommandObjectLanguage() override;
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result);
+};
} // namespace lldb_private
#endif // liblldb_CommandObjectLanguage_h_
diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp
index ca6b39c0ebfa..3fdd888d2ed0 100644
--- a/source/Commands/CommandObjectLog.cpp
+++ b/source/Commands/CommandObjectLog.cpp
@@ -12,20 +12,20 @@
// Other libraries and framework includes
// Project includes
#include "CommandObjectLog.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Debugger.h"
-#include "lldb/Host/FileSpec.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Timer.h"
-#include "lldb/Core/Debugger.h"
+#include "lldb/Host/FileSpec.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
@@ -36,429 +36,358 @@
using namespace lldb;
using namespace lldb_private;
-class CommandObjectLogEnable : public CommandObjectParsed
-{
+static OptionDefinition g_log_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Set the destination file to log to." },
+ { LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." },
+ { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose logging." },
+ { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable debug logging." },
+ { LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." },
+ { LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with a timestamp." },
+ { LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." },
+ { LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." },
+ { LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append a stack backtrace to each log line." },
+ { LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to the log file instead of overwriting." },
+ // clang-format on
+};
+
+class CommandObjectLogEnable : public CommandObjectParsed {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectLogEnable(CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "log enable",
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectLogEnable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "log enable",
"Enable logging for a single log channel.",
nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentData channel_arg;
- CommandArgumentData category_arg;
-
- // Define the first (and only) variant of this arg.
- channel_arg.arg_type = eArgTypeLogChannel;
- channel_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (channel_arg);
-
- category_arg.arg_type = eArgTypeLogCategory;
- category_arg.arg_repetition = eArgRepeatPlus;
-
- arg2.push_back (category_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
+ m_options() {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData channel_arg;
+ CommandArgumentData category_arg;
+
+ // Define the first (and only) variant of this arg.
+ channel_arg.arg_type = eArgTypeLogChannel;
+ channel_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(channel_arg);
+
+ category_arg.arg_type = eArgTypeLogCategory;
+ category_arg.arg_repetition = eArgRepeatPlus;
+
+ arg2.push_back(category_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ }
+
+ ~CommandObjectLogEnable() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), log_file(), log_options(0) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ log_file.SetFile(option_arg, true);
+ break;
+ case 't':
+ log_options |= LLDB_LOG_OPTION_THREADSAFE;
+ break;
+ case 'v':
+ log_options |= LLDB_LOG_OPTION_VERBOSE;
+ break;
+ case 'g':
+ log_options |= LLDB_LOG_OPTION_DEBUG;
+ break;
+ case 's':
+ log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE;
+ break;
+ case 'T':
+ log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP;
+ break;
+ case 'p':
+ log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;
+ break;
+ case 'n':
+ log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
+ break;
+ case 'S':
+ log_options |= LLDB_LOG_OPTION_BACKTRACE;
+ break;
+ case 'a':
+ log_options |= LLDB_LOG_OPTION_APPEND;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectLogEnable() override = default;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ log_file.Clear();
+ log_options = 0;
+ }
- Options *
- GetOptions () override
- {
- return &m_options;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_log_options);
}
-// int
-// HandleArgumentCompletion (Args &input,
-// int &cursor_index,
-// int &cursor_char_position,
-// OptionElementVector &opt_element_vector,
-// int match_start_point,
-// int max_return_elements,
-// bool &word_complete,
-// StringList &matches)
-// {
-// std::string completion_str (input.GetArgumentAtIndex(cursor_index));
-// completion_str.erase (cursor_char_position);
-//
-// if (cursor_index == 1)
-// {
-// //
-// Log::AutoCompleteChannelName (completion_str.c_str(), matches);
-// }
-// return matches.GetSize();
-// }
-//
+ // Instance variables to hold the values for command options.
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- log_file (),
- log_options (0)
- {
- }
+ FileSpec log_file;
+ uint32_t log_options;
+ };
- ~CommandOptions () override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'f': log_file.SetFile(option_arg, true); break;
- case 't': log_options |= LLDB_LOG_OPTION_THREADSAFE; break;
- case 'v': log_options |= LLDB_LOG_OPTION_VERBOSE; break;
- case 'g': log_options |= LLDB_LOG_OPTION_DEBUG; break;
- case 's': log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE; break;
- case 'T': log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP; break;
- case 'p': log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;break;
- case 'n': log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; break;
- case 'S': log_options |= LLDB_LOG_OPTION_BACKTRACE; break;
- case 'a': log_options |= LLDB_LOG_OPTION_APPEND; break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
+protected:
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ if (args.GetArgumentCount() < 2) {
+ result.AppendErrorWithFormat(
+ "%s takes a log channel and one or more log types.\n",
+ m_cmd_name.c_str());
+ return false;
+ }
- void
- OptionParsingStarting () override
- {
- log_file.Clear();
- log_options = 0;
- }
+ // Store into a std::string since we're about to shift the channel off.
+ const std::string channel = args[0].ref;
+ args.Shift(); // Shift off the channel
+ char log_file[PATH_MAX];
+ if (m_options.log_file)
+ m_options.log_file.GetPath(log_file, sizeof(log_file));
+ else
+ log_file[0] = '\0';
+ bool success = m_interpreter.GetDebugger().EnableLog(
+ channel.c_str(), args.GetConstArgumentVector(), log_file,
+ m_options.log_options, result.GetErrorStream());
+ if (success)
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
+ }
+
+ CommandOptions m_options;
+};
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+class CommandObjectLogDisable : public CommandObjectParsed {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectLogDisable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "log disable",
+ "Disable one or more log channel categories.",
+ nullptr) {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData channel_arg;
+ CommandArgumentData category_arg;
- // Options table: Required for subclasses of Options.
+ // Define the first (and only) variant of this arg.
+ channel_arg.arg_type = eArgTypeLogChannel;
+ channel_arg.arg_repetition = eArgRepeatPlain;
- static OptionDefinition g_option_table[];
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(channel_arg);
- // Instance variables to hold the values for command options.
+ category_arg.arg_type = eArgTypeLogCategory;
+ category_arg.arg_repetition = eArgRepeatPlus;
- FileSpec log_file;
- uint32_t log_options;
- };
+ arg2.push_back(category_arg);
-protected:
- bool
- DoExecute (Args& args,
- CommandReturnObject &result) override
- {
- if (args.GetArgumentCount() < 2)
- {
- result.AppendErrorWithFormat("%s takes a log channel and one or more log types.\n", m_cmd_name.c_str());
- }
- else
- {
- std::string channel(args.GetArgumentAtIndex(0));
- args.Shift (); // Shift off the channel
- char log_file[PATH_MAX];
- if (m_options.log_file)
- m_options.log_file.GetPath(log_file, sizeof(log_file));
- else
- log_file[0] = '\0';
- bool success = m_interpreter.GetDebugger().EnableLog (channel.c_str(),
- args.GetConstArgumentVector(),
- log_file,
- m_options.log_options,
- result.GetErrorStream());
- if (success)
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- else
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
- }
-
- CommandOptions m_options;
-};
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ }
-OptionDefinition
-CommandObjectLogEnable::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Set the destination file to log to."},
-{ LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." },
-{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose logging." },
-{ LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable debug logging." },
-{ LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." },
-{ LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with a timestamp." },
-{ LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." },
-{ LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." },
-{ LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append a stack backtrace to each log line." },
-{ LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to the log file instead of overwriting." },
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
-};
+ ~CommandObjectLogDisable() override = default;
-class CommandObjectLogDisable : public CommandObjectParsed
-{
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectLogDisable(CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "log disable",
- "Disable one or more log channel categories.",
- nullptr)
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentData channel_arg;
- CommandArgumentData category_arg;
-
- // Define the first (and only) variant of this arg.
- channel_arg.arg_type = eArgTypeLogChannel;
- channel_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (channel_arg);
-
- category_arg.arg_type = eArgTypeLogCategory;
- category_arg.arg_repetition = eArgRepeatPlus;
-
- arg2.push_back (category_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
+protected:
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ if (args.empty()) {
+ result.AppendErrorWithFormat(
+ "%s takes a log channel and one or more log types.\n",
+ m_cmd_name.c_str());
+ return false;
}
- ~CommandObjectLogDisable() override = default;
-
-protected:
- bool
- DoExecute (Args& args,
- CommandReturnObject &result) override
- {
- const size_t argc = args.GetArgumentCount();
- if (argc == 0)
- {
- result.AppendErrorWithFormat("%s takes a log channel and one or more log types.\n", m_cmd_name.c_str());
- }
- else
- {
- Log::Callbacks log_callbacks;
-
- std::string channel(args.GetArgumentAtIndex(0));
- args.Shift (); // Shift off the channel
- if (Log::GetLogChannelCallbacks (ConstString(channel.c_str()), log_callbacks))
- {
- log_callbacks.disable (args.GetConstArgumentVector(), &result.GetErrorStream());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- else if (channel == "all")
- {
- Log::DisableAllLogChannels(&result.GetErrorStream());
- }
- else
- {
- LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str()));
- if (log_channel_sp)
- {
- log_channel_sp->Disable(args.GetConstArgumentVector(), &result.GetErrorStream());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- else
- result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0));
- }
- }
- return result.Succeeded();
+ Log::Callbacks log_callbacks;
+
+ const std::string channel = args[0].ref;
+ args.Shift(); // Shift off the channel
+ if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
+ log_callbacks.disable(args.GetConstArgumentVector(),
+ &result.GetErrorStream());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else if (channel == "all") {
+ Log::DisableAllLogChannels(&result.GetErrorStream());
+ } else {
+ LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel.data()));
+ if (log_channel_sp) {
+ log_channel_sp->Disable(args.GetConstArgumentVector(),
+ &result.GetErrorStream());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else
+ result.AppendErrorWithFormat("Invalid log channel '%s'.\n",
+ channel.data());
}
+ return result.Succeeded();
+ }
};
-class CommandObjectLogList : public CommandObjectParsed
-{
+class CommandObjectLogList : public CommandObjectParsed {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectLogList(CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "log list",
- "List the log categories for one or more log channels. If none specified, lists them all.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandArgumentData channel_arg;
-
- // Define the first (and only) variant of this arg.
- channel_arg.arg_type = eArgTypeLogChannel;
- channel_arg.arg_repetition = eArgRepeatStar;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (channel_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectLogList() override = default;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectLogList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "log list",
+ "List the log categories for one or more log "
+ "channels. If none specified, lists them all.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData channel_arg;
+
+ // Define the first (and only) variant of this arg.
+ channel_arg.arg_type = eArgTypeLogChannel;
+ channel_arg.arg_repetition = eArgRepeatStar;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(channel_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectLogList() override = default;
protected:
- bool
- DoExecute (Args& args,
- CommandReturnObject &result) override
- {
- const size_t argc = args.GetArgumentCount();
- if (argc == 0)
- {
- Log::ListAllLogChannels (&result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ if (args.empty()) {
+ Log::ListAllLogChannels(&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ for (auto &entry : args.entries()) {
+ Log::Callbacks log_callbacks;
+
+ if (Log::GetLogChannelCallbacks(ConstString(entry.ref),
+ log_callbacks)) {
+ log_callbacks.list_categories(&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else if (entry.ref == "all") {
+ Log::ListAllLogChannels(&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ LogChannelSP log_channel_sp(LogChannel::FindPlugin(entry.c_str()));
+ if (log_channel_sp) {
+ log_channel_sp->ListCategories(&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else
+ result.AppendErrorWithFormat("Invalid log channel '%s'.\n",
+ entry.c_str());
}
- else
- {
- for (size_t i=0; i<argc; ++i)
- {
- Log::Callbacks log_callbacks;
-
- std::string channel(args.GetArgumentAtIndex(i));
- if (Log::GetLogChannelCallbacks (ConstString(channel.c_str()), log_callbacks))
- {
- log_callbacks.list_categories (&result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- else if (channel == "all")
- {
- Log::ListAllLogChannels (&result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- else
- {
- LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str()));
- if (log_channel_sp)
- {
- log_channel_sp->ListCategories(&result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- else
- result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0));
- }
- }
- }
- return result.Succeeded();
+ }
}
+ return result.Succeeded();
+ }
};
-class CommandObjectLogTimer : public CommandObjectParsed
-{
+class CommandObjectLogTimer : public CommandObjectParsed {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectLogTimer(CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "log timers",
- "Enable, disable, dump, and reset LLDB internal performance timers.",
- "log timers < enable <depth> | disable | dump | increment <bool> | reset >")
- {
- }
-
- ~CommandObjectLogTimer() override = default;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectLogTimer(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "log timers",
+ "Enable, disable, dump, and reset LLDB internal "
+ "performance timers.",
+ "log timers < enable <depth> | disable | dump | "
+ "increment <bool> | reset >") {}
+
+ ~CommandObjectLogTimer() override = default;
protected:
- bool
- DoExecute (Args& args,
- CommandReturnObject &result) override
- {
- const size_t argc = args.GetArgumentCount();
- result.SetStatus(eReturnStatusFailed);
-
- if (argc == 1)
- {
- const char *sub_command = args.GetArgumentAtIndex(0);
-
- if (strcasecmp(sub_command, "enable") == 0)
- {
- Timer::SetDisplayDepth (UINT32_MAX);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- else if (strcasecmp(sub_command, "disable") == 0)
- {
- Timer::DumpCategoryTimes (&result.GetOutputStream());
- Timer::SetDisplayDepth (0);
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- else if (strcasecmp(sub_command, "dump") == 0)
- {
- Timer::DumpCategoryTimes (&result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- else if (strcasecmp(sub_command, "reset") == 0)
- {
- Timer::ResetCategoryTimes ();
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- }
- else if (argc == 2)
- {
- const char *sub_command = args.GetArgumentAtIndex(0);
-
- if (strcasecmp(sub_command, "enable") == 0)
- {
- bool success;
- uint32_t depth = StringConvert::ToUInt32(args.GetArgumentAtIndex(1), 0, 0, &success);
- if (success)
- {
- Timer::SetDisplayDepth (depth);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- else
- result.AppendError("Could not convert enable depth to an unsigned integer.");
- }
- if (strcasecmp(sub_command, "increment") == 0)
- {
- bool success;
- bool increment = Args::StringToBoolean(args.GetArgumentAtIndex(1), false, &success);
- if (success)
- {
- Timer::SetQuiet (!increment);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- else
- result.AppendError("Could not convert increment value to boolean.");
- }
- }
-
- if (!result.Succeeded())
- {
- result.AppendError("Missing subcommand");
- result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusFailed);
+
+ if (args.GetArgumentCount() == 1) {
+ auto sub_command = args[0].ref;
+
+ if (sub_command.equals_lower("enable")) {
+ Timer::SetDisplayDepth(UINT32_MAX);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else if (sub_command.equals_lower("disable")) {
+ Timer::DumpCategoryTimes(&result.GetOutputStream());
+ Timer::SetDisplayDepth(0);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else if (sub_command.equals_lower("dump")) {
+ Timer::DumpCategoryTimes(&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else if (sub_command.equals_lower("reset")) {
+ Timer::ResetCategoryTimes();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ } else if (args.GetArgumentCount() == 2) {
+ auto sub_command = args[0].ref;
+ auto param = args[1].ref;
+
+ if (sub_command.equals_lower("enable")) {
+ uint32_t depth;
+ if (param.consumeInteger(0, depth)) {
+ result.AppendError(
+ "Could not convert enable depth to an unsigned integer.");
+ } else {
+ Timer::SetDisplayDepth(depth);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
- return result.Succeeded();
+ } else if (sub_command.equals_lower("increment")) {
+ bool success;
+ bool increment = Args::StringToBoolean(param, false, &success);
+ if (success) {
+ Timer::SetQuiet(!increment);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else
+ result.AppendError("Could not convert increment value to boolean.");
+ }
+ }
+
+ if (!result.Succeeded()) {
+ result.AppendError("Missing subcommand");
+ result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
}
+ return result.Succeeded();
+ }
};
CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "log", "Commands controlling LLDB internal logging.",
- "log <subcommand> [<command-options>]")
-{
- LoadSubCommand ("enable", CommandObjectSP (new CommandObjectLogEnable (interpreter)));
- LoadSubCommand ("disable", CommandObjectSP (new CommandObjectLogDisable (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectLogList (interpreter)));
- LoadSubCommand ("timers", CommandObjectSP (new CommandObjectLogTimer (interpreter)));
+ : CommandObjectMultiword(interpreter, "log",
+ "Commands controlling LLDB internal logging.",
+ "log <subcommand> [<command-options>]") {
+ LoadSubCommand("enable",
+ CommandObjectSP(new CommandObjectLogEnable(interpreter)));
+ LoadSubCommand("disable",
+ CommandObjectSP(new CommandObjectLogDisable(interpreter)));
+ LoadSubCommand("list",
+ CommandObjectSP(new CommandObjectLogList(interpreter)));
+ LoadSubCommand("timers",
+ CommandObjectSP(new CommandObjectLogTimer(interpreter)));
}
CommandObjectLog::~CommandObjectLog() = default;
diff --git a/source/Commands/CommandObjectLog.h b/source/Commands/CommandObjectLog.h
index be5215f2bdc3..1e24a4b2ac67 100644
--- a/source/Commands/CommandObjectLog.h
+++ b/source/Commands/CommandObjectLog.h
@@ -25,21 +25,20 @@ namespace lldb_private {
// CommandObjectLog
//-------------------------------------------------------------------------
-class CommandObjectLog : public CommandObjectMultiword
-{
+class CommandObjectLog : public CommandObjectMultiword {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectLog(CommandInterpreter &interpreter);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectLog(CommandInterpreter &interpreter);
- ~CommandObjectLog() override;
+ ~CommandObjectLog() override;
private:
- //------------------------------------------------------------------
- // For CommandObjectLog only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (CommandObjectLog);
+ //------------------------------------------------------------------
+ // For CommandObjectLog only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(CommandObjectLog);
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index 7065e65ac96b..49ae92389277 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -48,1716 +48,1623 @@
using namespace lldb;
using namespace lldb_private;
-static OptionDefinition
-g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "num-per-line" ,'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNumberPerLine ,"The number of items per line to display."},
- { LLDB_OPT_SET_2, false, "binary" ,'b', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone ,"If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that uses the format, size, count and number per line settings."},
- { LLDB_OPT_SET_3, true , "type" ,'t', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone ,"The name of a type to view memory as."},
- { LLDB_OPT_SET_3, false , "offset" ,'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount ,"How many elements of the specified type to skip before starting to display data."},
- { LLDB_OPT_SET_1|
- LLDB_OPT_SET_2|
- LLDB_OPT_SET_3, false, "force" ,'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone ,"Necessary if reading over target.max-memory-read-size bytes."},
+static OptionDefinition g_read_memory_options[] = {
+ // clang-format off
+ {LLDB_OPT_SET_1, false, "num-per-line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNumberPerLine, "The number of items per line to display." },
+ {LLDB_OPT_SET_2, false, "binary", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that "
+ "uses the format, size, count and number per line settings." },
+ {LLDB_OPT_SET_3, true , "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The name of a type to view memory as." },
+ {LLDB_OPT_SET_3, false, "offset", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many elements of the specified type to skip before starting to display data." },
+ {LLDB_OPT_SET_1 |
+ LLDB_OPT_SET_2 |
+ LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Necessary if reading over target.max-memory-read-size bytes." },
+ // clang-format on
};
-class OptionGroupReadMemory : public OptionGroup
-{
+class OptionGroupReadMemory : public OptionGroup {
public:
- OptionGroupReadMemory () :
- m_num_per_line (1,1),
- m_output_as_binary (false),
- m_view_as_type(),
- m_offset(0,0)
- {
- }
+ OptionGroupReadMemory()
+ : m_num_per_line(1, 1), m_output_as_binary(false), m_view_as_type(),
+ m_offset(0, 0) {}
- ~OptionGroupReadMemory() override = default;
+ ~OptionGroupReadMemory() override = default;
- uint32_t
- GetNumDefinitions () override
- {
- return sizeof (g_option_table) / sizeof (OptionDefinition);
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- Error
- SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg) override
- {
- Error error;
- const int short_option = g_option_table[option_idx].short_option;
-
- switch (short_option)
- {
- case 'l':
- error = m_num_per_line.SetValueFromString (option_arg);
- if (m_num_per_line.GetCurrentValue() == 0)
- error.SetErrorStringWithFormat("invalid value for --num-per-line option '%s'", option_arg);
- break;
-
- case 'b':
- m_output_as_binary = true;
- break;
-
- case 't':
- error = m_view_as_type.SetValueFromString (option_arg);
- break;
-
- case 'r':
- m_force = true;
- break;
-
- case 'E':
- error = m_offset.SetValueFromString(option_arg);
- break;
-
- default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting (CommandInterpreter &interpreter) override
- {
- m_num_per_line.Clear();
- m_output_as_binary = false;
- m_view_as_type.Clear();
- m_force = false;
- m_offset.Clear();
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_read_memory_options);
+ }
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = g_read_memory_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'l':
+ error = m_num_per_line.SetValueFromString(option_value);
+ if (m_num_per_line.GetCurrentValue() == 0)
+ error.SetErrorStringWithFormat(
+ "invalid value for --num-per-line option '%s'",
+ option_value.str().c_str());
+ break;
+
+ case 'b':
+ m_output_as_binary = true;
+ break;
+
+ case 't':
+ error = m_view_as_type.SetValueFromString(option_value);
+ break;
+
+ case 'r':
+ m_force = true;
+ break;
+
+ case 'E':
+ error = m_offset.SetValueFromString(option_value);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'",
+ short_option);
+ break;
}
-
- Error
- FinalizeSettings (Target *target, OptionGroupFormat& format_options)
- {
- Error error;
- OptionValueUInt64 &byte_size_value = format_options.GetByteSizeValue();
- OptionValueUInt64 &count_value = format_options.GetCountValue();
- const bool byte_size_option_set = byte_size_value.OptionWasSet();
- const bool num_per_line_option_set = m_num_per_line.OptionWasSet();
- const bool count_option_set = format_options.GetCountValue().OptionWasSet();
-
- switch (format_options.GetFormat())
- {
- default:
- break;
-
- case eFormatBoolean:
- if (!byte_size_option_set)
- byte_size_value = 1;
- if (!num_per_line_option_set)
- m_num_per_line = 1;
- if (!count_option_set)
- format_options.GetCountValue() = 8;
- break;
-
- case eFormatCString:
- break;
-
- case eFormatInstruction:
- if (count_option_set)
- byte_size_value = target->GetArchitecture().GetMaximumOpcodeByteSize();
- m_num_per_line = 1;
- break;
-
- case eFormatAddressInfo:
- if (!byte_size_option_set)
- byte_size_value = target->GetArchitecture().GetAddressByteSize();
- m_num_per_line = 1;
- if (!count_option_set)
- format_options.GetCountValue() = 8;
- break;
-
- case eFormatPointer:
- byte_size_value = target->GetArchitecture().GetAddressByteSize();
- if (!num_per_line_option_set)
- m_num_per_line = 4;
- if (!count_option_set)
- format_options.GetCountValue() = 8;
- break;
-
- case eFormatBinary:
- case eFormatFloat:
- case eFormatOctal:
- case eFormatDecimal:
- case eFormatEnum:
- case eFormatUnicode16:
- case eFormatUnicode32:
- case eFormatUnsigned:
- case eFormatHexFloat:
- if (!byte_size_option_set)
- byte_size_value = 4;
- if (!num_per_line_option_set)
- m_num_per_line = 1;
- if (!count_option_set)
- format_options.GetCountValue() = 8;
- break;
-
- case eFormatBytes:
- case eFormatBytesWithASCII:
- if (byte_size_option_set)
- {
- if (byte_size_value > 1)
- error.SetErrorStringWithFormat(
- "display format (bytes/bytes with ASCII) conflicts with the specified byte size %" PRIu64
- "\n"
- "\tconsider using a different display format or don't specify the byte size.",
- byte_size_value.GetCurrentValue());
- }
- else
- byte_size_value = 1;
- if (!num_per_line_option_set)
- m_num_per_line = 16;
- if (!count_option_set)
- format_options.GetCountValue() = 32;
- break;
-
- case eFormatCharArray:
- case eFormatChar:
- case eFormatCharPrintable:
- if (!byte_size_option_set)
- byte_size_value = 1;
- if (!num_per_line_option_set)
- m_num_per_line = 32;
- if (!count_option_set)
- format_options.GetCountValue() = 64;
- break;
-
- case eFormatComplex:
- if (!byte_size_option_set)
- byte_size_value = 8;
- if (!num_per_line_option_set)
- m_num_per_line = 1;
- if (!count_option_set)
- format_options.GetCountValue() = 8;
- break;
-
- case eFormatComplexInteger:
- if (!byte_size_option_set)
- byte_size_value = 8;
- if (!num_per_line_option_set)
- m_num_per_line = 1;
- if (!count_option_set)
- format_options.GetCountValue() = 8;
- break;
-
- case eFormatHex:
- if (!byte_size_option_set)
- byte_size_value = 4;
- if (!num_per_line_option_set)
- {
- switch (byte_size_value)
- {
- case 1:
- case 2:
- m_num_per_line = 8;
- break;
- case 4:
- m_num_per_line = 4;
- break;
- case 8:
- m_num_per_line = 2;
- break;
- default:
- m_num_per_line = 1;
- break;
- }
- }
- if (!count_option_set)
- count_value = 8;
- break;
-
- case eFormatVectorOfChar:
- case eFormatVectorOfSInt8:
- case eFormatVectorOfUInt8:
- case eFormatVectorOfSInt16:
- case eFormatVectorOfUInt16:
- case eFormatVectorOfSInt32:
- case eFormatVectorOfUInt32:
- case eFormatVectorOfSInt64:
- case eFormatVectorOfUInt64:
- case eFormatVectorOfFloat16:
- case eFormatVectorOfFloat32:
- case eFormatVectorOfFloat64:
- case eFormatVectorOfUInt128:
- if (!byte_size_option_set)
- byte_size_value = 128;
- if (!num_per_line_option_set)
- m_num_per_line = 1;
- if (!count_option_set)
- count_value = 4;
- break;
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_num_per_line.Clear();
+ m_output_as_binary = false;
+ m_view_as_type.Clear();
+ m_force = false;
+ m_offset.Clear();
+ }
+
+ Error FinalizeSettings(Target *target, OptionGroupFormat &format_options) {
+ Error error;
+ OptionValueUInt64 &byte_size_value = format_options.GetByteSizeValue();
+ OptionValueUInt64 &count_value = format_options.GetCountValue();
+ const bool byte_size_option_set = byte_size_value.OptionWasSet();
+ const bool num_per_line_option_set = m_num_per_line.OptionWasSet();
+ const bool count_option_set = format_options.GetCountValue().OptionWasSet();
+
+ switch (format_options.GetFormat()) {
+ default:
+ break;
+
+ case eFormatBoolean:
+ if (!byte_size_option_set)
+ byte_size_value = 1;
+ if (!num_per_line_option_set)
+ m_num_per_line = 1;
+ if (!count_option_set)
+ format_options.GetCountValue() = 8;
+ break;
+
+ case eFormatCString:
+ break;
+
+ case eFormatInstruction:
+ if (count_option_set)
+ byte_size_value = target->GetArchitecture().GetMaximumOpcodeByteSize();
+ m_num_per_line = 1;
+ break;
+
+ case eFormatAddressInfo:
+ if (!byte_size_option_set)
+ byte_size_value = target->GetArchitecture().GetAddressByteSize();
+ m_num_per_line = 1;
+ if (!count_option_set)
+ format_options.GetCountValue() = 8;
+ break;
+
+ case eFormatPointer:
+ byte_size_value = target->GetArchitecture().GetAddressByteSize();
+ if (!num_per_line_option_set)
+ m_num_per_line = 4;
+ if (!count_option_set)
+ format_options.GetCountValue() = 8;
+ break;
+
+ case eFormatBinary:
+ case eFormatFloat:
+ case eFormatOctal:
+ case eFormatDecimal:
+ case eFormatEnum:
+ case eFormatUnicode16:
+ case eFormatUnicode32:
+ case eFormatUnsigned:
+ case eFormatHexFloat:
+ if (!byte_size_option_set)
+ byte_size_value = 4;
+ if (!num_per_line_option_set)
+ m_num_per_line = 1;
+ if (!count_option_set)
+ format_options.GetCountValue() = 8;
+ break;
+
+ case eFormatBytes:
+ case eFormatBytesWithASCII:
+ if (byte_size_option_set) {
+ if (byte_size_value > 1)
+ error.SetErrorStringWithFormat(
+ "display format (bytes/bytes with ASCII) conflicts with the "
+ "specified byte size %" PRIu64 "\n"
+ "\tconsider using a different display format or don't specify "
+ "the byte size.",
+ byte_size_value.GetCurrentValue());
+ } else
+ byte_size_value = 1;
+ if (!num_per_line_option_set)
+ m_num_per_line = 16;
+ if (!count_option_set)
+ format_options.GetCountValue() = 32;
+ break;
+
+ case eFormatCharArray:
+ case eFormatChar:
+ case eFormatCharPrintable:
+ if (!byte_size_option_set)
+ byte_size_value = 1;
+ if (!num_per_line_option_set)
+ m_num_per_line = 32;
+ if (!count_option_set)
+ format_options.GetCountValue() = 64;
+ break;
+
+ case eFormatComplex:
+ if (!byte_size_option_set)
+ byte_size_value = 8;
+ if (!num_per_line_option_set)
+ m_num_per_line = 1;
+ if (!count_option_set)
+ format_options.GetCountValue() = 8;
+ break;
+
+ case eFormatComplexInteger:
+ if (!byte_size_option_set)
+ byte_size_value = 8;
+ if (!num_per_line_option_set)
+ m_num_per_line = 1;
+ if (!count_option_set)
+ format_options.GetCountValue() = 8;
+ break;
+
+ case eFormatHex:
+ if (!byte_size_option_set)
+ byte_size_value = 4;
+ if (!num_per_line_option_set) {
+ switch (byte_size_value) {
+ case 1:
+ case 2:
+ m_num_per_line = 8;
+ break;
+ case 4:
+ m_num_per_line = 4;
+ break;
+ case 8:
+ m_num_per_line = 2;
+ break;
+ default:
+ m_num_per_line = 1;
+ break;
}
- return error;
+ }
+ if (!count_option_set)
+ count_value = 8;
+ break;
+
+ case eFormatVectorOfChar:
+ case eFormatVectorOfSInt8:
+ case eFormatVectorOfUInt8:
+ case eFormatVectorOfSInt16:
+ case eFormatVectorOfUInt16:
+ case eFormatVectorOfSInt32:
+ case eFormatVectorOfUInt32:
+ case eFormatVectorOfSInt64:
+ case eFormatVectorOfUInt64:
+ case eFormatVectorOfFloat16:
+ case eFormatVectorOfFloat32:
+ case eFormatVectorOfFloat64:
+ case eFormatVectorOfUInt128:
+ if (!byte_size_option_set)
+ byte_size_value = 128;
+ if (!num_per_line_option_set)
+ m_num_per_line = 1;
+ if (!count_option_set)
+ count_value = 4;
+ break;
}
+ return error;
+ }
- bool
- AnyOptionWasSet () const
- {
- return m_num_per_line.OptionWasSet() ||
- m_output_as_binary ||
- m_view_as_type.OptionWasSet() ||
- m_offset.OptionWasSet();
- }
-
- OptionValueUInt64 m_num_per_line;
- bool m_output_as_binary;
- OptionValueString m_view_as_type;
- bool m_force;
- OptionValueUInt64 m_offset;
+ bool AnyOptionWasSet() const {
+ return m_num_per_line.OptionWasSet() || m_output_as_binary ||
+ m_view_as_type.OptionWasSet() || m_offset.OptionWasSet();
+ }
+
+ OptionValueUInt64 m_num_per_line;
+ bool m_output_as_binary;
+ OptionValueString m_view_as_type;
+ bool m_force;
+ OptionValueUInt64 m_offset;
};
//----------------------------------------------------------------------
// Read memory from the inferior process
//----------------------------------------------------------------------
-class CommandObjectMemoryRead : public CommandObjectParsed
-{
+class CommandObjectMemoryRead : public CommandObjectParsed {
public:
- CommandObjectMemoryRead(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "memory read", "Read from the memory of the current target process.",
- nullptr, eCommandRequiresTarget | eCommandProcessMustBePaused),
- m_option_group(interpreter),
- m_format_options(eFormatBytesWithASCII, 1, 8),
- m_memory_options(),
- m_outfile_options(),
- m_varobj_options(),
- m_next_addr(LLDB_INVALID_ADDRESS),
- m_prev_byte_size(0),
- m_prev_format_options(eFormatBytesWithASCII, 1, 8),
- m_prev_memory_options(),
- m_prev_outfile_options(),
- m_prev_varobj_options()
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentData start_addr_arg;
- CommandArgumentData end_addr_arg;
-
- // Define the first (and only) variant of this arg.
- start_addr_arg.arg_type = eArgTypeAddressOrExpression;
- start_addr_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (start_addr_arg);
-
- // Define the first (and only) variant of this arg.
- end_addr_arg.arg_type = eArgTypeAddressOrExpression;
- end_addr_arg.arg_repetition = eArgRepeatOptional;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg2.push_back (end_addr_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
-
- // Add the "--format" and "--count" options to group 1 and 3
- m_option_group.Append (&m_format_options,
- OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_COUNT,
- LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
- m_option_group.Append (&m_format_options,
- OptionGroupFormat::OPTION_GROUP_GDB_FMT,
- LLDB_OPT_SET_1 | LLDB_OPT_SET_3);
- // Add the "--size" option to group 1 and 2
- m_option_group.Append (&m_format_options,
- OptionGroupFormat::OPTION_GROUP_SIZE,
- LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
- m_option_group.Append (&m_memory_options);
- m_option_group.Append (&m_outfile_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
- m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
- m_option_group.Finalize();
- }
+ CommandObjectMemoryRead(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "memory read",
+ "Read from the memory of the current target process.", nullptr,
+ eCommandRequiresTarget | eCommandProcessMustBePaused),
+ m_option_group(), m_format_options(eFormatBytesWithASCII, 1, 8),
+ m_memory_options(), m_outfile_options(), m_varobj_options(),
+ m_next_addr(LLDB_INVALID_ADDRESS), m_prev_byte_size(0),
+ m_prev_format_options(eFormatBytesWithASCII, 1, 8),
+ m_prev_memory_options(), m_prev_outfile_options(),
+ m_prev_varobj_options() {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData start_addr_arg;
+ CommandArgumentData end_addr_arg;
- ~CommandObjectMemoryRead() override = default;
+ // Define the first (and only) variant of this arg.
+ start_addr_arg.arg_type = eArgTypeAddressOrExpression;
+ start_addr_arg.arg_repetition = eArgRepeatPlain;
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(start_addr_arg);
- const char *
- GetRepeatCommand (Args &current_command_args, uint32_t index) override
- {
- return m_cmd_name.c_str();
- }
+ // Define the first (and only) variant of this arg.
+ end_addr_arg.arg_type = eArgTypeAddressOrExpression;
+ end_addr_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(end_addr_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+
+ // Add the "--format" and "--count" options to group 1 and 3
+ m_option_group.Append(&m_format_options,
+ OptionGroupFormat::OPTION_GROUP_FORMAT |
+ OptionGroupFormat::OPTION_GROUP_COUNT,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
+ m_option_group.Append(&m_format_options,
+ OptionGroupFormat::OPTION_GROUP_GDB_FMT,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_3);
+ // Add the "--size" option to group 1 and 2
+ m_option_group.Append(&m_format_options,
+ OptionGroupFormat::OPTION_GROUP_SIZE,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
+ m_option_group.Append(&m_memory_options);
+ m_option_group.Append(&m_outfile_options, LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
+ m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectMemoryRead() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+ const char *GetRepeatCommand(Args &current_command_args,
+ uint32_t index) override {
+ return m_cmd_name.c_str();
+ }
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- // No need to check "target" for validity as eCommandRequiresTarget ensures it is valid
- Target *target = m_exe_ctx.GetTargetPtr();
-
- const size_t argc = command.GetArgumentCount();
-
- if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2)
- {
- result.AppendErrorWithFormat ("%s takes a start address expression with an optional end address expression.\n", m_cmd_name.c_str());
- result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ // No need to check "target" for validity as eCommandRequiresTarget ensures
+ // it is valid
+ Target *target = m_exe_ctx.GetTargetPtr();
+
+ const size_t argc = command.GetArgumentCount();
+
+ if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2) {
+ result.AppendErrorWithFormat("%s takes a start address expression with "
+ "an optional end address expression.\n",
+ m_cmd_name.c_str());
+ result.AppendRawWarning("Expressions should be quoted if they contain "
+ "spaces or other special characters.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- CompilerType clang_ast_type;
- Error error;
+ CompilerType clang_ast_type;
+ Error error;
+
+ const char *view_as_type_cstr =
+ m_memory_options.m_view_as_type.GetCurrentValue();
+ if (view_as_type_cstr && view_as_type_cstr[0]) {
+ // We are viewing memory as a type
+
+ SymbolContext sc;
+ const bool exact_match = false;
+ TypeList type_list;
+ uint32_t reference_count = 0;
+ uint32_t pointer_count = 0;
+ size_t idx;
+
+#define ALL_KEYWORDS \
+ KEYWORD("const") \
+ KEYWORD("volatile") \
+ KEYWORD("restrict") \
+ KEYWORD("struct") \
+ KEYWORD("class") \
+ KEYWORD("union")
- const char *view_as_type_cstr = m_memory_options.m_view_as_type.GetCurrentValue();
- if (view_as_type_cstr && view_as_type_cstr[0])
- {
- // We are viewing memory as a type
-
- SymbolContext sc;
- const bool exact_match = false;
- TypeList type_list;
- uint32_t reference_count = 0;
- uint32_t pointer_count = 0;
- size_t idx;
-
-#define ALL_KEYWORDS \
- KEYWORD("const") \
- KEYWORD("volatile") \
- KEYWORD("restrict") \
- KEYWORD("struct") \
- KEYWORD("class") \
- KEYWORD("union")
-
#define KEYWORD(s) s,
- static const char *g_keywords[] =
- {
- ALL_KEYWORDS
- };
+ static const char *g_keywords[] = {ALL_KEYWORDS};
#undef KEYWORD
#define KEYWORD(s) (sizeof(s) - 1),
- static const int g_keyword_lengths[] =
- {
- ALL_KEYWORDS
- };
+ static const int g_keyword_lengths[] = {ALL_KEYWORDS};
#undef KEYWORD
-
+
#undef ALL_KEYWORDS
-
- static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
- std::string type_str(view_as_type_cstr);
-
- // Remove all instances of g_keywords that are followed by spaces
- for (size_t i = 0; i < g_num_keywords; ++i)
- {
- const char *keyword = g_keywords[i];
- int keyword_len = g_keyword_lengths[i];
-
- idx = 0;
- while ((idx = type_str.find (keyword, idx)) != std::string::npos)
- {
- if (type_str[idx + keyword_len] == ' ' || type_str[idx + keyword_len] == '\t')
- {
- type_str.erase(idx, keyword_len+1);
- idx = 0;
- }
- else
- {
- idx += keyword_len;
- }
- }
- }
- bool done = type_str.empty();
- //
- idx = type_str.find_first_not_of (" \t");
- if (idx > 0 && idx != std::string::npos)
- type_str.erase (0, idx);
- while (!done)
- {
- // Strip trailing spaces
- if (type_str.empty())
- done = true;
- else
- {
- switch (type_str[type_str.size()-1])
- {
- case '*':
- ++pointer_count;
- LLVM_FALLTHROUGH;
- case ' ':
- case '\t':
- type_str.erase(type_str.size()-1);
- break;
-
- case '&':
- if (reference_count == 0)
- {
- reference_count = 1;
- type_str.erase(type_str.size()-1);
- }
- else
- {
- result.AppendErrorWithFormat ("invalid type string: '%s'\n", view_as_type_cstr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- break;
-
- default:
- done = true;
- break;
- }
- }
- }
-
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- ConstString lookup_type_name(type_str.c_str());
- StackFrame *frame = m_exe_ctx.GetFramePtr();
- if (frame)
- {
- sc = frame->GetSymbolContext (eSymbolContextModule);
- if (sc.module_sp)
- {
- sc.module_sp->FindTypes (sc,
- lookup_type_name,
- exact_match,
- 1,
- searched_symbol_files,
- type_list);
- }
- }
- if (type_list.GetSize() == 0)
- {
- target->GetImages().FindTypes (sc,
- lookup_type_name,
- exact_match,
- 1,
- searched_symbol_files,
- type_list);
- }
- if (type_list.GetSize() == 0 && lookup_type_name.GetCString() && *lookup_type_name.GetCString() == '$')
- {
- if (ClangPersistentVariables *persistent_vars = llvm::dyn_cast_or_null<ClangPersistentVariables>(target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC)))
- {
- clang::TypeDecl *tdecl = llvm::dyn_cast_or_null<clang::TypeDecl>(persistent_vars->GetPersistentDecl(ConstString(lookup_type_name)));
-
- if (tdecl)
- {
- clang_ast_type.SetCompilerType(ClangASTContext::GetASTContext(&tdecl->getASTContext()),
- reinterpret_cast<lldb::opaque_compiler_type_t>(const_cast<clang::Type*>(tdecl->getTypeForDecl())));
- }
- }
+ static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
+ std::string type_str(view_as_type_cstr);
+
+ // Remove all instances of g_keywords that are followed by spaces
+ for (size_t i = 0; i < g_num_keywords; ++i) {
+ const char *keyword = g_keywords[i];
+ int keyword_len = g_keyword_lengths[i];
+
+ idx = 0;
+ while ((idx = type_str.find(keyword, idx)) != std::string::npos) {
+ if (type_str[idx + keyword_len] == ' ' ||
+ type_str[idx + keyword_len] == '\t') {
+ type_str.erase(idx, keyword_len + 1);
+ idx = 0;
+ } else {
+ idx += keyword_len;
+ }
+ }
+ }
+ bool done = type_str.empty();
+ //
+ idx = type_str.find_first_not_of(" \t");
+ if (idx > 0 && idx != std::string::npos)
+ type_str.erase(0, idx);
+ while (!done) {
+ // Strip trailing spaces
+ if (type_str.empty())
+ done = true;
+ else {
+ switch (type_str[type_str.size() - 1]) {
+ case '*':
+ ++pointer_count;
+ LLVM_FALLTHROUGH;
+ case ' ':
+ case '\t':
+ type_str.erase(type_str.size() - 1);
+ break;
+
+ case '&':
+ if (reference_count == 0) {
+ reference_count = 1;
+ type_str.erase(type_str.size() - 1);
+ } else {
+ result.AppendErrorWithFormat("invalid type string: '%s'\n",
+ view_as_type_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ break;
- if (!clang_ast_type.IsValid())
- {
- if (type_list.GetSize() == 0)
- {
- result.AppendErrorWithFormat ("unable to find any types that match the raw type '%s' for full type '%s'\n",
- lookup_type_name.GetCString(),
- view_as_type_cstr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else
- {
- TypeSP type_sp (type_list.GetTypeAtIndex(0));
- clang_ast_type = type_sp->GetFullCompilerType ();
- }
- }
-
- while (pointer_count > 0)
- {
- CompilerType pointer_type = clang_ast_type.GetPointerType();
- if (pointer_type.IsValid())
- clang_ast_type = pointer_type;
- else
- {
- result.AppendError ("unable make a pointer type\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- --pointer_count;
- }
+ default:
+ done = true;
+ break;
+ }
+ }
+ }
- m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize(nullptr);
-
- if (m_format_options.GetByteSizeValue() == 0)
- {
- result.AppendErrorWithFormat ("unable to get the byte size of the type '%s'\n",
- view_as_type_cstr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (!m_format_options.GetCountValue().OptionWasSet())
- m_format_options.GetCountValue() = 1;
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ ConstString lookup_type_name(type_str.c_str());
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
+ if (frame) {
+ sc = frame->GetSymbolContext(eSymbolContextModule);
+ if (sc.module_sp) {
+ sc.module_sp->FindTypes(sc, lookup_type_name, exact_match, 1,
+ searched_symbol_files, type_list);
}
- else
- {
- error = m_memory_options.FinalizeSettings (target, m_format_options);
+ }
+ if (type_list.GetSize() == 0) {
+ target->GetImages().FindTypes(sc, lookup_type_name, exact_match, 1,
+ searched_symbol_files, type_list);
+ }
+
+ if (type_list.GetSize() == 0 && lookup_type_name.GetCString() &&
+ *lookup_type_name.GetCString() == '$') {
+ if (ClangPersistentVariables *persistent_vars =
+ llvm::dyn_cast_or_null<ClangPersistentVariables>(
+ target->GetPersistentExpressionStateForLanguage(
+ lldb::eLanguageTypeC))) {
+ clang::TypeDecl *tdecl = llvm::dyn_cast_or_null<clang::TypeDecl>(
+ persistent_vars->GetPersistentDecl(
+ ConstString(lookup_type_name)));
+
+ if (tdecl) {
+ clang_ast_type.SetCompilerType(
+ ClangASTContext::GetASTContext(&tdecl->getASTContext()),
+ reinterpret_cast<lldb::opaque_compiler_type_t>(
+ const_cast<clang::Type *>(tdecl->getTypeForDecl())));
+ }
}
+ }
- // Look for invalid combinations of settings
- if (error.Fail())
- {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
+ if (!clang_ast_type.IsValid()) {
+ if (type_list.GetSize() == 0) {
+ result.AppendErrorWithFormat("unable to find any types that match "
+ "the raw type '%s' for full type '%s'\n",
+ lookup_type_name.GetCString(),
+ view_as_type_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ TypeSP type_sp(type_list.GetTypeAtIndex(0));
+ clang_ast_type = type_sp->GetFullCompilerType();
}
+ }
- lldb::addr_t addr;
- size_t total_byte_size = 0;
- if (argc == 0)
- {
- // Use the last address and byte size and all options as they were
- // if no options have been set
- addr = m_next_addr;
- total_byte_size = m_prev_byte_size;
- clang_ast_type = m_prev_clang_ast_type;
- if (!m_format_options.AnyOptionWasSet() &&
- !m_memory_options.AnyOptionWasSet() &&
- !m_outfile_options.AnyOptionWasSet() &&
- !m_varobj_options.AnyOptionWasSet())
- {
- m_format_options = m_prev_format_options;
- m_memory_options = m_prev_memory_options;
- m_outfile_options = m_prev_outfile_options;
- m_varobj_options = m_prev_varobj_options;
- }
+ while (pointer_count > 0) {
+ CompilerType pointer_type = clang_ast_type.GetPointerType();
+ if (pointer_type.IsValid())
+ clang_ast_type = pointer_type;
+ else {
+ result.AppendError("unable make a pointer type\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ --pointer_count;
+ }
- size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
+ m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize(nullptr);
- // TODO For non-8-bit byte addressable architectures this needs to be
- // revisited to fully support all lldb's range of formatting options.
- // Furthermore code memory reads (for those architectures) will not
- // be correctly formatted even w/o formatting options.
- size_t item_byte_size =
- target->GetArchitecture().GetDataByteSize() > 1 ?
- target->GetArchitecture().GetDataByteSize() :
- m_format_options.GetByteSizeValue().GetCurrentValue();
+ if (m_format_options.GetByteSizeValue() == 0) {
+ result.AppendErrorWithFormat(
+ "unable to get the byte size of the type '%s'\n",
+ view_as_type_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
+ if (!m_format_options.GetCountValue().OptionWasSet())
+ m_format_options.GetCountValue() = 1;
+ } else {
+ error = m_memory_options.FinalizeSettings(target, m_format_options);
+ }
- if (total_byte_size == 0)
- {
- total_byte_size = item_count * item_byte_size;
- if (total_byte_size == 0)
- total_byte_size = 32;
- }
+ // Look for invalid combinations of settings
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (argc > 0)
- addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error);
+ lldb::addr_t addr;
+ size_t total_byte_size = 0;
+ if (argc == 0) {
+ // Use the last address and byte size and all options as they were
+ // if no options have been set
+ addr = m_next_addr;
+ total_byte_size = m_prev_byte_size;
+ clang_ast_type = m_prev_clang_ast_type;
+ if (!m_format_options.AnyOptionWasSet() &&
+ !m_memory_options.AnyOptionWasSet() &&
+ !m_outfile_options.AnyOptionWasSet() &&
+ !m_varobj_options.AnyOptionWasSet()) {
+ m_format_options = m_prev_format_options;
+ m_memory_options = m_prev_memory_options;
+ m_outfile_options = m_prev_outfile_options;
+ m_varobj_options = m_prev_varobj_options;
+ }
+ }
- if (addr == LLDB_INVALID_ADDRESS)
- {
- result.AppendError("invalid start address expression.");
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
- if (argc == 2)
- {
- lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1),
- LLDB_INVALID_ADDRESS, nullptr);
- if (end_addr == LLDB_INVALID_ADDRESS)
- {
- result.AppendError("invalid end address expression.");
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else if (end_addr <= addr)
- {
- result.AppendErrorWithFormat("end address (0x%" PRIx64 ") must be greater that the start address (0x%" PRIx64 ").\n", end_addr, addr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else if (m_format_options.GetCountValue().OptionWasSet())
- {
- result.AppendErrorWithFormat("specify either the end address (0x%" PRIx64 ") or the count (--count %" PRIu64 "), not both.\n", end_addr, (uint64_t)item_count);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ // TODO For non-8-bit byte addressable architectures this needs to be
+ // revisited to fully support all lldb's range of formatting options.
+ // Furthermore code memory reads (for those architectures) will not
+ // be correctly formatted even w/o formatting options.
+ size_t item_byte_size =
+ target->GetArchitecture().GetDataByteSize() > 1
+ ? target->GetArchitecture().GetDataByteSize()
+ : m_format_options.GetByteSizeValue().GetCurrentValue();
- total_byte_size = end_addr - addr;
- item_count = total_byte_size / item_byte_size;
- }
+ const size_t num_per_line =
+ m_memory_options.m_num_per_line.GetCurrentValue();
- uint32_t max_unforced_size = target->GetMaximumMemReadSize();
-
- if (total_byte_size > max_unforced_size && !m_memory_options.m_force)
- {
- result.AppendErrorWithFormat("Normally, \'memory read\' will not read over %" PRIu32 " bytes of data.\n",max_unforced_size);
- result.AppendErrorWithFormat("Please use --force to override this restriction just once.\n");
- result.AppendErrorWithFormat("or set target.max-memory-read-size if you will often need a larger limit.\n");
- return false;
- }
-
- DataBufferSP data_sp;
- size_t bytes_read = 0;
- if (clang_ast_type.GetOpaqueQualType())
- {
- // Make sure we don't display our type as ASCII bytes like the default memory read
- if (!m_format_options.GetFormatValue().OptionWasSet())
- m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
-
- bytes_read = clang_ast_type.GetByteSize(nullptr) * m_format_options.GetCountValue().GetCurrentValue();
-
- if (argc > 0)
- addr = addr + (clang_ast_type.GetByteSize(nullptr) * m_memory_options.m_offset.GetCurrentValue());
- }
- else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
- {
- data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
- if (data_sp->GetBytes() == nullptr)
- {
- result.AppendErrorWithFormat ("can't allocate 0x%" PRIx32 " bytes for the memory read buffer, specify a smaller size to read", (uint32_t)total_byte_size);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ if (total_byte_size == 0) {
+ total_byte_size = item_count * item_byte_size;
+ if (total_byte_size == 0)
+ total_byte_size = 32;
+ }
- Address address(addr, nullptr);
- bytes_read = target->ReadMemory(address, false, data_sp->GetBytes (), data_sp->GetByteSize(), error);
- if (bytes_read == 0)
- {
- const char *error_cstr = error.AsCString();
- if (error_cstr && error_cstr[0])
- {
- result.AppendError(error_cstr);
- }
- else
- {
- result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
- }
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (bytes_read < total_byte_size)
- result.AppendWarningWithFormat("Not all bytes (%" PRIu64 "/%" PRIu64 ") were able to be read from 0x%" PRIx64 ".\n", (uint64_t)bytes_read, (uint64_t)total_byte_size, addr);
- }
- else
- {
- // we treat c-strings as a special case because they do not have a fixed size
- if (m_format_options.GetByteSizeValue().OptionWasSet() && !m_format_options.HasGDBFormat())
- item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
- else
- item_byte_size = target->GetMaximumSizeOfStringSummary();
- if (!m_format_options.GetCountValue().OptionWasSet())
- item_count = 1;
- data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary
- if (data_sp->GetBytes() == nullptr)
- {
- result.AppendErrorWithFormat ("can't allocate 0x%" PRIx64 " bytes for the memory read buffer, specify a smaller size to read", (uint64_t)((item_byte_size+1) * item_count));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- uint8_t *data_ptr = data_sp->GetBytes();
- auto data_addr = addr;
- auto count = item_count;
- item_count = 0;
- bool break_on_no_NULL = false;
- while (item_count < count)
- {
- std::string buffer;
- buffer.resize(item_byte_size+1,0);
- Error error;
- size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0], item_byte_size+1, error);
- if (error.Fail())
- {
- result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (item_byte_size == read)
- {
- result.AppendWarningWithFormat("unable to find a NULL terminated string at 0x%" PRIx64 ".Consider increasing the maximum read length.\n", data_addr);
- --read;
- break_on_no_NULL = true;
- }
- else
- ++read; // account for final NULL byte
-
- memcpy(data_ptr, &buffer[0], read);
- data_ptr += read;
- data_addr += read;
- bytes_read += read;
- item_count++; // if we break early we know we only read item_count strings
-
- if (break_on_no_NULL)
- break;
- }
- data_sp.reset(new DataBufferHeap(data_sp->GetBytes(),bytes_read+1));
- }
+ if (argc > 0)
+ addr = Args::StringToAddress(&m_exe_ctx, command[0].ref,
+ LLDB_INVALID_ADDRESS, &error);
- m_next_addr = addr + bytes_read;
- m_prev_byte_size = bytes_read;
- m_prev_format_options = m_format_options;
- m_prev_memory_options = m_memory_options;
- m_prev_outfile_options = m_outfile_options;
- m_prev_varobj_options = m_varobj_options;
- m_prev_clang_ast_type = clang_ast_type;
-
- StreamFile outfile_stream;
- Stream *output_stream = nullptr;
- const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue();
- if (outfile_spec)
- {
- char path[PATH_MAX];
- outfile_spec.GetPath (path, sizeof(path));
-
- uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
- const bool append = m_outfile_options.GetAppend().GetCurrentValue();
- if (append)
- open_options |= File::eOpenOptionAppend;
-
- if (outfile_stream.GetFile ().Open (path, open_options).Success())
- {
- if (m_memory_options.m_output_as_binary)
- {
- const size_t bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read);
- if (bytes_written > 0)
- {
- result.GetOutputStream().Printf ("%zi bytes %s to '%s'\n",
- bytes_written,
- append ? "appended" : "written",
- path);
- return true;
- }
- else
- {
- result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- // We are going to write ASCII to the file just point the
- // output_stream to our outfile_stream...
- output_stream = &outfile_stream;
- }
- }
- else
- {
- result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path, append ? "append" : "write");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ if (addr == LLDB_INVALID_ADDRESS) {
+ result.AppendError("invalid start address expression.");
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (argc == 2) {
+ lldb::addr_t end_addr = Args::StringToAddress(
+ &m_exe_ctx, command[1].ref, LLDB_INVALID_ADDRESS, nullptr);
+ if (end_addr == LLDB_INVALID_ADDRESS) {
+ result.AppendError("invalid end address expression.");
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (end_addr <= addr) {
+ result.AppendErrorWithFormat(
+ "end address (0x%" PRIx64
+ ") must be greater that the start address (0x%" PRIx64 ").\n",
+ end_addr, addr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (m_format_options.GetCountValue().OptionWasSet()) {
+ result.AppendErrorWithFormat(
+ "specify either the end address (0x%" PRIx64
+ ") or the count (--count %" PRIu64 "), not both.\n",
+ end_addr, (uint64_t)item_count);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ total_byte_size = end_addr - addr;
+ item_count = total_byte_size / item_byte_size;
+ }
+
+ uint32_t max_unforced_size = target->GetMaximumMemReadSize();
+
+ if (total_byte_size > max_unforced_size && !m_memory_options.m_force) {
+ result.AppendErrorWithFormat(
+ "Normally, \'memory read\' will not read over %" PRIu32
+ " bytes of data.\n",
+ max_unforced_size);
+ result.AppendErrorWithFormat(
+ "Please use --force to override this restriction just once.\n");
+ result.AppendErrorWithFormat("or set target.max-memory-read-size if you "
+ "will often need a larger limit.\n");
+ return false;
+ }
+
+ DataBufferSP data_sp;
+ size_t bytes_read = 0;
+ if (clang_ast_type.GetOpaqueQualType()) {
+ // Make sure we don't display our type as ASCII bytes like the default
+ // memory read
+ if (!m_format_options.GetFormatValue().OptionWasSet())
+ m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
+
+ bytes_read = clang_ast_type.GetByteSize(nullptr) *
+ m_format_options.GetCountValue().GetCurrentValue();
+
+ if (argc > 0)
+ addr = addr + (clang_ast_type.GetByteSize(nullptr) *
+ m_memory_options.m_offset.GetCurrentValue());
+ } else if (m_format_options.GetFormatValue().GetCurrentValue() !=
+ eFormatCString) {
+ data_sp.reset(new DataBufferHeap(total_byte_size, '\0'));
+ if (data_sp->GetBytes() == nullptr) {
+ result.AppendErrorWithFormat(
+ "can't allocate 0x%" PRIx32
+ " bytes for the memory read buffer, specify a smaller size to read",
+ (uint32_t)total_byte_size);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Address address(addr, nullptr);
+ bytes_read = target->ReadMemory(address, false, data_sp->GetBytes(),
+ data_sp->GetByteSize(), error);
+ if (bytes_read == 0) {
+ const char *error_cstr = error.AsCString();
+ if (error_cstr && error_cstr[0]) {
+ result.AppendError(error_cstr);
+ } else {
+ result.AppendErrorWithFormat(
+ "failed to read memory from 0x%" PRIx64 ".\n", addr);
}
- else
- {
- output_stream = &result.GetOutputStream();
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (bytes_read < total_byte_size)
+ result.AppendWarningWithFormat(
+ "Not all bytes (%" PRIu64 "/%" PRIu64
+ ") were able to be read from 0x%" PRIx64 ".\n",
+ (uint64_t)bytes_read, (uint64_t)total_byte_size, addr);
+ } else {
+ // we treat c-strings as a special case because they do not have a fixed
+ // size
+ if (m_format_options.GetByteSizeValue().OptionWasSet() &&
+ !m_format_options.HasGDBFormat())
+ item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
+ else
+ item_byte_size = target->GetMaximumSizeOfStringSummary();
+ if (!m_format_options.GetCountValue().OptionWasSet())
+ item_count = 1;
+ data_sp.reset(new DataBufferHeap((item_byte_size + 1) * item_count,
+ '\0')); // account for NULLs as necessary
+ if (data_sp->GetBytes() == nullptr) {
+ result.AppendErrorWithFormat(
+ "can't allocate 0x%" PRIx64
+ " bytes for the memory read buffer, specify a smaller size to read",
+ (uint64_t)((item_byte_size + 1) * item_count));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ uint8_t *data_ptr = data_sp->GetBytes();
+ auto data_addr = addr;
+ auto count = item_count;
+ item_count = 0;
+ bool break_on_no_NULL = false;
+ while (item_count < count) {
+ std::string buffer;
+ buffer.resize(item_byte_size + 1, 0);
+ Error error;
+ size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0],
+ item_byte_size + 1, error);
+ if (error.Fail()) {
+ result.AppendErrorWithFormat(
+ "failed to read memory from 0x%" PRIx64 ".\n", addr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
- if (clang_ast_type.GetOpaqueQualType())
- {
- for (uint32_t i = 0; i<item_count; ++i)
- {
- addr_t item_addr = addr + (i * item_byte_size);
- Address address (item_addr);
- StreamString name_strm;
- name_strm.Printf ("0x%" PRIx64, item_addr);
- ValueObjectSP valobj_sp (ValueObjectMemory::Create (exe_scope,
- name_strm.GetString().c_str(),
- address,
- clang_ast_type));
- if (valobj_sp)
- {
- Format format = m_format_options.GetFormat();
- if (format != eFormatDefault)
- valobj_sp->SetFormat (format);
-
- DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(eLanguageRuntimeDescriptionDisplayVerbosityFull,format));
-
- valobj_sp->Dump(*output_stream,options);
- }
- else
- {
- result.AppendErrorWithFormat ("failed to create a value object for: (%s) %s\n",
- view_as_type_cstr,
- name_strm.GetString().c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
+ if (item_byte_size == read) {
+ result.AppendWarningWithFormat(
+ "unable to find a NULL terminated string at 0x%" PRIx64
+ ".Consider increasing the maximum read length.\n",
+ data_addr);
+ --read;
+ break_on_no_NULL = true;
+ } else
+ ++read; // account for final NULL byte
+
+ memcpy(data_ptr, &buffer[0], read);
+ data_ptr += read;
+ data_addr += read;
+ bytes_read += read;
+ item_count++; // if we break early we know we only read item_count
+ // strings
+
+ if (break_on_no_NULL)
+ break;
+ }
+ data_sp.reset(new DataBufferHeap(data_sp->GetBytes(), bytes_read + 1));
+ }
+
+ m_next_addr = addr + bytes_read;
+ m_prev_byte_size = bytes_read;
+ m_prev_format_options = m_format_options;
+ m_prev_memory_options = m_memory_options;
+ m_prev_outfile_options = m_outfile_options;
+ m_prev_varobj_options = m_varobj_options;
+ m_prev_clang_ast_type = clang_ast_type;
+
+ StreamFile outfile_stream;
+ Stream *output_stream = nullptr;
+ const FileSpec &outfile_spec =
+ m_outfile_options.GetFile().GetCurrentValue();
+ if (outfile_spec) {
+ char path[PATH_MAX];
+ outfile_spec.GetPath(path, sizeof(path));
+
+ uint32_t open_options =
+ File::eOpenOptionWrite | File::eOpenOptionCanCreate;
+ const bool append = m_outfile_options.GetAppend().GetCurrentValue();
+ if (append)
+ open_options |= File::eOpenOptionAppend;
+
+ if (outfile_stream.GetFile().Open(path, open_options).Success()) {
+ if (m_memory_options.m_output_as_binary) {
+ const size_t bytes_written =
+ outfile_stream.Write(data_sp->GetBytes(), bytes_read);
+ if (bytes_written > 0) {
+ result.GetOutputStream().Printf(
+ "%zi bytes %s to '%s'\n", bytes_written,
+ append ? "appended" : "written", path);
return true;
+ } else {
+ result.AppendErrorWithFormat("Failed to write %" PRIu64
+ " bytes to '%s'.\n",
+ (uint64_t)bytes_read, path);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ // We are going to write ASCII to the file just point the
+ // output_stream to our outfile_stream...
+ output_stream = &outfile_stream;
}
+ } else {
+ result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path,
+ append ? "append" : "write");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ output_stream = &result.GetOutputStream();
+ }
- result.SetStatus(eReturnStatusSuccessFinishResult);
- DataExtractor data (data_sp,
- target->GetArchitecture().GetByteOrder(),
- target->GetArchitecture().GetAddressByteSize(),
- target->GetArchitecture().GetDataByteSize());
-
- Format format = m_format_options.GetFormat();
- if ( ( (format == eFormatChar) || (format == eFormatCharPrintable) )
- && (item_byte_size != 1))
- {
- // if a count was not passed, or it is 1
- if (!m_format_options.GetCountValue().OptionWasSet() || item_count == 1)
- {
- // this turns requests such as
- // memory read -fc -s10 -c1 *charPtrPtr
- // which make no sense (what is a char of size 10?)
- // into a request for fetching 10 chars of size 1 from the same memory location
- format = eFormatCharArray;
- item_count = item_byte_size;
- item_byte_size = 1;
- }
- else
- {
- // here we passed a count, and it was not 1
- // so we have a byte_size and a count
- // we could well multiply those, but instead let's just fail
- result.AppendErrorWithFormat("reading memory as characters of size %" PRIu64 " is not supported", (uint64_t)item_byte_size);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
+ if (clang_ast_type.GetOpaqueQualType()) {
+ for (uint32_t i = 0; i < item_count; ++i) {
+ addr_t item_addr = addr + (i * item_byte_size);
+ Address address(item_addr);
+ StreamString name_strm;
+ name_strm.Printf("0x%" PRIx64, item_addr);
+ ValueObjectSP valobj_sp(ValueObjectMemory::Create(
+ exe_scope, name_strm.GetString(), address, clang_ast_type));
+ if (valobj_sp) {
+ Format format = m_format_options.GetFormat();
+ if (format != eFormatDefault)
+ valobj_sp->SetFormat(format);
+
+ DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
+ eLanguageRuntimeDescriptionDisplayVerbosityFull, format));
+
+ valobj_sp->Dump(*output_stream, options);
+ } else {
+ result.AppendErrorWithFormat(
+ "failed to create a value object for: (%s) %s\n",
+ view_as_type_cstr, name_strm.GetData());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ }
+ return true;
+ }
- assert (output_stream);
- size_t bytes_dumped = data.Dump (output_stream,
- 0,
- format,
- item_byte_size,
- item_count,
- num_per_line / target->GetArchitecture().GetDataByteSize(),
- addr,
- 0,
- 0,
- exe_scope);
- m_next_addr = addr + bytes_dumped;
- output_stream->EOL();
- return true;
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ DataExtractor data(data_sp, target->GetArchitecture().GetByteOrder(),
+ target->GetArchitecture().GetAddressByteSize(),
+ target->GetArchitecture().GetDataByteSize());
+
+ Format format = m_format_options.GetFormat();
+ if (((format == eFormatChar) || (format == eFormatCharPrintable)) &&
+ (item_byte_size != 1)) {
+ // if a count was not passed, or it is 1
+ if (!m_format_options.GetCountValue().OptionWasSet() || item_count == 1) {
+ // this turns requests such as
+ // memory read -fc -s10 -c1 *charPtrPtr
+ // which make no sense (what is a char of size 10?)
+ // into a request for fetching 10 chars of size 1 from the same memory
+ // location
+ format = eFormatCharArray;
+ item_count = item_byte_size;
+ item_byte_size = 1;
+ } else {
+ // here we passed a count, and it was not 1
+ // so we have a byte_size and a count
+ // we could well multiply those, but instead let's just fail
+ result.AppendErrorWithFormat(
+ "reading memory as characters of size %" PRIu64 " is not supported",
+ (uint64_t)item_byte_size);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
- OptionGroupOptions m_option_group;
- OptionGroupFormat m_format_options;
- OptionGroupReadMemory m_memory_options;
- OptionGroupOutputFile m_outfile_options;
- OptionGroupValueObjectDisplay m_varobj_options;
- lldb::addr_t m_next_addr;
- lldb::addr_t m_prev_byte_size;
- OptionGroupFormat m_prev_format_options;
- OptionGroupReadMemory m_prev_memory_options;
- OptionGroupOutputFile m_prev_outfile_options;
- OptionGroupValueObjectDisplay m_prev_varobj_options;
- CompilerType m_prev_clang_ast_type;
+ assert(output_stream);
+ size_t bytes_dumped =
+ data.Dump(output_stream, 0, format, item_byte_size, item_count,
+ num_per_line / target->GetArchitecture().GetDataByteSize(),
+ addr, 0, 0, exe_scope);
+ m_next_addr = addr + bytes_dumped;
+ output_stream->EOL();
+ return true;
+ }
+
+ OptionGroupOptions m_option_group;
+ OptionGroupFormat m_format_options;
+ OptionGroupReadMemory m_memory_options;
+ OptionGroupOutputFile m_outfile_options;
+ OptionGroupValueObjectDisplay m_varobj_options;
+ lldb::addr_t m_next_addr;
+ lldb::addr_t m_prev_byte_size;
+ OptionGroupFormat m_prev_format_options;
+ OptionGroupReadMemory m_prev_memory_options;
+ OptionGroupOutputFile m_prev_outfile_options;
+ OptionGroupValueObjectDisplay m_prev_varobj_options;
+ CompilerType m_prev_clang_ast_type;
};
-OptionDefinition
-g_memory_find_option_table[] =
-{
- { LLDB_OPT_SET_1, true, "expression", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."},
- { LLDB_OPT_SET_2, true, "string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Use text to find a byte pattern."},
- { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many times to perform the search."},
- { LLDB_OPT_SET_ALL, false, "dump-offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."},
+OptionDefinition g_memory_find_option_table[] = {
+ // clang-format off
+ {LLDB_OPT_SET_1, true, "expression", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."},
+ {LLDB_OPT_SET_2, true, "string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Use text to find a byte pattern."},
+ {LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many times to perform the search."},
+ {LLDB_OPT_SET_ALL, false, "dump-offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."},
+ // clang-format on
};
//----------------------------------------------------------------------
// Find the specified data in memory
//----------------------------------------------------------------------
-class CommandObjectMemoryFind : public CommandObjectParsed
-{
+class CommandObjectMemoryFind : public CommandObjectParsed {
public:
- class OptionGroupFindMemory : public OptionGroup
- {
+ class OptionGroupFindMemory : public OptionGroup {
public:
- OptionGroupFindMemory () :
- OptionGroup(),
- m_count(1),
- m_offset(0)
- {
- }
+ OptionGroupFindMemory() : OptionGroup(), m_count(1), m_offset(0) {}
~OptionGroupFindMemory() override = default;
- uint32_t
- GetNumDefinitions () override
- {
- return sizeof (g_memory_find_option_table) / sizeof (OptionDefinition);
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_memory_find_option_table;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_memory_find_option_table);
}
-
- Error
- SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg) override
- {
- Error error;
- const int short_option = g_memory_find_option_table[option_idx].short_option;
-
- switch (short_option)
- {
- case 'e':
- m_expr.SetValueFromString(option_arg);
- break;
-
- case 's':
- m_string.SetValueFromString(option_arg);
- break;
-
- case 'c':
- if (m_count.SetValueFromString(option_arg).Fail())
- error.SetErrorString("unrecognized value for count");
- break;
-
- case 'o':
- if (m_offset.SetValueFromString(option_arg).Fail())
- error.SetErrorString("unrecognized value for dump-offset");
- break;
- default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
- break;
- }
- return error;
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option =
+ g_memory_find_option_table[option_idx].short_option;
+
+ switch (short_option) {
+ case 'e':
+ m_expr.SetValueFromString(option_value);
+ break;
+
+ case 's':
+ m_string.SetValueFromString(option_value);
+ break;
+
+ case 'c':
+ if (m_count.SetValueFromString(option_value).Fail())
+ error.SetErrorString("unrecognized value for count");
+ break;
+
+ case 'o':
+ if (m_offset.SetValueFromString(option_value).Fail())
+ error.SetErrorString("unrecognized value for dump-offset");
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'",
+ short_option);
+ break;
+ }
+ return error;
}
-
- void
- OptionParsingStarting (CommandInterpreter &interpreter) override
- {
- m_expr.Clear();
- m_string.Clear();
- m_count.Clear();
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_expr.Clear();
+ m_string.Clear();
+ m_count.Clear();
}
-
- OptionValueString m_expr;
- OptionValueString m_string;
- OptionValueUInt64 m_count;
- OptionValueUInt64 m_offset;
+
+ OptionValueString m_expr;
+ OptionValueString m_string;
+ OptionValueUInt64 m_count;
+ OptionValueUInt64 m_offset;
};
CommandObjectMemoryFind(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "memory find", "Find a value in the memory of the current target process.",
- nullptr, eCommandRequiresProcess | eCommandProcessMustBeLaunched),
- m_option_group(interpreter),
- m_memory_options()
- {
+ : CommandObjectParsed(
+ interpreter, "memory find",
+ "Find a value in the memory of the current target process.",
+ nullptr, eCommandRequiresProcess | eCommandProcessMustBeLaunched),
+ m_option_group(), m_memory_options() {
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
CommandArgumentData addr_arg;
CommandArgumentData value_arg;
-
+
// Define the first (and only) variant of this arg.
addr_arg.arg_type = eArgTypeAddressOrExpression;
addr_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (addr_arg);
-
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(addr_arg);
+
// Define the first (and only) variant of this arg.
value_arg.arg_type = eArgTypeAddressOrExpression;
value_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg2.push_back (value_arg);
-
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(value_arg);
+
// Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
-
- m_option_group.Append (&m_memory_options);
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+
+ m_option_group.Append(&m_memory_options);
m_option_group.Finalize();
}
~CommandObjectMemoryFind() override = default;
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
-
+ Options *GetOptions() override { return &m_option_group; }
+
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
- Process *process = m_exe_ctx.GetProcessPtr();
+ class ProcessMemoryIterator {
+ public:
+ ProcessMemoryIterator(ProcessSP process_sp, lldb::addr_t base)
+ : m_process_sp(process_sp), m_base_addr(base), m_is_valid(true) {
+ lldbassert(process_sp.get() != nullptr);
+ }
- const size_t argc = command.GetArgumentCount();
+ bool IsValid() { return m_is_valid; }
- if (argc != 2)
- {
- result.AppendError("two addresses needed for memory find");
- return false;
- }
+ uint8_t operator[](lldb::addr_t offset) {
+ if (!IsValid())
+ return 0;
+ uint8_t retval = 0;
Error error;
- lldb::addr_t low_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0),LLDB_INVALID_ADDRESS,&error);
- if (low_addr == LLDB_INVALID_ADDRESS || error.Fail())
- {
- result.AppendError("invalid low address");
- return false;
- }
- lldb::addr_t high_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1),LLDB_INVALID_ADDRESS,&error);
- if (high_addr == LLDB_INVALID_ADDRESS || error.Fail())
- {
- result.AppendError("invalid high address");
- return false;
+ if (0 ==
+ m_process_sp->ReadMemory(m_base_addr + offset, &retval, 1, error)) {
+ m_is_valid = false;
+ return 0;
}
- if (high_addr <= low_addr)
- {
- result.AppendError("starting address must be smaller than ending address");
+ return retval;
+ }
+
+ private:
+ ProcessSP m_process_sp;
+ lldb::addr_t m_base_addr;
+ bool m_is_valid;
+ };
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ // No need to check "process" for validity as eCommandRequiresProcess
+ // ensures it is valid
+ Process *process = m_exe_ctx.GetProcessPtr();
+
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc != 2) {
+ result.AppendError("two addresses needed for memory find");
+ return false;
+ }
+
+ Error error;
+ lldb::addr_t low_addr = Args::StringToAddress(&m_exe_ctx, command[0].ref,
+ LLDB_INVALID_ADDRESS, &error);
+ if (low_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
+ result.AppendError("invalid low address");
+ return false;
+ }
+ lldb::addr_t high_addr = Args::StringToAddress(
+ &m_exe_ctx, command[1].ref, LLDB_INVALID_ADDRESS, &error);
+ if (high_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
+ result.AppendError("invalid high address");
+ return false;
+ }
+
+ if (high_addr <= low_addr) {
+ result.AppendError(
+ "starting address must be smaller than ending address");
+ return false;
+ }
+
+ lldb::addr_t found_location = LLDB_INVALID_ADDRESS;
+
+ DataBufferHeap buffer;
+
+ if (m_memory_options.m_string.OptionWasSet())
+ buffer.CopyData(m_memory_options.m_string.GetStringValue());
+ else if (m_memory_options.m_expr.OptionWasSet()) {
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
+ ValueObjectSP result_sp;
+ if ((eExpressionCompleted ==
+ process->GetTarget().EvaluateExpression(
+ m_memory_options.m_expr.GetStringValue(), frame, result_sp)) &&
+ result_sp) {
+ uint64_t value = result_sp->GetValueAsUnsigned(0);
+ switch (result_sp->GetCompilerType().GetByteSize(nullptr)) {
+ case 1: {
+ uint8_t byte = (uint8_t)value;
+ buffer.CopyData(&byte, 1);
+ } break;
+ case 2: {
+ uint16_t word = (uint16_t)value;
+ buffer.CopyData(&word, 2);
+ } break;
+ case 4: {
+ uint32_t lword = (uint32_t)value;
+ buffer.CopyData(&lword, 4);
+ } break;
+ case 8: {
+ buffer.CopyData(&value, 8);
+ } break;
+ case 3:
+ case 5:
+ case 6:
+ case 7:
+ result.AppendError("unknown type. pass a string instead");
return false;
- }
-
- lldb::addr_t found_location = LLDB_INVALID_ADDRESS;
-
- DataBufferHeap buffer;
-
- if (m_memory_options.m_string.OptionWasSet())
- buffer.CopyData(m_memory_options.m_string.GetStringValue(), strlen(m_memory_options.m_string.GetStringValue()));
- else if (m_memory_options.m_expr.OptionWasSet())
- {
- StackFrame* frame = m_exe_ctx.GetFramePtr();
- ValueObjectSP result_sp;
- if ((eExpressionCompleted == process->GetTarget().EvaluateExpression(m_memory_options.m_expr.GetStringValue(), frame, result_sp)) &&
- result_sp)
- {
- uint64_t value = result_sp->GetValueAsUnsigned(0);
- switch (result_sp->GetCompilerType().GetByteSize(nullptr))
- {
- case 1: {
- uint8_t byte = (uint8_t)value;
- buffer.CopyData(&byte,1);
- }
- break;
- case 2: {
- uint16_t word = (uint16_t)value;
- buffer.CopyData(&word,2);
- }
- break;
- case 4: {
- uint32_t lword = (uint32_t)value;
- buffer.CopyData(&lword,4);
- }
- break;
- case 8: {
- buffer.CopyData(&value, 8);
- }
- break;
- case 3:
- case 5:
- case 6:
- case 7:
- result.AppendError("unknown type. pass a string instead");
- return false;
- default:
- result.AppendError("result size larger than 8 bytes. pass a string instead");
- return false;
- }
- }
- else
- {
- result.AppendError("expression evaluation failed. pass a string instead");
- return false;
- }
- }
- else
- {
- result.AppendError("please pass either a block of text, or an expression to evaluate.");
+ default:
+ result.AppendError(
+ "result size larger than 8 bytes. pass a string instead");
return false;
+ }
+ } else {
+ result.AppendError(
+ "expression evaluation failed. pass a string instead");
+ return false;
}
-
- size_t count = m_memory_options.m_count.GetCurrentValue();
- found_location = low_addr;
- bool ever_found = false;
- while (count)
- {
- found_location = Search(found_location, high_addr, buffer.GetBytes(), buffer.GetByteSize());
- if (found_location == LLDB_INVALID_ADDRESS)
- {
- if (!ever_found)
- {
- result.AppendMessage("data not found within the range.\n");
- result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
- }
- else
- result.AppendMessage("no more matches within the range.\n");
- break;
- }
- result.AppendMessageWithFormat("data found at location: 0x%" PRIx64 "\n", found_location);
-
- DataBufferHeap dumpbuffer(32,0);
- process->ReadMemory(found_location+m_memory_options.m_offset.GetCurrentValue(), dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), error);
- if (!error.Fail())
- {
- DataExtractor data(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), process->GetByteOrder(), process->GetAddressByteSize());
- data.Dump(&result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1, dumpbuffer.GetByteSize(), 16, found_location+m_memory_options.m_offset.GetCurrentValue(), 0, 0);
- result.GetOutputStream().EOL();
- }
+ } else {
+ result.AppendError(
+ "please pass either a block of text, or an expression to evaluate.");
+ return false;
+ }
- --count;
- found_location++;
- ever_found = true;
+ size_t count = m_memory_options.m_count.GetCurrentValue();
+ found_location = low_addr;
+ bool ever_found = false;
+ while (count) {
+ found_location = FastSearch(found_location, high_addr, buffer.GetBytes(),
+ buffer.GetByteSize());
+ if (found_location == LLDB_INVALID_ADDRESS) {
+ if (!ever_found) {
+ result.AppendMessage("data not found within the range.\n");
+ result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
+ } else
+ result.AppendMessage("no more matches within the range.\n");
+ break;
}
-
- result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- return true;
+ result.AppendMessageWithFormat("data found at location: 0x%" PRIx64 "\n",
+ found_location);
+
+ DataBufferHeap dumpbuffer(32, 0);
+ process->ReadMemory(
+ found_location + m_memory_options.m_offset.GetCurrentValue(),
+ dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), error);
+ if (!error.Fail()) {
+ DataExtractor data(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
+ process->GetByteOrder(),
+ process->GetAddressByteSize());
+ data.Dump(&result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1,
+ dumpbuffer.GetByteSize(), 16,
+ found_location + m_memory_options.m_offset.GetCurrentValue(),
+ 0, 0);
+ result.GetOutputStream().EOL();
+ }
+
+ --count;
+ found_location++;
+ ever_found = true;
+ }
+
+ result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
+ return true;
}
-
- lldb::addr_t
- Search (lldb::addr_t low,
- lldb::addr_t high,
- uint8_t* buffer,
- size_t buffer_size)
- {
- Process *process = m_exe_ctx.GetProcessPtr();
- DataBufferHeap heap(buffer_size, 0);
- for (auto ptr = low;
- ptr < high;
- ptr++)
- {
- Error error;
- process->ReadMemory(ptr, heap.GetBytes(), buffer_size, error);
- if (error.Fail())
- return LLDB_INVALID_ADDRESS;
- if (memcmp(heap.GetBytes(), buffer, buffer_size) == 0)
- return ptr;
- }
- return LLDB_INVALID_ADDRESS;
+
+ lldb::addr_t FastSearch(lldb::addr_t low, lldb::addr_t high, uint8_t *buffer,
+ size_t buffer_size) {
+ const size_t region_size = high - low;
+
+ if (region_size < buffer_size)
+ return LLDB_INVALID_ADDRESS;
+
+ std::vector<size_t> bad_char_heuristic(256, buffer_size);
+ ProcessSP process_sp = m_exe_ctx.GetProcessSP();
+ ProcessMemoryIterator iterator(process_sp, low);
+
+ for (size_t idx = 0; idx < buffer_size - 1; idx++) {
+ decltype(bad_char_heuristic)::size_type bcu_idx = buffer[idx];
+ bad_char_heuristic[bcu_idx] = buffer_size - idx - 1;
+ }
+ for (size_t s = 0; s <= (region_size - buffer_size);) {
+ int64_t j = buffer_size - 1;
+ while (j >= 0 && buffer[j] == iterator[s + j])
+ j--;
+ if (j < 0)
+ return low + s;
+ else
+ s += bad_char_heuristic[iterator[s + buffer_size - 1]];
}
-
- OptionGroupOptions m_option_group;
- OptionGroupFindMemory m_memory_options;
+
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ OptionGroupOptions m_option_group;
+ OptionGroupFindMemory m_memory_options;
};
-OptionDefinition
-g_memory_write_option_table[] =
-{
-{ LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Write memory using the contents of a file."},
-{ LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."},
+OptionDefinition g_memory_write_option_table[] = {
+ // clang-format off
+ {LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Write memory using the contents of a file."},
+ {LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."},
+ // clang-format on
};
//----------------------------------------------------------------------
// Write memory to the inferior process
//----------------------------------------------------------------------
-class CommandObjectMemoryWrite : public CommandObjectParsed
-{
+class CommandObjectMemoryWrite : public CommandObjectParsed {
public:
- class OptionGroupWriteMemory : public OptionGroup
- {
- public:
- OptionGroupWriteMemory () :
- OptionGroup()
- {
- }
+ class OptionGroupWriteMemory : public OptionGroup {
+ public:
+ OptionGroupWriteMemory() : OptionGroup() {}
- ~OptionGroupWriteMemory() override = default;
+ ~OptionGroupWriteMemory() override = default;
- uint32_t
- GetNumDefinitions () override
- {
- return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition);
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_memory_write_option_table;
- }
-
- Error
- SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg) override
- {
- Error error;
- const int short_option = g_memory_write_option_table[option_idx].short_option;
-
- switch (short_option)
- {
- case 'i':
- m_infile.SetFile (option_arg, true);
- if (!m_infile.Exists())
- {
- m_infile.Clear();
- error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg);
- }
- break;
-
- case 'o':
- {
- bool success;
- m_infile_offset = StringConvert::ToUInt64(option_arg, 0, 0, &success);
- if (!success)
- {
- error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg);
- }
- }
- break;
-
- default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
- break;
- }
- return error;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_memory_write_option_table);
+ }
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option =
+ g_memory_write_option_table[option_idx].short_option;
+
+ switch (short_option) {
+ case 'i':
+ m_infile.SetFile(option_value, true);
+ if (!m_infile.Exists()) {
+ m_infile.Clear();
+ error.SetErrorStringWithFormat("input file does not exist: '%s'",
+ option_value.str().c_str());
}
-
- void
- OptionParsingStarting (CommandInterpreter &interpreter) override
- {
- m_infile.Clear();
- m_infile_offset = 0;
+ break;
+
+ case 'o': {
+ if (option_value.getAsInteger(0, m_infile_offset)) {
+ m_infile_offset = 0;
+ error.SetErrorStringWithFormat("invalid offset string '%s'",
+ option_value.str().c_str());
}
+ } break;
- FileSpec m_infile;
- off_t m_infile_offset;
- };
-
- CommandObjectMemoryWrite(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "memory write", "Write to the memory of the current target process.",
- nullptr, eCommandRequiresProcess | eCommandProcessMustBeLaunched),
- m_option_group(interpreter),
- m_format_options(eFormatBytes, 1, UINT64_MAX),
- m_memory_options()
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentData addr_arg;
- CommandArgumentData value_arg;
-
- // Define the first (and only) variant of this arg.
- addr_arg.arg_type = eArgTypeAddress;
- addr_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (addr_arg);
-
- // Define the first (and only) variant of this arg.
- value_arg.arg_type = eArgTypeValue;
- value_arg.arg_repetition = eArgRepeatPlus;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg2.push_back (value_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
-
- m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
- m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2);
- m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
- m_option_group.Finalize();
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'",
+ short_option);
+ break;
+ }
+ return error;
}
- ~CommandObjectMemoryWrite() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_option_group;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_infile.Clear();
+ m_infile_offset = 0;
}
- bool
- UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
- {
- if (total_byte_size > 8)
- return false;
+ FileSpec m_infile;
+ off_t m_infile_offset;
+ };
- if (total_byte_size == 8)
- return true;
+ CommandObjectMemoryWrite(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "memory write",
+ "Write to the memory of the current target process.", nullptr,
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched),
+ m_option_group(), m_format_options(eFormatBytes, 1, UINT64_MAX),
+ m_memory_options() {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData addr_arg;
+ CommandArgumentData value_arg;
- const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
- return uval64 <= max;
- }
+ // Define the first (and only) variant of this arg.
+ addr_arg.arg_type = eArgTypeAddress;
+ addr_arg.arg_repetition = eArgRepeatPlain;
- bool
- SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
- {
- if (total_byte_size > 8)
- return false;
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(addr_arg);
- if (total_byte_size == 8)
- return true;
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlus;
- const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
- const int64_t min = ~(max);
- return min <= sval64 && sval64 <= max;
- }
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+
+ m_option_group.Append(&m_format_options,
+ OptionGroupFormat::OPTION_GROUP_FORMAT,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_format_options,
+ OptionGroupFormat::OPTION_GROUP_SIZE,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
+ m_option_group.Append(&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectMemoryWrite() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+ bool UIntValueIsValidForSize(uint64_t uval64, size_t total_byte_size) {
+ if (total_byte_size > 8)
+ return false;
+
+ if (total_byte_size == 8)
+ return true;
+
+ const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
+ return uval64 <= max;
+ }
+
+ bool SIntValueIsValidForSize(int64_t sval64, size_t total_byte_size) {
+ if (total_byte_size > 8)
+ return false;
+
+ if (total_byte_size == 8)
+ return true;
+
+ const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
+ const int64_t min = ~(max);
+ return min <= sval64 && sval64 <= max;
+ }
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
- Process *process = m_exe_ctx.GetProcessPtr();
-
- const size_t argc = command.GetArgumentCount();
-
- if (m_memory_options.m_infile)
- {
- if (argc < 1)
- {
- result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- else if (argc < 2)
- {
- result.AppendErrorWithFormat ("%s takes a destination address and at least one value.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ // No need to check "process" for validity as eCommandRequiresProcess
+ // ensures it is valid
+ Process *process = m_exe_ctx.GetProcessPtr();
+
+ const size_t argc = command.GetArgumentCount();
+
+ if (m_memory_options.m_infile) {
+ if (argc < 1) {
+ result.AppendErrorWithFormat(
+ "%s takes a destination address when writing file contents.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else if (argc < 2) {
+ result.AppendErrorWithFormat(
+ "%s takes a destination address and at least one value.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- StreamString buffer (Stream::eBinary,
- process->GetTarget().GetArchitecture().GetAddressByteSize(),
- process->GetTarget().GetArchitecture().GetByteOrder());
+ StreamString buffer(
+ Stream::eBinary,
+ process->GetTarget().GetArchitecture().GetAddressByteSize(),
+ process->GetTarget().GetArchitecture().GetByteOrder());
- OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
- size_t item_byte_size = byte_size_value.GetCurrentValue();
+ OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
+ size_t item_byte_size = byte_size_value.GetCurrentValue();
- Error error;
- lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
- command.GetArgumentAtIndex(0),
- LLDB_INVALID_ADDRESS,
- &error);
-
- if (addr == LLDB_INVALID_ADDRESS)
- {
- result.AppendError("invalid address expression\n");
- result.AppendError(error.AsCString());
+ Error error;
+ lldb::addr_t addr = Args::StringToAddress(&m_exe_ctx, command[0].ref,
+ LLDB_INVALID_ADDRESS, &error);
+
+ if (addr == LLDB_INVALID_ADDRESS) {
+ result.AppendError("invalid address expression\n");
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_memory_options.m_infile) {
+ size_t length = SIZE_MAX;
+ if (item_byte_size > 1)
+ length = item_byte_size;
+ lldb::DataBufferSP data_sp(m_memory_options.m_infile.ReadFileContents(
+ m_memory_options.m_infile_offset, length));
+ if (data_sp) {
+ length = data_sp->GetByteSize();
+ if (length > 0) {
+ Error error;
+ size_t bytes_written =
+ process->WriteMemory(addr, data_sp->GetBytes(), length, error);
+
+ if (bytes_written == length) {
+ // All bytes written
+ result.GetOutputStream().Printf(
+ "%" PRIu64 " bytes were written to 0x%" PRIx64 "\n",
+ (uint64_t)bytes_written, addr);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else if (bytes_written > 0) {
+ // Some byte written
+ result.GetOutputStream().Printf(
+ "%" PRIu64 " bytes of %" PRIu64
+ " requested were written to 0x%" PRIx64 "\n",
+ (uint64_t)bytes_written, (uint64_t)length, addr);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Memory write to 0x%" PRIx64
+ " failed: %s.\n",
+ addr, error.AsCString());
result.SetStatus(eReturnStatusFailed);
- return false;
+ }
}
-
- if (m_memory_options.m_infile)
- {
- size_t length = SIZE_MAX;
- if (item_byte_size > 1)
- length = item_byte_size;
- lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length));
- if (data_sp)
- {
- length = data_sp->GetByteSize();
- if (length > 0)
- {
- Error error;
- size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error);
-
- if (bytes_written == length)
- {
- // All bytes written
- result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr);
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- else if (bytes_written > 0)
- {
- // Some byte written
- result.GetOutputStream().Printf("%" PRIu64 " bytes of %" PRIu64 " requested were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, (uint64_t)length, addr);
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- }
- }
- }
- else
- {
- result.AppendErrorWithFormat ("Unable to read contents of file.\n");
- result.SetStatus(eReturnStatusFailed);
- }
- return result.Succeeded();
+ } else {
+ result.AppendErrorWithFormat("Unable to read contents of file.\n");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ } else if (item_byte_size == 0) {
+ if (m_format_options.GetFormat() == eFormatPointer)
+ item_byte_size = buffer.GetAddressByteSize();
+ else
+ item_byte_size = 1;
+ }
+
+ command.Shift(); // shift off the address argument
+ uint64_t uval64;
+ int64_t sval64;
+ bool success = false;
+ for (auto &entry : command) {
+ switch (m_format_options.GetFormat()) {
+ case kNumFormats:
+ case eFormatFloat: // TODO: add support for floats soon
+ case eFormatCharPrintable:
+ case eFormatBytesWithASCII:
+ case eFormatComplex:
+ case eFormatEnum:
+ case eFormatUnicode16:
+ case eFormatUnicode32:
+ case eFormatVectorOfChar:
+ case eFormatVectorOfSInt8:
+ case eFormatVectorOfUInt8:
+ case eFormatVectorOfSInt16:
+ case eFormatVectorOfUInt16:
+ case eFormatVectorOfSInt32:
+ case eFormatVectorOfUInt32:
+ case eFormatVectorOfSInt64:
+ case eFormatVectorOfUInt64:
+ case eFormatVectorOfFloat16:
+ case eFormatVectorOfFloat32:
+ case eFormatVectorOfFloat64:
+ case eFormatVectorOfUInt128:
+ case eFormatOSType:
+ case eFormatComplexInteger:
+ case eFormatAddressInfo:
+ case eFormatHexFloat:
+ case eFormatInstruction:
+ case eFormatVoid:
+ result.AppendError("unsupported format for writing memory");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+
+ case eFormatDefault:
+ case eFormatBytes:
+ case eFormatHex:
+ case eFormatHexUppercase:
+ case eFormatPointer:
+ // Decode hex bytes
+ if (entry.ref.getAsInteger(16, uval64)) {
+ result.AppendErrorWithFormat(
+ "'%s' is not a valid hex string value.\n", entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ result.AppendErrorWithFormat("Value 0x%" PRIx64
+ " is too large to fit in a %" PRIu64
+ " byte unsigned integer value.\n",
+ uval64, (uint64_t)item_byte_size);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else if (item_byte_size == 0)
- {
- if (m_format_options.GetFormat() == eFormatPointer)
- item_byte_size = buffer.GetAddressByteSize();
- else
- item_byte_size = 1;
+ buffer.PutMaxHex64(uval64, item_byte_size);
+ break;
+
+ case eFormatBoolean:
+ uval64 = Args::StringToBoolean(entry.ref, false, &success);
+ if (!success) {
+ result.AppendErrorWithFormat(
+ "'%s' is not a valid boolean string value.\n", entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- command.Shift(); // shift off the address argument
- uint64_t uval64;
- int64_t sval64;
- bool success = false;
- const size_t num_value_args = command.GetArgumentCount();
- for (size_t i=0; i<num_value_args; ++i)
- {
- const char *value_str = command.GetArgumentAtIndex(i);
-
- switch (m_format_options.GetFormat())
- {
- case kNumFormats:
- case eFormatFloat: // TODO: add support for floats soon
- case eFormatCharPrintable:
- case eFormatBytesWithASCII:
- case eFormatComplex:
- case eFormatEnum:
- case eFormatUnicode16:
- case eFormatUnicode32:
- case eFormatVectorOfChar:
- case eFormatVectorOfSInt8:
- case eFormatVectorOfUInt8:
- case eFormatVectorOfSInt16:
- case eFormatVectorOfUInt16:
- case eFormatVectorOfSInt32:
- case eFormatVectorOfUInt32:
- case eFormatVectorOfSInt64:
- case eFormatVectorOfUInt64:
- case eFormatVectorOfFloat16:
- case eFormatVectorOfFloat32:
- case eFormatVectorOfFloat64:
- case eFormatVectorOfUInt128:
- case eFormatOSType:
- case eFormatComplexInteger:
- case eFormatAddressInfo:
- case eFormatHexFloat:
- case eFormatInstruction:
- case eFormatVoid:
- result.AppendError("unsupported format for writing memory");
- result.SetStatus(eReturnStatusFailed);
- return false;
-
- case eFormatDefault:
- case eFormatBytes:
- case eFormatHex:
- case eFormatHexUppercase:
- case eFormatPointer:
- // Decode hex bytes
- uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 16, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else if (!UIntValueIsValidForSize (uval64, item_byte_size))
- {
- result.AppendErrorWithFormat("Value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- buffer.PutMaxHex64 (uval64, item_byte_size);
- break;
-
- case eFormatBoolean:
- uval64 = Args::StringToBoolean(value_str, false, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- buffer.PutMaxHex64 (uval64, item_byte_size);
- break;
-
- case eFormatBinary:
- uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 2, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else if (!UIntValueIsValidForSize (uval64, item_byte_size))
- {
- result.AppendErrorWithFormat("Value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- buffer.PutMaxHex64 (uval64, item_byte_size);
- break;
-
- case eFormatCharArray:
- case eFormatChar:
- case eFormatCString:
- if (value_str[0])
- {
- size_t len = strlen (value_str);
- // Include the NULL for C strings...
- if (m_format_options.GetFormat() == eFormatCString)
- ++len;
- Error error;
- if (process->WriteMemory (addr, value_str, len, error) == len)
- {
- addr += len;
- }
- else
- {
- result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- break;
-
- case eFormatDecimal:
- sval64 = StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else if (!SIntValueIsValidForSize (sval64, item_byte_size))
- {
- result.AppendErrorWithFormat ("Value %" PRIi64 " is too large or small to fit in a %" PRIu64 " byte signed integer value.\n", sval64, (uint64_t)item_byte_size);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- buffer.PutMaxHex64 (sval64, item_byte_size);
- break;
-
- case eFormatUnsigned:
- uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else if (!UIntValueIsValidForSize (uval64, item_byte_size))
- {
- result.AppendErrorWithFormat ("Value %" PRIu64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- buffer.PutMaxHex64 (uval64, item_byte_size);
- break;
-
- case eFormatOctal:
- uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 8, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else if (!UIntValueIsValidForSize (uval64, item_byte_size))
- {
- result.AppendErrorWithFormat ("Value %" PRIo64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- buffer.PutMaxHex64 (uval64, item_byte_size);
- break;
- }
+ buffer.PutMaxHex64(uval64, item_byte_size);
+ break;
+
+ case eFormatBinary:
+ if (entry.ref.getAsInteger(2, uval64)) {
+ result.AppendErrorWithFormat(
+ "'%s' is not a valid binary string value.\n", entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ result.AppendErrorWithFormat("Value 0x%" PRIx64
+ " is too large to fit in a %" PRIu64
+ " byte unsigned integer value.\n",
+ uval64, (uint64_t)item_byte_size);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ buffer.PutMaxHex64(uval64, item_byte_size);
+ break;
+
+ case eFormatCharArray:
+ case eFormatChar:
+ case eFormatCString: {
+ if (entry.ref.empty())
+ break;
+
+ size_t len = entry.ref.size();
+ // Include the NULL for C strings...
+ if (m_format_options.GetFormat() == eFormatCString)
+ ++len;
+ Error error;
+ if (process->WriteMemory(addr, entry.c_str(), len, error) == len) {
+ addr += len;
+ } else {
+ result.AppendErrorWithFormat("Memory write to 0x%" PRIx64
+ " failed: %s.\n",
+ addr, error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ break;
+ }
+ case eFormatDecimal:
+ if (entry.ref.getAsInteger(0, sval64)) {
+ result.AppendErrorWithFormat(
+ "'%s' is not a valid signed decimal value.\n", entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (!SIntValueIsValidForSize(sval64, item_byte_size)) {
+ result.AppendErrorWithFormat(
+ "Value %" PRIi64 " is too large or small to fit in a %" PRIu64
+ " byte signed integer value.\n",
+ sval64, (uint64_t)item_byte_size);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ buffer.PutMaxHex64(sval64, item_byte_size);
+ break;
- if (!buffer.GetString().empty())
- {
- Error error;
- if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size())
- return true;
- else
- {
- result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ case eFormatUnsigned:
+
+ if (!entry.ref.getAsInteger(0, uval64)) {
+ result.AppendErrorWithFormat(
+ "'%s' is not a valid unsigned decimal string value.\n",
+ entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ result.AppendErrorWithFormat("Value %" PRIu64
+ " is too large to fit in a %" PRIu64
+ " byte unsigned integer value.\n",
+ uval64, (uint64_t)item_byte_size);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ buffer.PutMaxHex64(uval64, item_byte_size);
+ break;
+
+ case eFormatOctal:
+ if (entry.ref.getAsInteger(8, uval64)) {
+ result.AppendErrorWithFormat(
+ "'%s' is not a valid octal string value.\n", entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ result.AppendErrorWithFormat("Value %" PRIo64
+ " is too large to fit in a %" PRIu64
+ " byte unsigned integer value.\n",
+ uval64, (uint64_t)item_byte_size);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ buffer.PutMaxHex64(uval64, item_byte_size);
+ break;
+ }
+ }
+
+ if (!buffer.GetString().empty()) {
+ Error error;
+ if (process->WriteMemory(addr, buffer.GetString().data(),
+ buffer.GetString().size(),
+ error) == buffer.GetString().size())
return true;
+ else {
+ result.AppendErrorWithFormat("Memory write to 0x%" PRIx64
+ " failed: %s.\n",
+ addr, error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
+ return true;
+ }
- OptionGroupOptions m_option_group;
- OptionGroupFormat m_format_options;
- OptionGroupWriteMemory m_memory_options;
+ OptionGroupOptions m_option_group;
+ OptionGroupFormat m_format_options;
+ OptionGroupWriteMemory m_memory_options;
};
//----------------------------------------------------------------------
// Get malloc/free history of a memory address.
//----------------------------------------------------------------------
-class CommandObjectMemoryHistory : public CommandObjectParsed
-{
+class CommandObjectMemoryHistory : public CommandObjectParsed {
public:
- CommandObjectMemoryHistory(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "memory history",
- "Print recorded stack traces for allocation/deallocation events associated with an address.", nullptr,
- eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBePaused |
- eCommandProcessMustBeLaunched)
- {
- CommandArgumentEntry arg1;
- CommandArgumentData addr_arg;
-
- // Define the first (and only) variant of this arg.
- addr_arg.arg_type = eArgTypeAddress;
- addr_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (addr_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
+ CommandObjectMemoryHistory(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "memory history", "Print recorded stack traces for "
+ "allocation/deallocation events "
+ "associated with an address.",
+ nullptr,
+ eCommandRequiresTarget | eCommandRequiresProcess |
+ eCommandProcessMustBePaused | eCommandProcessMustBeLaunched) {
+ CommandArgumentEntry arg1;
+ CommandArgumentData addr_arg;
+
+ // Define the first (and only) variant of this arg.
+ addr_arg.arg_type = eArgTypeAddress;
+ addr_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(addr_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectMemoryHistory() override = default;
+
+ const char *GetRepeatCommand(Args &current_command_args,
+ uint32_t index) override {
+ return m_cmd_name.c_str();
+ }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc == 0 || argc > 1) {
+ result.AppendErrorWithFormat("%s takes an address expression",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- ~CommandObjectMemoryHistory() override = default;
+ Error error;
+ lldb::addr_t addr = Args::StringToAddress(&m_exe_ctx, command[0].ref,
+ LLDB_INVALID_ADDRESS, &error);
- const char *
- GetRepeatCommand (Args &current_command_args, uint32_t index) override
- {
- return m_cmd_name.c_str();
+ if (addr == LLDB_INVALID_ADDRESS) {
+ result.AppendError("invalid address expression");
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- if (argc == 0 || argc > 1)
- {
- result.AppendErrorWithFormat ("%s takes an address expression", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- Error error;
- lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
- command.GetArgumentAtIndex(0),
- LLDB_INVALID_ADDRESS,
- &error);
-
- if (addr == LLDB_INVALID_ADDRESS)
- {
- result.AppendError("invalid address expression");
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- Stream *output_stream = &result.GetOutputStream();
-
- const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
- const MemoryHistorySP &memory_history = MemoryHistory::FindPlugin(process_sp);
-
- if (!memory_history)
- {
- result.AppendError("no available memory history provider");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- HistoryThreads thread_list = memory_history->GetHistoryThreads(addr);
-
- for (auto thread : thread_list) {
- thread->GetStatus(*output_stream, 0, UINT32_MAX, 0);
- }
-
- result.SetStatus(eReturnStatusSuccessFinishResult);
-
- return true;
+
+ Stream *output_stream = &result.GetOutputStream();
+
+ const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
+ const MemoryHistorySP &memory_history =
+ MemoryHistory::FindPlugin(process_sp);
+
+ if (!memory_history) {
+ result.AppendError("no available memory history provider");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ HistoryThreads thread_list = memory_history->GetHistoryThreads(addr);
+
+ const bool stop_format = false;
+ for (auto thread : thread_list) {
+ thread->GetStatus(*output_stream, 0, UINT32_MAX, 0, stop_format);
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ return true;
+ }
};
//-------------------------------------------------------------------------
@@ -1765,102 +1672,90 @@ protected:
//-------------------------------------------------------------------------
#pragma mark CommandObjectMemoryRegion
-class CommandObjectMemoryRegion : public CommandObjectParsed
-{
+class CommandObjectMemoryRegion : public CommandObjectParsed {
public:
- CommandObjectMemoryRegion(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "memory region",
- "Get information on the memory region containing an address in the current target process.",
- "memory region ADDR", eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched),
- m_prev_end_addr(LLDB_INVALID_ADDRESS)
- {
- }
+ CommandObjectMemoryRegion(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "memory region",
+ "Get information on the memory region containing "
+ "an address in the current target process.",
+ "memory region ADDR",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched),
+ m_prev_end_addr(LLDB_INVALID_ADDRESS) {}
- ~CommandObjectMemoryRegion() override = default;
+ ~CommandObjectMemoryRegion() override = default;
protected:
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- ProcessSP process_sp = m_exe_ctx.GetProcessSP();
- if (process_sp)
- {
- Error error;
- lldb::addr_t load_addr = m_prev_end_addr;
- m_prev_end_addr = LLDB_INVALID_ADDRESS;
-
- const size_t argc = command.GetArgumentCount();
- if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS))
- {
- result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n", m_cmd_name.c_str(),
- m_cmd_syntax.c_str());
- result.SetStatus(eReturnStatusFailed);
- }
- else
- {
- const char *load_addr_cstr = command.GetArgumentAtIndex(0);
- if (command.GetArgumentCount() == 1)
- {
- load_addr = Args::StringToAddress(&m_exe_ctx, load_addr_cstr, LLDB_INVALID_ADDRESS, &error);
- if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS)
- {
- result.AppendErrorWithFormat("invalid address argument \"%s\": %s\n", load_addr_cstr,
- error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- }
- }
-
- lldb_private::MemoryRegionInfo range_info;
- error = process_sp->GetMemoryRegionInfo(load_addr, range_info);
- if (error.Success())
- {
- lldb_private::Address addr;
- ConstString section_name;
- if (process_sp->GetTarget().ResolveLoadAddress(load_addr, addr))
- {
- SectionSP section_sp(addr.GetSection());
- if (section_sp)
- {
- // Got the top most section, not the deepest section
- while (section_sp->GetParent())
- section_sp = section_sp->GetParent();
- section_name = section_sp->GetName();
- }
- }
- result.AppendMessageWithFormat(
- "[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") %c%c%c%s%s\n", range_info.GetRange().GetRangeBase(),
- range_info.GetRange().GetRangeEnd(), range_info.GetReadable() ? 'r' : '-',
- range_info.GetWritable() ? 'w' : '-', range_info.GetExecutable() ? 'x' : '-',
- section_name ? " " : "", section_name ? section_name.AsCString() : "");
- m_prev_end_addr = range_info.GetRange().GetRangeEnd();
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.SetStatus(eReturnStatusFailed);
- result.AppendErrorWithFormat("%s\n", error.AsCString());
- }
- }
- }
- else
- {
- m_prev_end_addr = LLDB_INVALID_ADDRESS;
- result.AppendError("invalid process");
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ ProcessSP process_sp = m_exe_ctx.GetProcessSP();
+ if (process_sp) {
+ Error error;
+ lldb::addr_t load_addr = m_prev_end_addr;
+ m_prev_end_addr = LLDB_INVALID_ADDRESS;
+
+ const size_t argc = command.GetArgumentCount();
+ if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS)) {
+ result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n",
+ m_cmd_name.c_str(), m_cmd_syntax.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ auto load_addr_str = command[0].ref;
+ if (command.GetArgumentCount() == 1) {
+ load_addr = Args::StringToAddress(&m_exe_ctx, load_addr_str,
+ LLDB_INVALID_ADDRESS, &error);
+ if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) {
+ result.AppendErrorWithFormat(
+ "invalid address argument \"%s\": %s\n", command[0].c_str(),
+ error.AsCString());
result.SetStatus(eReturnStatusFailed);
+ }
}
- return result.Succeeded();
- }
- const char *
- GetRepeatCommand(Args &current_command_args, uint32_t index) override
- {
- // If we repeat this command, repeat it without any arguments so we can
- // show the next memory range
- return m_cmd_name.c_str();
+ lldb_private::MemoryRegionInfo range_info;
+ error = process_sp->GetMemoryRegionInfo(load_addr, range_info);
+ if (error.Success()) {
+ lldb_private::Address addr;
+ ConstString section_name;
+ if (process_sp->GetTarget().ResolveLoadAddress(load_addr, addr)) {
+ SectionSP section_sp(addr.GetSection());
+ if (section_sp) {
+ // Got the top most section, not the deepest section
+ while (section_sp->GetParent())
+ section_sp = section_sp->GetParent();
+ section_name = section_sp->GetName();
+ }
+ }
+ result.AppendMessageWithFormat(
+ "[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") %c%c%c%s%s\n",
+ range_info.GetRange().GetRangeBase(),
+ range_info.GetRange().GetRangeEnd(),
+ range_info.GetReadable() ? 'r' : '-',
+ range_info.GetWritable() ? 'w' : '-',
+ range_info.GetExecutable() ? 'x' : '-', section_name ? " " : "",
+ section_name ? section_name.AsCString() : "");
+ m_prev_end_addr = range_info.GetRange().GetRangeEnd();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.SetStatus(eReturnStatusFailed);
+ result.AppendErrorWithFormat("%s\n", error.AsCString());
+ }
+ }
+ } else {
+ m_prev_end_addr = LLDB_INVALID_ADDRESS;
+ result.AppendError("invalid process");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
+
+ const char *GetRepeatCommand(Args &current_command_args,
+ uint32_t index) override {
+ // If we repeat this command, repeat it without any arguments so we can
+ // show the next memory range
+ return m_cmd_name.c_str();
+ }
- lldb::addr_t m_prev_end_addr;
+ lldb::addr_t m_prev_end_addr;
};
//-------------------------------------------------------------------------
@@ -1868,14 +1763,20 @@ protected:
//-------------------------------------------------------------------------
CommandObjectMemory::CommandObjectMemory(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "memory", "Commands for operating on memory in the current target process.",
- "memory <subcommand> [<subcommand-options>]")
-{
- LoadSubCommand("find", CommandObjectSP(new CommandObjectMemoryFind(interpreter)));
- LoadSubCommand("read", CommandObjectSP(new CommandObjectMemoryRead(interpreter)));
- LoadSubCommand("write", CommandObjectSP(new CommandObjectMemoryWrite(interpreter)));
- LoadSubCommand("history", CommandObjectSP(new CommandObjectMemoryHistory(interpreter)));
- LoadSubCommand("region", CommandObjectSP(new CommandObjectMemoryRegion(interpreter)));
+ : CommandObjectMultiword(
+ interpreter, "memory",
+ "Commands for operating on memory in the current target process.",
+ "memory <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("find",
+ CommandObjectSP(new CommandObjectMemoryFind(interpreter)));
+ LoadSubCommand("read",
+ CommandObjectSP(new CommandObjectMemoryRead(interpreter)));
+ LoadSubCommand("write",
+ CommandObjectSP(new CommandObjectMemoryWrite(interpreter)));
+ LoadSubCommand("history",
+ CommandObjectSP(new CommandObjectMemoryHistory(interpreter)));
+ LoadSubCommand("region",
+ CommandObjectSP(new CommandObjectMemoryRegion(interpreter)));
}
CommandObjectMemory::~CommandObjectMemory() = default;
diff --git a/source/Commands/CommandObjectMemory.h b/source/Commands/CommandObjectMemory.h
index cf5b4419746c..9f3978baf76a 100644
--- a/source/Commands/CommandObjectMemory.h
+++ b/source/Commands/CommandObjectMemory.h
@@ -18,12 +18,11 @@
namespace lldb_private {
-class CommandObjectMemory : public CommandObjectMultiword
-{
+class CommandObjectMemory : public CommandObjectMultiword {
public:
- CommandObjectMemory (CommandInterpreter &interpreter);
+ CommandObjectMemory(CommandInterpreter &interpreter);
- ~CommandObjectMemory() override;
+ ~CommandObjectMemory() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectMultiword.cpp b/source/Commands/CommandObjectMultiword.cpp
index c951e0bbfa0d..0d0aa108a4ce 100644
--- a/source/Commands/CommandObjectMultiword.cpp
+++ b/source/Commands/CommandObjectMultiword.cpp
@@ -14,8 +14,8 @@
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
using namespace lldb;
using namespace lldb_private;
@@ -28,496 +28,391 @@ CommandObjectMultiword::CommandObjectMultiword(CommandInterpreter &interpreter,
const char *name,
const char *help,
const char *syntax,
- uint32_t flags) :
- CommandObject (interpreter, name, help, syntax, flags),
- m_can_be_removed(false)
-{
-}
+ uint32_t flags)
+ : CommandObject(interpreter, name, help, syntax, flags),
+ m_can_be_removed(false) {}
CommandObjectMultiword::~CommandObjectMultiword() = default;
-CommandObjectSP
-CommandObjectMultiword::GetSubcommandSP (const char *sub_cmd, StringList *matches)
-{
- CommandObjectSP return_cmd_sp;
- CommandObject::CommandMap::iterator pos;
-
- if (!m_subcommand_dict.empty())
- {
- pos = m_subcommand_dict.find (sub_cmd);
- if (pos != m_subcommand_dict.end()) {
- // An exact match; append the sub_cmd to the 'matches' string list.
- if (matches)
- matches->AppendString(sub_cmd);
- return_cmd_sp = pos->second;
- }
- else
- {
- StringList local_matches;
- if (matches == nullptr)
- matches = &local_matches;
- int num_matches = AddNamesMatchingPartialString (m_subcommand_dict, sub_cmd, *matches);
-
- if (num_matches == 1)
- {
- // Cleaner, but slightly less efficient would be to call back into this function, since I now
- // know I have an exact match...
-
- sub_cmd = matches->GetStringAtIndex(0);
- pos = m_subcommand_dict.find(sub_cmd);
- if (pos != m_subcommand_dict.end())
- return_cmd_sp = pos->second;
- }
- }
+CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd,
+ StringList *matches) {
+ CommandObjectSP return_cmd_sp;
+ CommandObject::CommandMap::iterator pos;
+
+ if (!m_subcommand_dict.empty()) {
+ pos = m_subcommand_dict.find(sub_cmd);
+ if (pos != m_subcommand_dict.end()) {
+ // An exact match; append the sub_cmd to the 'matches' string list.
+ if (matches)
+ matches->AppendString(sub_cmd);
+ return_cmd_sp = pos->second;
+ } else {
+ StringList local_matches;
+ if (matches == nullptr)
+ matches = &local_matches;
+ int num_matches =
+ AddNamesMatchingPartialString(m_subcommand_dict, sub_cmd, *matches);
+
+ if (num_matches == 1) {
+ // Cleaner, but slightly less efficient would be to call back into this
+ // function, since I now
+ // know I have an exact match...
+
+ sub_cmd = matches->GetStringAtIndex(0);
+ pos = m_subcommand_dict.find(sub_cmd);
+ if (pos != m_subcommand_dict.end())
+ return_cmd_sp = pos->second;
+ }
}
- return return_cmd_sp;
+ }
+ return return_cmd_sp;
}
CommandObject *
-CommandObjectMultiword::GetSubcommandObject (const char *sub_cmd, StringList *matches)
-{
- return GetSubcommandSP(sub_cmd, matches).get();
+CommandObjectMultiword::GetSubcommandObject(llvm::StringRef sub_cmd,
+ StringList *matches) {
+ return GetSubcommandSP(sub_cmd, matches).get();
}
-bool
-CommandObjectMultiword::LoadSubCommand(const char *name,
- const CommandObjectSP& cmd_obj)
-{
- if (cmd_obj)
- assert((&GetCommandInterpreter() == &cmd_obj->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter");
-
- CommandMap::iterator pos;
- bool success = true;
-
- pos = m_subcommand_dict.find(name);
- if (pos == m_subcommand_dict.end())
- {
- m_subcommand_dict[name] = cmd_obj;
- }
- else
- success = false;
+bool CommandObjectMultiword::LoadSubCommand(llvm::StringRef name,
+ const CommandObjectSP &cmd_obj) {
+ if (cmd_obj)
+ assert((&GetCommandInterpreter() == &cmd_obj->GetCommandInterpreter()) &&
+ "tried to add a CommandObject from a different interpreter");
+
+ CommandMap::iterator pos;
+ bool success = true;
- return success;
+ pos = m_subcommand_dict.find(name);
+ if (pos == m_subcommand_dict.end()) {
+ m_subcommand_dict[name] = cmd_obj;
+ } else
+ success = false;
+
+ return success;
}
-bool
-CommandObjectMultiword::Execute(const char *args_string, CommandReturnObject &result)
-{
- Args args (args_string);
- const size_t argc = args.GetArgumentCount();
- if (argc == 0)
- {
- this->CommandObject::GenerateHelpText (result);
- }
- else
- {
- const char *sub_command = args.GetArgumentAtIndex (0);
-
- if (sub_command)
- {
- if (::strcasecmp (sub_command, "help") == 0)
- {
- this->CommandObject::GenerateHelpText (result);
- }
- else if (!m_subcommand_dict.empty())
- {
- StringList matches;
- CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
- if (sub_cmd_obj != nullptr)
- {
- // Now call CommandObject::Execute to process and options in 'rest_of_line'. From there
- // the command-specific version of Execute will be called, with the processed arguments.
-
- args.Shift();
-
- sub_cmd_obj->Execute (args_string, result);
- }
- else
- {
- std::string error_msg;
- const size_t num_subcmd_matches = matches.GetSize();
- if (num_subcmd_matches > 0)
- error_msg.assign ("ambiguous command ");
- else
- error_msg.assign ("invalid command ");
-
- error_msg.append ("'");
- error_msg.append (GetCommandName());
- error_msg.append (" ");
- error_msg.append (sub_command);
- error_msg.append ("'.");
-
- if (num_subcmd_matches > 0)
- {
- error_msg.append (" Possible completions:");
- for (size_t i = 0; i < num_subcmd_matches; i++)
- {
- error_msg.append ("\n\t");
- error_msg.append (matches.GetStringAtIndex (i));
- }
- }
- error_msg.append ("\n");
- result.AppendRawError (error_msg.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("'%s' does not have any subcommands.\n", GetCommandName());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- }
+bool CommandObjectMultiword::Execute(const char *args_string,
+ CommandReturnObject &result) {
+ Args args(args_string);
+ const size_t argc = args.GetArgumentCount();
+ if (argc == 0) {
+ this->CommandObject::GenerateHelpText(result);
+ return result.Succeeded();
+ }
+ auto sub_command = args[0].ref;
+ if (sub_command.empty())
return result.Succeeded();
-}
-void
-CommandObjectMultiword::GenerateHelpText (Stream &output_stream)
-{
- // First time through here, generate the help text for the object and
- // push it to the return result object as well
-
- CommandObject::GenerateHelpText(output_stream);
- output_stream.PutCString("\nThe following subcommands are supported:\n\n");
-
- CommandMap::iterator pos;
- uint32_t max_len = FindLongestCommandWord (m_subcommand_dict);
-
- if (max_len)
- max_len += 4; // Indent the output by 4 spaces.
-
- for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos)
- {
- std::string indented_command (" ");
- indented_command.append (pos->first);
- if (pos->second->WantsRawCommandString ())
- {
- std::string help_text (pos->second->GetHelp());
- help_text.append(" Expects 'raw' input (see 'help raw-input'.)");
- m_interpreter.OutputFormattedHelpText (output_stream,
- indented_command.c_str(),
- "--",
- help_text.c_str(),
- max_len);
- }
- else
- m_interpreter.OutputFormattedHelpText (output_stream,
- indented_command.c_str(),
- "--",
- pos->second->GetHelp(),
- max_len);
+ if (sub_command.equals_lower("help")) {
+ this->CommandObject::GenerateHelpText(result);
+ return result.Succeeded();
+ }
+
+ if (m_subcommand_dict.empty()) {
+ result.AppendErrorWithFormat("'%s' does not have any subcommands.\n",
+ GetCommandName().str().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ StringList matches;
+ CommandObject *sub_cmd_obj = GetSubcommandObject(sub_command, &matches);
+ if (sub_cmd_obj != nullptr) {
+ // Now call CommandObject::Execute to process options in `rest_of_line`.
+ // From there the command-specific version of Execute will be called,
+ // with the processed arguments.
+
+ args.Shift();
+ sub_cmd_obj->Execute(args_string, result);
+ return result.Succeeded();
+ }
+
+ std::string error_msg;
+ const size_t num_subcmd_matches = matches.GetSize();
+ if (num_subcmd_matches > 0)
+ error_msg.assign("ambiguous command ");
+ else
+ error_msg.assign("invalid command ");
+
+ error_msg.append("'");
+ error_msg.append(GetCommandName());
+ error_msg.append(" ");
+ error_msg.append(sub_command);
+ error_msg.append("'.");
+
+ if (num_subcmd_matches > 0) {
+ error_msg.append(" Possible completions:");
+ for (size_t i = 0; i < num_subcmd_matches; i++) {
+ error_msg.append("\n\t");
+ error_msg.append(matches.GetStringAtIndex(i));
}
+ }
+ error_msg.append("\n");
+ result.AppendRawError(error_msg.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+}
- output_stream.PutCString ("\nFor more help on any particular subcommand, type 'help <command> <subcommand>'.\n");
+void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) {
+ // First time through here, generate the help text for the object and
+ // push it to the return result object as well
+
+ CommandObject::GenerateHelpText(output_stream);
+ output_stream.PutCString("\nThe following subcommands are supported:\n\n");
+
+ CommandMap::iterator pos;
+ uint32_t max_len = FindLongestCommandWord(m_subcommand_dict);
+
+ if (max_len)
+ max_len += 4; // Indent the output by 4 spaces.
+
+ for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos) {
+ std::string indented_command(" ");
+ indented_command.append(pos->first);
+ if (pos->second->WantsRawCommandString()) {
+ std::string help_text(pos->second->GetHelp());
+ help_text.append(" Expects 'raw' input (see 'help raw-input'.)");
+ m_interpreter.OutputFormattedHelpText(output_stream,
+ indented_command.c_str(), "--",
+ help_text.c_str(), max_len);
+ } else
+ m_interpreter.OutputFormattedHelpText(output_stream,
+ indented_command.c_str(), "--",
+ pos->second->GetHelp(), max_len);
+ }
+
+ output_stream.PutCString("\nFor more help on any particular subcommand, type "
+ "'help <command> <subcommand>'.\n");
}
-int
-CommandObjectMultiword::HandleCompletion(Args &input,
- int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches)
-{
- // Any of the command matches will provide a complete word, otherwise the individual
- // completers will override this.
- word_complete = true;
-
- const char *arg0 = input.GetArgumentAtIndex(0);
- if (cursor_index == 0)
- {
- AddNamesMatchingPartialString (m_subcommand_dict,
- arg0,
- matches);
-
- if (matches.GetSize() == 1
- && matches.GetStringAtIndex(0) != nullptr
- && strcmp (arg0, matches.GetStringAtIndex(0)) == 0)
- {
- StringList temp_matches;
- CommandObject *cmd_obj = GetSubcommandObject (arg0,
- &temp_matches);
- if (cmd_obj != nullptr)
- {
- if (input.GetArgumentCount() == 1)
- {
- word_complete = true;
- }
- else
- {
- matches.DeleteStringAtIndex (0);
- input.Shift();
- cursor_char_position = 0;
- input.AppendArgument ("");
- return cmd_obj->HandleCompletion (input,
- cursor_index,
- cursor_char_position,
- match_start_point,
- max_return_elements,
- word_complete,
- matches);
- }
- }
+int CommandObjectMultiword::HandleCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches) {
+ // Any of the command matches will provide a complete word, otherwise the
+ // individual completers will override this.
+ word_complete = true;
+
+ auto arg0 = input[0].ref;
+ if (cursor_index == 0) {
+ AddNamesMatchingPartialString(m_subcommand_dict, arg0, matches);
+
+ if (matches.GetSize() == 1 && matches.GetStringAtIndex(0) != nullptr &&
+ (arg0 == matches.GetStringAtIndex(0))) {
+ StringList temp_matches;
+ CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches);
+ if (cmd_obj != nullptr) {
+ if (input.GetArgumentCount() == 1) {
+ word_complete = true;
+ } else {
+ matches.DeleteStringAtIndex(0);
+ input.Shift();
+ cursor_char_position = 0;
+ input.AppendArgument(llvm::StringRef());
+ return cmd_obj->HandleCompletion(
+ input, cursor_index, cursor_char_position, match_start_point,
+ max_return_elements, word_complete, matches);
}
- return matches.GetSize();
+ }
}
- else
- {
- CommandObject *sub_command_object = GetSubcommandObject (arg0,
- &matches);
- if (sub_command_object == nullptr)
- {
- return matches.GetSize();
- }
- else
- {
- // Remove the one match that we got from calling GetSubcommandObject.
- matches.DeleteStringAtIndex(0);
- input.Shift();
- cursor_index--;
- return sub_command_object->HandleCompletion (input,
- cursor_index,
- cursor_char_position,
- match_start_point,
- max_return_elements,
- word_complete,
- matches);
- }
+ return matches.GetSize();
+ } else {
+ CommandObject *sub_command_object = GetSubcommandObject(arg0, &matches);
+ if (sub_command_object == nullptr) {
+ return matches.GetSize();
+ } else {
+ // Remove the one match that we got from calling GetSubcommandObject.
+ matches.DeleteStringAtIndex(0);
+ input.Shift();
+ cursor_index--;
+ return sub_command_object->HandleCompletion(
+ input, cursor_index, cursor_char_position, match_start_point,
+ max_return_elements, word_complete, matches);
}
+ }
}
-const char *
-CommandObjectMultiword::GetRepeatCommand (Args &current_command_args, uint32_t index)
-{
- index++;
- if (current_command_args.GetArgumentCount() <= index)
- return nullptr;
- CommandObject *sub_command_object = GetSubcommandObject (current_command_args.GetArgumentAtIndex(index));
- if (sub_command_object == nullptr)
- return nullptr;
- return sub_command_object->GetRepeatCommand(current_command_args, index);
+const char *CommandObjectMultiword::GetRepeatCommand(Args &current_command_args,
+ uint32_t index) {
+ index++;
+ if (current_command_args.GetArgumentCount() <= index)
+ return nullptr;
+ CommandObject *sub_command_object =
+ GetSubcommandObject(current_command_args[index].ref);
+ if (sub_command_object == nullptr)
+ return nullptr;
+ return sub_command_object->GetRepeatCommand(current_command_args, index);
}
-void
-CommandObjectMultiword::AproposAllSubCommands (const char *prefix,
- const char *search_word,
- StringList &commands_found,
- StringList &commands_help)
-{
- CommandObject::CommandMap::const_iterator pos;
-
- for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos)
- {
- const char * command_name = pos->first.c_str();
- CommandObject *sub_cmd_obj = pos->second.get();
- StreamString complete_command_name;
-
- complete_command_name.Printf ("%s %s", prefix, command_name);
-
- if (sub_cmd_obj->HelpTextContainsWord (search_word))
- {
- commands_found.AppendString (complete_command_name.GetData());
- commands_help.AppendString (sub_cmd_obj->GetHelp());
- }
-
- if (sub_cmd_obj->IsMultiwordObject())
- sub_cmd_obj->AproposAllSubCommands (complete_command_name.GetData(),
- search_word,
- commands_found,
- commands_help);
+void CommandObjectMultiword::AproposAllSubCommands(llvm::StringRef prefix,
+ llvm::StringRef search_word,
+ StringList &commands_found,
+ StringList &commands_help) {
+ CommandObject::CommandMap::const_iterator pos;
+
+ for (pos = m_subcommand_dict.begin(); pos != m_subcommand_dict.end(); ++pos) {
+ const char *command_name = pos->first.c_str();
+ CommandObject *sub_cmd_obj = pos->second.get();
+ StreamString complete_command_name;
+
+ complete_command_name << prefix << " " << command_name;
+
+ if (sub_cmd_obj->HelpTextContainsWord(search_word)) {
+ commands_found.AppendString(complete_command_name.GetString());
+ commands_help.AppendString(sub_cmd_obj->GetHelp());
}
-}
-CommandObjectProxy::CommandObjectProxy (CommandInterpreter &interpreter,
- const char *name,
- const char *help,
- const char *syntax,
- uint32_t flags) :
- CommandObject (interpreter, name, help, syntax, flags)
-{
+ if (sub_cmd_obj->IsMultiwordObject())
+ sub_cmd_obj->AproposAllSubCommands(complete_command_name.GetString(),
+ search_word, commands_found,
+ commands_help);
+ }
}
+CommandObjectProxy::CommandObjectProxy(CommandInterpreter &interpreter,
+ const char *name, const char *help,
+ const char *syntax, uint32_t flags)
+ : CommandObject(interpreter, name, help, syntax, flags) {}
+
CommandObjectProxy::~CommandObjectProxy() = default;
-const char *
-CommandObjectProxy::GetHelpLong ()
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->GetHelpLong();
- return nullptr;
+llvm::StringRef CommandObjectProxy::GetHelpLong() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetHelpLong();
+ return llvm::StringRef();
}
-bool
-CommandObjectProxy::IsRemovable() const
-{
- const CommandObject *proxy_command = const_cast<CommandObjectProxy *>(this)->GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->IsRemovable();
- return false;
+bool CommandObjectProxy::IsRemovable() const {
+ const CommandObject *proxy_command =
+ const_cast<CommandObjectProxy *>(this)->GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->IsRemovable();
+ return false;
}
-bool
-CommandObjectProxy::IsMultiwordObject ()
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->IsMultiwordObject();
- return false;
+bool CommandObjectProxy::IsMultiwordObject() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->IsMultiwordObject();
+ return false;
}
-CommandObjectMultiword*
-CommandObjectProxy::GetAsMultiwordCommand ()
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->GetAsMultiwordCommand();
- return nullptr;
+CommandObjectMultiword *CommandObjectProxy::GetAsMultiwordCommand() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetAsMultiwordCommand();
+ return nullptr;
}
-void
-CommandObjectProxy::GenerateHelpText (Stream &result)
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->GenerateHelpText(result);
+void CommandObjectProxy::GenerateHelpText(Stream &result) {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GenerateHelpText(result);
}
lldb::CommandObjectSP
-CommandObjectProxy::GetSubcommandSP (const char *sub_cmd, StringList *matches)
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->GetSubcommandSP(sub_cmd, matches);
- return lldb::CommandObjectSP();
+CommandObjectProxy::GetSubcommandSP(llvm::StringRef sub_cmd,
+ StringList *matches) {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetSubcommandSP(sub_cmd, matches);
+ return lldb::CommandObjectSP();
}
-CommandObject *
-CommandObjectProxy::GetSubcommandObject (const char *sub_cmd, StringList *matches)
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->GetSubcommandObject(sub_cmd, matches);
- return nullptr;
+CommandObject *CommandObjectProxy::GetSubcommandObject(llvm::StringRef sub_cmd,
+ StringList *matches) {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetSubcommandObject(sub_cmd, matches);
+ return nullptr;
}
-void
-CommandObjectProxy::AproposAllSubCommands (const char *prefix,
- const char *search_word,
- StringList &commands_found,
- StringList &commands_help)
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->AproposAllSubCommands (prefix,
- search_word,
- commands_found,
- commands_help);
+void CommandObjectProxy::AproposAllSubCommands(llvm::StringRef prefix,
+ llvm::StringRef search_word,
+ StringList &commands_found,
+ StringList &commands_help) {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->AproposAllSubCommands(prefix, search_word,
+ commands_found, commands_help);
}
-bool
-CommandObjectProxy::LoadSubCommand (const char *cmd_name,
- const lldb::CommandObjectSP& command_sp)
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->LoadSubCommand (cmd_name, command_sp);
- return false;
+bool CommandObjectProxy::LoadSubCommand(
+ llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_sp) {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->LoadSubCommand(cmd_name, command_sp);
+ return false;
}
-bool
-CommandObjectProxy::WantsRawCommandString()
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->WantsRawCommandString();
- return false;
+bool CommandObjectProxy::WantsRawCommandString() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->WantsRawCommandString();
+ return false;
}
-bool
-CommandObjectProxy::WantsCompletion()
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->WantsCompletion();
- return false;
+bool CommandObjectProxy::WantsCompletion() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->WantsCompletion();
+ return false;
}
-Options *
-CommandObjectProxy::GetOptions ()
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->GetOptions ();
- return nullptr;
+Options *CommandObjectProxy::GetOptions() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetOptions();
+ return nullptr;
}
-int
-CommandObjectProxy::HandleCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches)
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->HandleCompletion (input,
- cursor_index,
- cursor_char_position,
- match_start_point,
- max_return_elements,
- word_complete,
- matches);
- matches.Clear();
- return 0;
+int CommandObjectProxy::HandleCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches) {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->HandleCompletion(
+ input, cursor_index, cursor_char_position, match_start_point,
+ max_return_elements, word_complete, matches);
+ matches.Clear();
+ return 0;
}
-int
-CommandObjectProxy::HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches)
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->HandleArgumentCompletion (input,
- cursor_index,
- cursor_char_position,
- opt_element_vector,
- match_start_point,
- max_return_elements,
- word_complete,
- matches);
- matches.Clear();
- return 0;
+int CommandObjectProxy::HandleArgumentCompletion(
+ Args &input, int &cursor_index, int &cursor_char_position,
+ OptionElementVector &opt_element_vector, int match_start_point,
+ int max_return_elements, bool &word_complete, StringList &matches) {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->HandleArgumentCompletion(
+ input, cursor_index, cursor_char_position, opt_element_vector,
+ match_start_point, max_return_elements, word_complete, matches);
+ matches.Clear();
+ return 0;
}
-const char *
-CommandObjectProxy::GetRepeatCommand (Args &current_command_args,
- uint32_t index)
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->GetRepeatCommand (current_command_args, index);
- return nullptr;
+const char *CommandObjectProxy::GetRepeatCommand(Args &current_command_args,
+ uint32_t index) {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetRepeatCommand(current_command_args, index);
+ return nullptr;
}
-bool
-CommandObjectProxy::Execute (const char *args_string,
- CommandReturnObject &result)
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->Execute (args_string, result);
- result.AppendError ("command is not implemented");
- result.SetStatus (eReturnStatusFailed);
- return false;
+bool CommandObjectProxy::Execute(const char *args_string,
+ CommandReturnObject &result) {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->Execute(args_string, result);
+ result.AppendError("command is not implemented");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index 99bd63b6bdbb..562572b4c75e 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -29,2172 +29,1882 @@
#include "lldb/Target/Process.h"
#include "lldb/Utility/Utils.h"
+#include "llvm/ADT/SmallString.h"
+
using namespace lldb;
using namespace lldb_private;
-static mode_t
-ParsePermissionString(const char* permissions)
-{
- if (strlen(permissions) != 9)
- return (mode_t)(-1);
- bool user_r,user_w,user_x,
- group_r,group_w,group_x,
- world_r,world_w,world_x;
-
- user_r = (permissions[0] == 'r');
- user_w = (permissions[1] == 'w');
- user_x = (permissions[2] == 'x');
-
- group_r = (permissions[3] == 'r');
- group_w = (permissions[4] == 'w');
- group_x = (permissions[5] == 'x');
-
- world_r = (permissions[6] == 'r');
- world_w = (permissions[7] == 'w');
- world_x = (permissions[8] == 'x');
-
- mode_t user,group,world;
- user = (user_r ? 4 : 0) | (user_w ? 2 : 0) | (user_x ? 1 : 0);
- group = (group_r ? 4 : 0) | (group_w ? 2 : 0) | (group_x ? 1 : 0);
- world = (world_r ? 4 : 0) | (world_w ? 2 : 0) | (world_x ? 1 : 0);
-
- return user | group | world;
+static mode_t ParsePermissionString(const char *) = delete;
+
+static mode_t ParsePermissionString(llvm::StringRef permissions) {
+ if (permissions.size() != 9)
+ return (mode_t)(-1);
+ bool user_r, user_w, user_x, group_r, group_w, group_x, world_r, world_w,
+ world_x;
+
+ user_r = (permissions[0] == 'r');
+ user_w = (permissions[1] == 'w');
+ user_x = (permissions[2] == 'x');
+
+ group_r = (permissions[3] == 'r');
+ group_w = (permissions[4] == 'w');
+ group_x = (permissions[5] == 'x');
+
+ world_r = (permissions[6] == 'r');
+ world_w = (permissions[7] == 'w');
+ world_x = (permissions[8] == 'x');
+
+ mode_t user, group, world;
+ user = (user_r ? 4 : 0) | (user_w ? 2 : 0) | (user_x ? 1 : 0);
+ group = (group_r ? 4 : 0) | (group_w ? 2 : 0) | (group_x ? 1 : 0);
+ world = (world_r ? 4 : 0) | (world_w ? 2 : 0) | (world_x ? 1 : 0);
+
+ return user | group | world;
}
-static OptionDefinition
-g_permissions_options[] =
-{
- { LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePermissionsNumber , "Give out the numeric value for permissions (e.g. 757)" },
- { LLDB_OPT_SET_ALL, false, "permissions-string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePermissionsString , "Give out the string value for permissions (e.g. rwxr-xr--)." },
- { LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow user to read." },
- { LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow user to write." },
- { LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow user to execute." },
-
- { LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow group to read." },
- { LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow group to write." },
- { LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow group to execute." },
-
- { LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow world to read." },
- { LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow world to write." },
- { LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone , "Allow world to execute." },
+static OptionDefinition g_permissions_options[] = {
+ // clang-format off
+ {LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePermissionsNumber, "Give out the numeric value for permissions (e.g. 757)"},
+ {LLDB_OPT_SET_ALL, false, "permissions-string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePermissionsString, "Give out the string value for permissions (e.g. rwxr-xr--)."},
+ {LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow user to read."},
+ {LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow user to write."},
+ {LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow user to execute."},
+ {LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow group to read."},
+ {LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow group to write."},
+ {LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow group to execute."},
+ {LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow world to read."},
+ {LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow world to write."},
+ {LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow world to execute."},
+ // clang-format on
};
-class OptionPermissions : public lldb_private::OptionGroup
-{
+class OptionPermissions : public OptionGroup {
public:
- OptionPermissions ()
- {
+ OptionPermissions() {}
+
+ ~OptionPermissions() override = default;
+
+ lldb_private::Error
+ SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ char short_option = (char)GetDefinitions()[option_idx].short_option;
+ switch (short_option) {
+ case 'v': {
+ if (option_arg.getAsInteger(8, m_permissions)) {
+ m_permissions = 0777;
+ error.SetErrorStringWithFormat("invalid value for permissions: %s",
+ option_arg.str().c_str());
+ }
+
+ } break;
+ case 's': {
+ mode_t perms = ParsePermissionString(option_arg);
+ if (perms == (mode_t)-1)
+ error.SetErrorStringWithFormat("invalid value for permissions: %s",
+ option_arg.str().c_str());
+ else
+ m_permissions = perms;
+ } break;
+ case 'r':
+ m_permissions |= lldb::eFilePermissionsUserRead;
+ break;
+ case 'w':
+ m_permissions |= lldb::eFilePermissionsUserWrite;
+ break;
+ case 'x':
+ m_permissions |= lldb::eFilePermissionsUserExecute;
+ break;
+ case 'R':
+ m_permissions |= lldb::eFilePermissionsGroupRead;
+ break;
+ case 'W':
+ m_permissions |= lldb::eFilePermissionsGroupWrite;
+ break;
+ case 'X':
+ m_permissions |= lldb::eFilePermissionsGroupExecute;
+ break;
+ case 'd':
+ m_permissions |= lldb::eFilePermissionsWorldRead;
+ break;
+ case 't':
+ m_permissions |= lldb::eFilePermissionsWorldWrite;
+ break;
+ case 'e':
+ m_permissions |= lldb::eFilePermissionsWorldExecute;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
+ break;
}
- ~OptionPermissions() override = default;
+ return error;
+ }
- lldb_private::Error
- SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg) override
- {
- Error error;
- char short_option = (char) GetDefinitions()[option_idx].short_option;
- switch (short_option)
- {
- case 'v':
- {
- bool ok;
- uint32_t perms = StringConvert::ToUInt32(option_arg, 777, 8, &ok);
- if (!ok)
- error.SetErrorStringWithFormat("invalid value for permissions: %s", option_arg);
- else
- m_permissions = perms;
- }
- break;
- case 's':
- {
- mode_t perms = ParsePermissionString(option_arg);
- if (perms == (mode_t)-1)
- error.SetErrorStringWithFormat("invalid value for permissions: %s", option_arg);
- else
- m_permissions = perms;
- }
- break;
- case 'r':
- m_permissions |= lldb::eFilePermissionsUserRead;
- break;
- case 'w':
- m_permissions |= lldb::eFilePermissionsUserWrite;
- break;
- case 'x':
- m_permissions |= lldb::eFilePermissionsUserExecute;
- break;
- case 'R':
- m_permissions |= lldb::eFilePermissionsGroupRead;
- break;
- case 'W':
- m_permissions |= lldb::eFilePermissionsGroupWrite;
- break;
- case 'X':
- m_permissions |= lldb::eFilePermissionsGroupExecute;
- break;
- case 'd':
- m_permissions |= lldb::eFilePermissionsWorldRead;
- break;
- case 't':
- m_permissions |= lldb::eFilePermissionsWorldWrite;
- break;
- case 'e':
- m_permissions |= lldb::eFilePermissionsWorldExecute;
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting (CommandInterpreter &interpreter) override
- {
- m_permissions = 0;
- }
-
- uint32_t
- GetNumDefinitions () override
- {
- return llvm::array_lengthof(g_permissions_options);
- }
-
- const lldb_private::OptionDefinition*
- GetDefinitions () override
- {
- return g_permissions_options;
- }
-
- // Instance variables to hold the values for command options.
-
- uint32_t m_permissions;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_permissions = 0;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_permissions_options);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ uint32_t m_permissions;
private:
- DISALLOW_COPY_AND_ASSIGN(OptionPermissions);
+ DISALLOW_COPY_AND_ASSIGN(OptionPermissions);
};
//----------------------------------------------------------------------
// "platform select <platform-name>"
//----------------------------------------------------------------------
-class CommandObjectPlatformSelect : public CommandObjectParsed
-{
+class CommandObjectPlatformSelect : public CommandObjectParsed {
public:
- CommandObjectPlatformSelect (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform select",
- "Create a platform if needed and select it as the current platform.",
- "platform select <platform-name>",
- 0),
- m_option_group (interpreter),
- m_platform_options (false) // Don't include the "--platform" option by passing false
- {
- m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, 1);
- m_option_group.Finalize();
- }
-
- ~CommandObjectPlatformSelect() override = default;
-
- int
- HandleCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::PlatformPluginNames(m_interpreter,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
- }
-
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
+ CommandObjectPlatformSelect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform select",
+ "Create a platform if needed and select it as the "
+ "current platform.",
+ "platform select <platform-name>", 0),
+ m_option_group(),
+ m_platform_options(
+ false) // Don't include the "--platform" option by passing false
+ {
+ m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectPlatformSelect() override = default;
+
+ int HandleCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position, int match_start_point,
+ int max_return_elements, bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index));
+ completion_str.erase(cursor_char_position);
+
+ CommandCompletions::PlatformPluginNames(
+ GetCommandInterpreter(), completion_str.c_str(), match_start_point,
+ max_return_elements, nullptr, word_complete, matches);
+ return matches.GetSize();
+ }
+
+ Options *GetOptions() override { return &m_option_group; }
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- if (args.GetArgumentCount() == 1)
- {
- const char *platform_name = args.GetArgumentAtIndex (0);
- if (platform_name && platform_name[0])
- {
- const bool select = true;
- m_platform_options.SetPlatformName (platform_name);
- Error error;
- ArchSpec platform_arch;
- PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, ArchSpec(), select, error, platform_arch));
- if (platform_sp)
- {
- m_interpreter.GetDebugger().GetPlatformList().SetSelectedPlatform(platform_sp);
-
- platform_sp->GetStatus (result.GetOutputStream());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError(error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("invalid platform name");
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("platform create takes a platform name as an argument\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ if (args.GetArgumentCount() == 1) {
+ const char *platform_name = args.GetArgumentAtIndex(0);
+ if (platform_name && platform_name[0]) {
+ const bool select = true;
+ m_platform_options.SetPlatformName(platform_name);
+ Error error;
+ ArchSpec platform_arch;
+ PlatformSP platform_sp(m_platform_options.CreatePlatformWithOptions(
+ m_interpreter, ArchSpec(), select, error, platform_arch));
+ if (platform_sp) {
+ m_interpreter.GetDebugger().GetPlatformList().SetSelectedPlatform(
+ platform_sp);
+
+ platform_sp->GetStatus(result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("invalid platform name");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError(
+ "platform create takes a platform name as an argument\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
- OptionGroupOptions m_option_group;
- OptionGroupPlatform m_platform_options;
+ OptionGroupOptions m_option_group;
+ OptionGroupPlatform m_platform_options;
};
//----------------------------------------------------------------------
// "platform list"
//----------------------------------------------------------------------
-class CommandObjectPlatformList : public CommandObjectParsed
-{
+class CommandObjectPlatformList : public CommandObjectParsed {
public:
- CommandObjectPlatformList (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "platform list",
- "List all platforms that are available.",
- nullptr,
- 0)
- {
- }
+ CommandObjectPlatformList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform list",
+ "List all platforms that are available.", nullptr,
+ 0) {}
- ~CommandObjectPlatformList() override = default;
+ ~CommandObjectPlatformList() override = default;
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Stream &ostrm = result.GetOutputStream();
- ostrm.Printf("Available platforms:\n");
-
- PlatformSP host_platform_sp (Platform::GetHostPlatform());
- ostrm.Printf ("%s: %s\n",
- host_platform_sp->GetPluginName().GetCString(),
- host_platform_sp->GetDescription());
-
- uint32_t idx;
- for (idx = 0; 1; ++idx)
- {
- const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (idx);
- if (plugin_name == nullptr)
- break;
- const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (idx);
- if (plugin_desc == nullptr)
- break;
- ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
- }
-
- if (idx == 0)
- {
- result.AppendError ("no platforms are available\n");
- result.SetStatus (eReturnStatusFailed);
- }
- else
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return result.Succeeded();
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Stream &ostrm = result.GetOutputStream();
+ ostrm.Printf("Available platforms:\n");
+
+ PlatformSP host_platform_sp(Platform::GetHostPlatform());
+ ostrm.Printf("%s: %s\n", host_platform_sp->GetPluginName().GetCString(),
+ host_platform_sp->GetDescription());
+
+ uint32_t idx;
+ for (idx = 0; 1; ++idx) {
+ const char *plugin_name =
+ PluginManager::GetPlatformPluginNameAtIndex(idx);
+ if (plugin_name == nullptr)
+ break;
+ const char *plugin_desc =
+ PluginManager::GetPlatformPluginDescriptionAtIndex(idx);
+ if (plugin_desc == nullptr)
+ break;
+ ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
}
+
+ if (idx == 0) {
+ result.AppendError("no platforms are available\n");
+ result.SetStatus(eReturnStatusFailed);
+ } else
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
};
//----------------------------------------------------------------------
// "platform status"
//----------------------------------------------------------------------
-class CommandObjectPlatformStatus : public CommandObjectParsed
-{
+class CommandObjectPlatformStatus : public CommandObjectParsed {
public:
- CommandObjectPlatformStatus(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "platform status", "Display status for the current platform.", nullptr, 0)
- {
- }
+ CommandObjectPlatformStatus(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform status",
+ "Display status for the current platform.", nullptr,
+ 0) {}
- ~CommandObjectPlatformStatus() override = default;
+ ~CommandObjectPlatformStatus() override = default;
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Stream &ostrm = result.GetOutputStream();
-
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- PlatformSP platform_sp;
- if (target)
- {
- platform_sp = target->GetPlatform();
- }
- if (!platform_sp)
- {
- platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
- }
- if (platform_sp)
- {
- platform_sp->GetStatus (ostrm);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError ("no platform us currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Stream &ostrm = result.GetOutputStream();
+
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ PlatformSP platform_sp;
+ if (target) {
+ platform_sp = target->GetPlatform();
+ }
+ if (!platform_sp) {
+ platform_sp =
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
+ }
+ if (platform_sp) {
+ platform_sp->GetStatus(ostrm);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError("no platform us currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
//----------------------------------------------------------------------
// "platform connect <connect-url>"
//----------------------------------------------------------------------
-class CommandObjectPlatformConnect : public CommandObjectParsed
-{
+class CommandObjectPlatformConnect : public CommandObjectParsed {
public:
- CommandObjectPlatformConnect(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "platform connect",
- "Select the current platform by providing a connection URL.",
- "platform connect <connect-url>", 0)
- {
- }
+ CommandObjectPlatformConnect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "platform connect",
+ "Select the current platform by providing a connection URL.",
+ "platform connect <connect-url>", 0) {}
- ~CommandObjectPlatformConnect() override = default;
+ ~CommandObjectPlatformConnect() override = default;
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Stream &ostrm = result.GetOutputStream();
-
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- Error error (platform_sp->ConnectRemote (args));
- if (error.Success())
- {
- platform_sp->GetStatus (ostrm);
- result.SetStatus (eReturnStatusSuccessFinishResult);
-
- platform_sp->ConnectToWaitingProcesses(m_interpreter.GetDebugger(), error);
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("%s\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("no platform is currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Stream &ostrm = result.GetOutputStream();
+
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ Error error(platform_sp->ConnectRemote(args));
+ if (error.Success()) {
+ platform_sp->GetStatus(ostrm);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ platform_sp->ConnectToWaitingProcesses(m_interpreter.GetDebugger(),
+ error);
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendErrorWithFormat("%s\n", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("no platform is currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
}
-
- Options *
- GetOptions () override
- {
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- OptionGroupOptions* m_platform_options = nullptr;
- if (platform_sp)
- {
- m_platform_options = platform_sp->GetConnectionOptions(m_interpreter);
- if (m_platform_options != nullptr && !m_platform_options->m_did_finalize)
- m_platform_options->Finalize();
- }
- return m_platform_options;
+ return result.Succeeded();
+ }
+
+ Options *GetOptions() override {
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ OptionGroupOptions *m_platform_options = nullptr;
+ if (platform_sp) {
+ m_platform_options = platform_sp->GetConnectionOptions(m_interpreter);
+ if (m_platform_options != nullptr && !m_platform_options->m_did_finalize)
+ m_platform_options->Finalize();
}
+ return m_platform_options;
+ }
};
//----------------------------------------------------------------------
// "platform disconnect"
//----------------------------------------------------------------------
-class CommandObjectPlatformDisconnect : public CommandObjectParsed
-{
+class CommandObjectPlatformDisconnect : public CommandObjectParsed {
public:
- CommandObjectPlatformDisconnect(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "platform disconnect", "Disconnect from the current platform.",
- "platform disconnect", 0)
- {
- }
+ CommandObjectPlatformDisconnect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform disconnect",
+ "Disconnect from the current platform.",
+ "platform disconnect", 0) {}
- ~CommandObjectPlatformDisconnect() override = default;
+ ~CommandObjectPlatformDisconnect() override = default;
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- if (args.GetArgumentCount() == 0)
- {
- Error error;
-
- if (platform_sp->IsConnected())
- {
- // Cache the instance name if there is one since we are
- // about to disconnect and the name might go with it.
- const char *hostname_cstr = platform_sp->GetHostname();
- std::string hostname;
- if (hostname_cstr)
- hostname.assign (hostname_cstr);
-
- error = platform_sp->DisconnectRemote ();
- if (error.Success())
- {
- Stream &ostrm = result.GetOutputStream();
- if (hostname.empty())
- ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetPluginName().GetCString());
- else
- ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("%s", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- // Not connected...
- result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetPluginName().GetCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ if (args.GetArgumentCount() == 0) {
+ Error error;
+
+ if (platform_sp->IsConnected()) {
+ // Cache the instance name if there is one since we are
+ // about to disconnect and the name might go with it.
+ const char *hostname_cstr = platform_sp->GetHostname();
+ std::string hostname;
+ if (hostname_cstr)
+ hostname.assign(hostname_cstr);
+
+ error = platform_sp->DisconnectRemote();
+ if (error.Success()) {
+ Stream &ostrm = result.GetOutputStream();
+ if (hostname.empty())
+ ostrm.Printf("Disconnected from \"%s\"\n",
+ platform_sp->GetPluginName().GetCString());
else
- {
- // Bad args
- result.AppendError ("\"platform disconnect\" doesn't take any arguments");
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("no platform is currently selected");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ ostrm.Printf("Disconnected from \"%s\"\n", hostname.c_str());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("%s", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ // Not connected...
+ result.AppendErrorWithFormat(
+ "not connected to '%s'",
+ platform_sp->GetPluginName().GetCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ // Bad args
+ result.AppendError(
+ "\"platform disconnect\" doesn't take any arguments");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("no platform is currently selected");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
//----------------------------------------------------------------------
// "platform settings"
//----------------------------------------------------------------------
-class CommandObjectPlatformSettings : public CommandObjectParsed
-{
+class CommandObjectPlatformSettings : public CommandObjectParsed {
public:
- CommandObjectPlatformSettings (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform settings",
- "Set settings for the current target's platform, or for a platform by name.",
- "platform settings",
- 0),
- m_options (interpreter),
- m_option_working_dir (LLDB_OPT_SET_1, false, "working-dir", 'w', 0, eArgTypePath, "The working directory for the platform.")
- {
- m_options.Append (&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- }
-
- ~CommandObjectPlatformSettings() override = default;
+ CommandObjectPlatformSettings(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform settings",
+ "Set settings for the current target's platform, "
+ "or for a platform by name.",
+ "platform settings", 0),
+ m_options(),
+ m_option_working_dir(LLDB_OPT_SET_1, false, "working-dir", 'w', 0,
+ eArgTypePath,
+ "The working directory for the platform.") {
+ m_options.Append(&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ }
+
+ ~CommandObjectPlatformSettings() override = default;
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- if (m_option_working_dir.GetOptionValue().OptionWasSet())
- platform_sp->SetWorkingDirectory(m_option_working_dir.GetOptionValue().GetCurrentValue());
- }
- else
- {
- result.AppendError ("no platform is currently selected");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
- }
-
- Options *
- GetOptions () override
- {
- if (!m_options.DidFinalize())
- m_options.Finalize();
- return &m_options;
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ if (m_option_working_dir.GetOptionValue().OptionWasSet())
+ platform_sp->SetWorkingDirectory(
+ m_option_working_dir.GetOptionValue().GetCurrentValue());
+ } else {
+ result.AppendError("no platform is currently selected");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
+
+ Options *GetOptions() override {
+ if (!m_options.DidFinalize())
+ m_options.Finalize();
+ return &m_options;
+ }
protected:
- OptionGroupOptions m_options;
- OptionGroupFile m_option_working_dir;
+ OptionGroupOptions m_options;
+ OptionGroupFile m_option_working_dir;
};
//----------------------------------------------------------------------
// "platform mkdir"
//----------------------------------------------------------------------
-class CommandObjectPlatformMkDir : public CommandObjectParsed
-{
+class CommandObjectPlatformMkDir : public CommandObjectParsed {
public:
- CommandObjectPlatformMkDir (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "platform mkdir",
- "Make a new directory on the remote end.",
- nullptr,
+ CommandObjectPlatformMkDir(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform mkdir",
+ "Make a new directory on the remote end.", nullptr,
0),
- m_options(interpreter)
- {
+ m_options() {}
+
+ ~CommandObjectPlatformMkDir() override = default;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ std::string cmd_line;
+ args.GetCommandString(cmd_line);
+ uint32_t mode;
+ const OptionPermissions *options_permissions =
+ (const OptionPermissions *)m_options.GetGroupWithOption('r');
+ if (options_permissions)
+ mode = options_permissions->m_permissions;
+ else
+ mode = lldb::eFilePermissionsUserRWX | lldb::eFilePermissionsGroupRWX |
+ lldb::eFilePermissionsWorldRX;
+ Error error = platform_sp->MakeDirectory(FileSpec{cmd_line, false}, mode);
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("no platform currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
- ~CommandObjectPlatformMkDir() override = default;
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- std::string cmd_line;
- args.GetCommandString(cmd_line);
- uint32_t mode;
- const OptionPermissions* options_permissions = (const OptionPermissions*)m_options.GetGroupWithOption('r');
- if (options_permissions)
- mode = options_permissions->m_permissions;
- else
- mode = lldb::eFilePermissionsUserRWX | lldb::eFilePermissionsGroupRWX | lldb::eFilePermissionsWorldRX;
- Error error = platform_sp->MakeDirectory(FileSpec{cmd_line, false}, mode);
- if (error.Success())
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError(error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("no platform currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
- }
-
- Options *
- GetOptions () override
- {
- if (!m_options.DidFinalize())
- {
- m_options.Append(new OptionPermissions());
- m_options.Finalize();
- }
- return &m_options;
+ Options *GetOptions() override {
+ if (!m_options.DidFinalize()) {
+ m_options.Append(new OptionPermissions());
+ m_options.Finalize();
}
+ return &m_options;
+ }
- OptionGroupOptions m_options;
+ OptionGroupOptions m_options;
};
//----------------------------------------------------------------------
// "platform fopen"
//----------------------------------------------------------------------
-class CommandObjectPlatformFOpen : public CommandObjectParsed
-{
+class CommandObjectPlatformFOpen : public CommandObjectParsed {
public:
- CommandObjectPlatformFOpen (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "platform file open",
- "Open a file on the remote end.",
- nullptr,
- 0),
- m_options(interpreter)
- {
+ CommandObjectPlatformFOpen(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform file open",
+ "Open a file on the remote end.", nullptr, 0),
+ m_options() {}
+
+ ~CommandObjectPlatformFOpen() override = default;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ Error error;
+ std::string cmd_line;
+ args.GetCommandString(cmd_line);
+ mode_t perms;
+ const OptionPermissions *options_permissions =
+ (const OptionPermissions *)m_options.GetGroupWithOption('r');
+ if (options_permissions)
+ perms = options_permissions->m_permissions;
+ else
+ perms = lldb::eFilePermissionsUserRW | lldb::eFilePermissionsGroupRW |
+ lldb::eFilePermissionsWorldRead;
+ lldb::user_id_t fd = platform_sp->OpenFile(
+ FileSpec(cmd_line, false),
+ File::eOpenOptionRead | File::eOpenOptionWrite |
+ File::eOpenOptionAppend | File::eOpenOptionCanCreate,
+ perms, error);
+ if (error.Success()) {
+ result.AppendMessageWithFormat("File Descriptor = %" PRIu64 "\n", fd);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("no platform currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
- ~CommandObjectPlatformFOpen() override = default;
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- Error error;
- std::string cmd_line;
- args.GetCommandString(cmd_line);
- mode_t perms;
- const OptionPermissions* options_permissions = (const OptionPermissions*)m_options.GetGroupWithOption('r');
- if (options_permissions)
- perms = options_permissions->m_permissions;
- else
- perms = lldb::eFilePermissionsUserRW | lldb::eFilePermissionsGroupRW | lldb::eFilePermissionsWorldRead;
- lldb::user_id_t fd = platform_sp->OpenFile(FileSpec(cmd_line.c_str(),false),
- File::eOpenOptionRead | File::eOpenOptionWrite |
- File::eOpenOptionAppend | File::eOpenOptionCanCreate,
- perms,
- error);
- if (error.Success())
- {
- result.AppendMessageWithFormat("File Descriptor = %" PRIu64 "\n",fd);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError(error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("no platform currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ Options *GetOptions() override {
+ if (!m_options.DidFinalize()) {
+ m_options.Append(new OptionPermissions());
+ m_options.Finalize();
}
+ return &m_options;
+ }
- Options *
- GetOptions () override
- {
- if (!m_options.DidFinalize())
- {
- m_options.Append(new OptionPermissions());
- m_options.Finalize();
- }
- return &m_options;
- }
-
- OptionGroupOptions m_options;
+ OptionGroupOptions m_options;
};
//----------------------------------------------------------------------
// "platform fclose"
//----------------------------------------------------------------------
-class CommandObjectPlatformFClose : public CommandObjectParsed
-{
+class CommandObjectPlatformFClose : public CommandObjectParsed {
public:
- CommandObjectPlatformFClose (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "platform file close",
- "Close a file on the remote end.",
- nullptr,
- 0)
- {
- }
-
- ~CommandObjectPlatformFClose() override = default;
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- std::string cmd_line;
- args.GetCommandString(cmd_line);
- const lldb::user_id_t fd = StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX);
- Error error;
- bool success = platform_sp->CloseFile(fd, error);
- if (success)
- {
- result.AppendMessageWithFormat("file %" PRIu64 " closed.\n", fd);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError(error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("no platform currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ CommandObjectPlatformFClose(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform file close",
+ "Close a file on the remote end.", nullptr, 0) {}
+
+ ~CommandObjectPlatformFClose() override = default;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ std::string cmd_line;
+ args.GetCommandString(cmd_line);
+ const lldb::user_id_t fd =
+ StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX);
+ Error error;
+ bool success = platform_sp->CloseFile(fd, error);
+ if (success) {
+ result.AppendMessageWithFormat("file %" PRIu64 " closed.\n", fd);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("no platform currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
//----------------------------------------------------------------------
// "platform fread"
//----------------------------------------------------------------------
-class CommandObjectPlatformFRead : public CommandObjectParsed
-{
+
+static OptionDefinition g_platform_fread_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex, "Offset into the file at which to start reading." },
+ { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Number of bytes to read from the file." },
+ // clang-format on
+};
+
+class CommandObjectPlatformFRead : public CommandObjectParsed {
public:
- CommandObjectPlatformFRead (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "platform file read",
- "Read data from a file on the remote end.",
- nullptr,
+ CommandObjectPlatformFRead(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform file read",
+ "Read data from a file on the remote end.", nullptr,
0),
- m_options (interpreter)
- {
+ m_options() {}
+
+ ~CommandObjectPlatformFRead() override = default;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ std::string cmd_line;
+ args.GetCommandString(cmd_line);
+ const lldb::user_id_t fd =
+ StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX);
+ std::string buffer(m_options.m_count, 0);
+ Error error;
+ uint32_t retcode = platform_sp->ReadFile(
+ fd, m_options.m_offset, &buffer[0], m_options.m_count, error);
+ result.AppendMessageWithFormat("Return = %d\n", retcode);
+ result.AppendMessageWithFormat("Data = \"%s\"\n", buffer.c_str());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError("no platform currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
- ~CommandObjectPlatformFRead() override = default;
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- std::string cmd_line;
- args.GetCommandString(cmd_line);
- const lldb::user_id_t fd = StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX);
- std::string buffer(m_options.m_count,0);
- Error error;
- uint32_t retcode = platform_sp->ReadFile(fd, m_options.m_offset, &buffer[0], m_options.m_count, error);
- result.AppendMessageWithFormat("Return = %d\n",retcode);
- result.AppendMessageWithFormat("Data = \"%s\"\n",buffer.c_str());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError ("no platform currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ char short_option = (char)m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'o':
+ if (option_arg.getAsInteger(0, m_offset))
+ error.SetErrorStringWithFormat("invalid offset: '%s'",
+ option_arg.str().c_str());
+ break;
+ case 'c':
+ if (option_arg.getAsInteger(0, m_count))
+ error.SetErrorStringWithFormat("invalid offset: '%s'",
+ option_arg.str().c_str());
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_offset = 0;
+ m_count = 1;
}
-
-protected:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
- bool success = false;
-
- switch (short_option)
- {
- case 'o':
- m_offset = StringConvert::ToUInt32(option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
- break;
- case 'c':
- m_count = StringConvert::ToUInt32(option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_offset = 0;
- m_count = 1;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- uint32_t m_offset;
- uint32_t m_count;
- };
-
- CommandOptions m_options;
-};
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_platform_fread_options);
+ }
-OptionDefinition
-CommandObjectPlatformFRead::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex , "Offset into the file at which to start reading." },
- { LLDB_OPT_SET_1, false, "count" , 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount , "Number of bytes to read from the file." },
- { 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone , nullptr }
+ // Instance variables to hold the values for command options.
+
+ uint32_t m_offset;
+ uint32_t m_count;
+ };
+
+ CommandOptions m_options;
};
//----------------------------------------------------------------------
// "platform fwrite"
//----------------------------------------------------------------------
-class CommandObjectPlatformFWrite : public CommandObjectParsed
-{
+
+static OptionDefinition g_platform_fwrite_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex, "Offset into the file at which to start reading." },
+ { LLDB_OPT_SET_1, false, "data", 'd', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeValue, "Text to write to the file." },
+ // clang-format on
+};
+
+class CommandObjectPlatformFWrite : public CommandObjectParsed {
public:
- CommandObjectPlatformFWrite (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "platform file write",
- "Write data to a file on the remote end.",
- nullptr,
+ CommandObjectPlatformFWrite(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform file write",
+ "Write data to a file on the remote end.", nullptr,
0),
- m_options (interpreter)
- {
+ m_options() {}
+
+ ~CommandObjectPlatformFWrite() override = default;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ std::string cmd_line;
+ args.GetCommandString(cmd_line);
+ Error error;
+ const lldb::user_id_t fd =
+ StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX);
+ uint32_t retcode =
+ platform_sp->WriteFile(fd, m_options.m_offset, &m_options.m_data[0],
+ m_options.m_data.size(), error);
+ result.AppendMessageWithFormat("Return = %d\n", retcode);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError("no platform currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
- ~CommandObjectPlatformFWrite() override = default;
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- std::string cmd_line;
- args.GetCommandString(cmd_line);
- Error error;
- const lldb::user_id_t fd = StringConvert::ToUInt64(cmd_line.c_str(), UINT64_MAX);
- uint32_t retcode = platform_sp->WriteFile (fd,
- m_options.m_offset,
- &m_options.m_data[0],
- m_options.m_data.size(),
- error);
- result.AppendMessageWithFormat("Return = %d\n",retcode);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError ("no platform currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ char short_option = (char)m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'o':
+ if (option_arg.getAsInteger(0, m_offset))
+ error.SetErrorStringWithFormat("invalid offset: '%s'",
+ option_arg.str().c_str());
+ break;
+ case 'd':
+ m_data.assign(option_arg);
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_offset = 0;
+ m_data.clear();
}
-
-protected:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
- bool success = false;
-
- switch (short_option)
- {
- case 'o':
- m_offset = StringConvert::ToUInt32(option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
- break;
- case 'd':
- m_data.assign(option_arg);
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_offset = 0;
- m_data.clear();
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- uint32_t m_offset;
- std::string m_data;
- };
-
- CommandOptions m_options;
-};
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_platform_fwrite_options);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ uint32_t m_offset;
+ std::string m_data;
+ };
-OptionDefinition
-CommandObjectPlatformFWrite::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex , "Offset into the file at which to start reading." },
- { LLDB_OPT_SET_1, false, "data" , 'd', OptionParser::eRequiredArgument , nullptr, nullptr, 0, eArgTypeValue , "Text to write to the file." },
- { 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone , nullptr }
+ CommandOptions m_options;
};
-class CommandObjectPlatformFile : public CommandObjectMultiword
-{
+class CommandObjectPlatformFile : public CommandObjectMultiword {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectPlatformFile(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "platform file", "Commands to access files on the current platform.",
- "platform file [open|close|read|write] ...")
- {
- LoadSubCommand ("open", CommandObjectSP (new CommandObjectPlatformFOpen (interpreter)));
- LoadSubCommand ("close", CommandObjectSP (new CommandObjectPlatformFClose (interpreter)));
- LoadSubCommand ("read", CommandObjectSP (new CommandObjectPlatformFRead (interpreter)));
- LoadSubCommand ("write", CommandObjectSP (new CommandObjectPlatformFWrite (interpreter)));
- }
-
- ~CommandObjectPlatformFile() override = default;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectPlatformFile(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "platform file",
+ "Commands to access files on the current platform.",
+ "platform file [open|close|read|write] ...") {
+ LoadSubCommand(
+ "open", CommandObjectSP(new CommandObjectPlatformFOpen(interpreter)));
+ LoadSubCommand(
+ "close", CommandObjectSP(new CommandObjectPlatformFClose(interpreter)));
+ LoadSubCommand(
+ "read", CommandObjectSP(new CommandObjectPlatformFRead(interpreter)));
+ LoadSubCommand(
+ "write", CommandObjectSP(new CommandObjectPlatformFWrite(interpreter)));
+ }
+
+ ~CommandObjectPlatformFile() override = default;
private:
- //------------------------------------------------------------------
- // For CommandObjectPlatform only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformFile);
+ //------------------------------------------------------------------
+ // For CommandObjectPlatform only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(CommandObjectPlatformFile);
};
//----------------------------------------------------------------------
// "platform get-file remote-file-path host-file-path"
//----------------------------------------------------------------------
-class CommandObjectPlatformGetFile : public CommandObjectParsed
-{
+class CommandObjectPlatformGetFile : public CommandObjectParsed {
public:
- CommandObjectPlatformGetFile (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform get-file",
- "Transfer a file from the remote end to the local host.",
- "platform get-file <remote-file-spec> <local-file-spec>",
- 0)
- {
- SetHelpLong(
-R"(Examples:
+ CommandObjectPlatformGetFile(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "platform get-file",
+ "Transfer a file from the remote end to the local host.",
+ "platform get-file <remote-file-spec> <local-file-spec>", 0) {
+ SetHelpLong(
+ R"(Examples:
(lldb) platform get-file /the/remote/file/path /the/local/file/path
- Transfer a file from the remote end with file path /the/remote/file/path to the local host.)"
- );
-
- CommandArgumentEntry arg1, arg2;
- CommandArgumentData file_arg_remote, file_arg_host;
-
- // Define the first (and only) variant of this arg.
- file_arg_remote.arg_type = eArgTypeFilename;
- file_arg_remote.arg_repetition = eArgRepeatPlain;
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (file_arg_remote);
-
- // Define the second (and only) variant of this arg.
- file_arg_host.arg_type = eArgTypeFilename;
- file_arg_host.arg_repetition = eArgRepeatPlain;
- // There is only one variant this argument could be; put it into the argument entry.
- arg2.push_back (file_arg_host);
-
- // Push the data for the first and the second arguments into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
+ Transfer a file from the remote end with file path /the/remote/file/path to the local host.)");
+
+ CommandArgumentEntry arg1, arg2;
+ CommandArgumentData file_arg_remote, file_arg_host;
+
+ // Define the first (and only) variant of this arg.
+ file_arg_remote.arg_type = eArgTypeFilename;
+ file_arg_remote.arg_repetition = eArgRepeatPlain;
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(file_arg_remote);
+
+ // Define the second (and only) variant of this arg.
+ file_arg_host.arg_type = eArgTypeFilename;
+ file_arg_host.arg_repetition = eArgRepeatPlain;
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(file_arg_host);
+
+ // Push the data for the first and the second arguments into the m_arguments
+ // vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ }
+
+ ~CommandObjectPlatformGetFile() override = default;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ // If the number of arguments is incorrect, issue an error message.
+ if (args.GetArgumentCount() != 2) {
+ result.GetErrorStream().Printf("error: required arguments missing; "
+ "specify both the source and destination "
+ "file paths\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- ~CommandObjectPlatformGetFile() override = default;
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- // If the number of arguments is incorrect, issue an error message.
- if (args.GetArgumentCount() != 2)
- {
- result.GetErrorStream().Printf("error: required arguments missing; specify both the source and destination file paths\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- const char *remote_file_path = args.GetArgumentAtIndex(0);
- const char *local_file_path = args.GetArgumentAtIndex(1);
- Error error = platform_sp->GetFile(FileSpec(remote_file_path, false),
- FileSpec(local_file_path, false));
- if (error.Success())
- {
- result.AppendMessageWithFormat("successfully get-file from %s (remote) to %s (host)\n",
- remote_file_path, local_file_path);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendMessageWithFormat("get-file failed: %s\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("no platform currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ const char *remote_file_path = args.GetArgumentAtIndex(0);
+ const char *local_file_path = args.GetArgumentAtIndex(1);
+ Error error = platform_sp->GetFile(FileSpec(remote_file_path, false),
+ FileSpec(local_file_path, false));
+ if (error.Success()) {
+ result.AppendMessageWithFormat(
+ "successfully get-file from %s (remote) to %s (host)\n",
+ remote_file_path, local_file_path);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendMessageWithFormat("get-file failed: %s\n",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("no platform currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
//----------------------------------------------------------------------
// "platform get-size remote-file-path"
//----------------------------------------------------------------------
-class CommandObjectPlatformGetSize : public CommandObjectParsed
-{
+class CommandObjectPlatformGetSize : public CommandObjectParsed {
public:
- CommandObjectPlatformGetSize (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform get-size",
- "Get the file size from the remote end.",
- "platform get-size <remote-file-spec>",
- 0)
- {
- SetHelpLong(
-R"(Examples:
+ CommandObjectPlatformGetSize(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform get-size",
+ "Get the file size from the remote end.",
+ "platform get-size <remote-file-spec>", 0) {
+ SetHelpLong(
+ R"(Examples:
(lldb) platform get-size /the/remote/file/path
- Get the file size from the remote end with path /the/remote/file/path.)"
- );
-
- CommandArgumentEntry arg1;
- CommandArgumentData file_arg_remote;
-
- // Define the first (and only) variant of this arg.
- file_arg_remote.arg_type = eArgTypeFilename;
- file_arg_remote.arg_repetition = eArgRepeatPlain;
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (file_arg_remote);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- }
+ Get the file size from the remote end with path /the/remote/file/path.)");
- ~CommandObjectPlatformGetSize() override = default;
+ CommandArgumentEntry arg1;
+ CommandArgumentData file_arg_remote;
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- // If the number of arguments is incorrect, issue an error message.
- if (args.GetArgumentCount() != 1)
- {
- result.GetErrorStream().Printf("error: required argument missing; specify the source file path as the only argument\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ // Define the first (and only) variant of this arg.
+ file_arg_remote.arg_type = eArgTypeFilename;
+ file_arg_remote.arg_repetition = eArgRepeatPlain;
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(file_arg_remote);
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- std::string remote_file_path(args.GetArgumentAtIndex(0));
- user_id_t size = platform_sp->GetFileSize(FileSpec(remote_file_path.c_str(), false));
- if (size != UINT64_MAX)
- {
- result.AppendMessageWithFormat("File size of %s (remote): %" PRIu64 "\n", remote_file_path.c_str(), size);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendMessageWithFormat("Error getting file size of %s (remote)\n", remote_file_path.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("no platform currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectPlatformGetSize() override = default;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ // If the number of arguments is incorrect, issue an error message.
+ if (args.GetArgumentCount() != 1) {
+ result.GetErrorStream().Printf("error: required argument missing; "
+ "specify the source file path as the only "
+ "argument\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ std::string remote_file_path(args.GetArgumentAtIndex(0));
+ user_id_t size =
+ platform_sp->GetFileSize(FileSpec(remote_file_path, false));
+ if (size != UINT64_MAX) {
+ result.AppendMessageWithFormat("File size of %s (remote): %" PRIu64
+ "\n",
+ remote_file_path.c_str(), size);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendMessageWithFormat(
+ "Error getting file size of %s (remote)\n",
+ remote_file_path.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("no platform currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
};
//----------------------------------------------------------------------
// "platform put-file"
//----------------------------------------------------------------------
-class CommandObjectPlatformPutFile : public CommandObjectParsed
-{
+class CommandObjectPlatformPutFile : public CommandObjectParsed {
public:
- CommandObjectPlatformPutFile (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "platform put-file",
- "Transfer a file from this system to the remote end.",
- nullptr,
- 0)
- {
- }
-
- ~CommandObjectPlatformPutFile() override = default;
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- const char* src = args.GetArgumentAtIndex(0);
- const char* dst = args.GetArgumentAtIndex(1);
-
- FileSpec src_fs(src, true);
- FileSpec dst_fs(dst ? dst : src_fs.GetFilename().GetCString(), false);
-
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- Error error (platform_sp->PutFile(src_fs, dst_fs));
- if (error.Success())
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("no platform currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ CommandObjectPlatformPutFile(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "platform put-file",
+ "Transfer a file from this system to the remote end.", nullptr, 0) {
+ }
+
+ ~CommandObjectPlatformPutFile() override = default;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ const char *src = args.GetArgumentAtIndex(0);
+ const char *dst = args.GetArgumentAtIndex(1);
+
+ FileSpec src_fs(src, true);
+ FileSpec dst_fs(dst ? dst : src_fs.GetFilename().GetCString(), false);
+
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ Error error(platform_sp->PutFile(src_fs, dst_fs));
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("no platform currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
//----------------------------------------------------------------------
// "platform process launch"
//----------------------------------------------------------------------
-class CommandObjectPlatformProcessLaunch : public CommandObjectParsed
-{
+class CommandObjectPlatformProcessLaunch : public CommandObjectParsed {
public:
- CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform process launch",
- "Launch a new process on a remote platform.",
- "platform process launch program",
- eCommandRequiresTarget | eCommandTryTargetAPILock),
- m_options (interpreter)
- {
- }
+ CommandObjectPlatformProcessLaunch(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform process launch",
+ "Launch a new process on a remote platform.",
+ "platform process launch program",
+ eCommandRequiresTarget | eCommandTryTargetAPILock),
+ m_options() {}
- ~CommandObjectPlatformProcessLaunch() override = default;
+ ~CommandObjectPlatformProcessLaunch() override = default;
+
+ Options *GetOptions() override { return &m_options; }
- Options *
- GetOptions () override
- {
- return &m_options;
- }
-
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- PlatformSP platform_sp;
- if (target)
- {
- platform_sp = target->GetPlatform();
- }
- if (!platform_sp)
- {
- platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
- }
-
- if (platform_sp)
- {
- Error error;
- const size_t argc = args.GetArgumentCount();
- Target *target = m_exe_ctx.GetTargetPtr();
- Module *exe_module = target->GetExecutableModulePointer();
- if (exe_module)
- {
- m_options.launch_info.GetExecutableFile () = exe_module->GetFileSpec();
- char exe_path[PATH_MAX];
- if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
- m_options.launch_info.GetArguments().AppendArgument (exe_path);
- m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
- }
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ PlatformSP platform_sp;
+ if (target) {
+ platform_sp = target->GetPlatform();
+ }
+ if (!platform_sp) {
+ platform_sp =
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
+ }
- if (argc > 0)
- {
- if (m_options.launch_info.GetExecutableFile ())
- {
- // We already have an executable file, so we will use this
- // and all arguments to this function are extra arguments
- m_options.launch_info.GetArguments().AppendArguments (args);
- }
- else
- {
- // We don't have any file yet, so the first argument is our
- // executable, and the rest are program arguments
- const bool first_arg_is_executable = true;
- m_options.launch_info.SetArguments (args, first_arg_is_executable);
- }
- }
-
- if (m_options.launch_info.GetExecutableFile ())
- {
- Debugger &debugger = m_interpreter.GetDebugger();
-
- if (argc == 0)
- target->GetRunArguments(m_options.launch_info.GetArguments());
-
- ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
- debugger,
- target,
- error));
- if (process_sp && process_sp->IsAlive())
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- return true;
- }
-
- if (error.Success())
- result.AppendError ("process launch failed");
- else
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (platform_sp) {
+ Error error;
+ const size_t argc = args.GetArgumentCount();
+ Target *target = m_exe_ctx.GetTargetPtr();
+ Module *exe_module = target->GetExecutableModulePointer();
+ if (exe_module) {
+ m_options.launch_info.GetExecutableFile() = exe_module->GetFileSpec();
+ llvm::SmallString<PATH_MAX> exe_path;
+ m_options.launch_info.GetExecutableFile().GetPath(exe_path);
+ if (!exe_path.empty())
+ m_options.launch_info.GetArguments().AppendArgument(exe_path);
+ m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
+ }
+
+ if (argc > 0) {
+ if (m_options.launch_info.GetExecutableFile()) {
+ // We already have an executable file, so we will use this
+ // and all arguments to this function are extra arguments
+ m_options.launch_info.GetArguments().AppendArguments(args);
+ } else {
+ // We don't have any file yet, so the first argument is our
+ // executable, and the rest are program arguments
+ const bool first_arg_is_executable = true;
+ m_options.launch_info.SetArguments(args, first_arg_is_executable);
+ }
+ }
+
+ if (m_options.launch_info.GetExecutableFile()) {
+ Debugger &debugger = m_interpreter.GetDebugger();
+
+ if (argc == 0)
+ target->GetRunArguments(m_options.launch_info.GetArguments());
+
+ ProcessSP process_sp(platform_sp->DebugProcess(
+ m_options.launch_info, debugger, target, error));
+ if (process_sp && process_sp->IsAlive()) {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
}
+
+ if (error.Success())
+ result.AppendError("process launch failed");
else
- {
- result.AppendError ("no platform is selected\n");
- }
- return result.Succeeded();
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ result.AppendError("'platform process launch' uses the current target "
+ "file and arguments, or the executable and its "
+ "arguments can be specified in this command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ result.AppendError("no platform is selected\n");
}
-
+ return result.Succeeded();
+ }
+
protected:
- ProcessLaunchCommandOptions m_options;
+ ProcessLaunchCommandOptions m_options;
};
//----------------------------------------------------------------------
// "platform process list"
//----------------------------------------------------------------------
-class CommandObjectPlatformProcessList : public CommandObjectParsed
-{
+
+OptionDefinition g_platform_process_list_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "List the process info for a specific process ID." },
+ { LLDB_OPT_SET_2, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "Find processes with executable basenames that match a string." },
+ { LLDB_OPT_SET_3, true, "ends-with", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "Find processes with executable basenames that end with a string." },
+ { LLDB_OPT_SET_4, true, "starts-with", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "Find processes with executable basenames that start with a string." },
+ { LLDB_OPT_SET_5, true, "contains", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "Find processes with executable basenames that contain a string." },
+ { LLDB_OPT_SET_6, true, "regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." },
+ { LLDB_OPT_SET_FROM_TO(2, 6), false, "parent", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "Find processes that have a matching parent process ID." },
+ { LLDB_OPT_SET_FROM_TO(2, 6), false, "uid", 'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Find processes that have a matching user ID." },
+ { LLDB_OPT_SET_FROM_TO(2, 6), false, "euid", 'U', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective user ID." },
+ { LLDB_OPT_SET_FROM_TO(2, 6), false, "gid", 'g', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Find processes that have a matching group ID." },
+ { LLDB_OPT_SET_FROM_TO(2, 6), false, "egid", 'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective group ID." },
+ { LLDB_OPT_SET_FROM_TO(2, 6), false, "arch", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeArchitecture, "Find processes that have a matching architecture." },
+ { LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show process arguments instead of the process executable basename." },
+ { LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose output." },
+ // clang-format on
+};
+
+class CommandObjectPlatformProcessList : public CommandObjectParsed {
public:
- CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform process list",
- "List processes on a remote platform by name, pid, or many other matching attributes.",
- "platform process list",
- 0),
- m_options (interpreter)
- {
- }
+ CommandObjectPlatformProcessList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform process list",
+ "List processes on a remote platform by name, pid, "
+ "or many other matching attributes.",
+ "platform process list", 0),
+ m_options() {}
- ~CommandObjectPlatformProcessList() override = default;
+ ~CommandObjectPlatformProcessList() override = default;
+
+ Options *GetOptions() override { return &m_options; }
- Options *
- GetOptions () override
- {
- return &m_options;
- }
-
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- PlatformSP platform_sp;
- if (target)
- {
- platform_sp = target->GetPlatform();
- }
- if (!platform_sp)
- {
- platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
- }
-
- if (platform_sp)
- {
- Error error;
- if (args.GetArgumentCount() == 0)
- {
- if (platform_sp)
- {
- Stream &ostrm = result.GetOutputStream();
-
- lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- ProcessInstanceInfo proc_info;
- if (platform_sp->GetProcessInfo (pid, proc_info))
- {
- ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
- proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("no process found with pid = %" PRIu64 "\n", pid);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- ProcessInstanceInfoList proc_infos;
- const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
- const char *match_desc = nullptr;
- const char *match_name = m_options.match_info.GetProcessInfo().GetName();
- if (match_name && match_name[0])
- {
- switch (m_options.match_info.GetNameMatchType())
- {
- case eNameMatchIgnore: break;
- case eNameMatchEquals: match_desc = "matched"; break;
- case eNameMatchContains: match_desc = "contained"; break;
- case eNameMatchStartsWith: match_desc = "started with"; break;
- case eNameMatchEndsWith: match_desc = "ended with"; break;
- case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
- }
- }
-
- if (matches == 0)
- {
- if (match_desc)
- result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
- match_desc,
- match_name,
- platform_sp->GetPluginName().GetCString());
- else
- result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetPluginName().GetCString());
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"",
- matches,
- matches > 1 ? "es were" : " was",
- platform_sp->GetName().GetCString());
- if (match_desc)
- result.AppendMessageWithFormat (" whose name %s \"%s\"",
- match_desc,
- match_name);
- result.AppendMessageWithFormat ("\n");
- ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
- for (uint32_t i=0; i<matches; ++i)
- {
- proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
- }
- }
- }
- }
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ PlatformSP platform_sp;
+ if (target) {
+ platform_sp = target->GetPlatform();
+ }
+ if (!platform_sp) {
+ platform_sp =
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
+ }
+
+ if (platform_sp) {
+ Error error;
+ if (args.GetArgumentCount() == 0) {
+ if (platform_sp) {
+ Stream &ostrm = result.GetOutputStream();
+
+ lldb::pid_t pid =
+ m_options.match_info.GetProcessInfo().GetProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID) {
+ ProcessInstanceInfo proc_info;
+ if (platform_sp->GetProcessInfo(pid, proc_info)) {
+ ProcessInstanceInfo::DumpTableHeader(ostrm, platform_sp.get(),
+ m_options.show_args,
+ m_options.verbose);
+ proc_info.DumpAsTableRow(ostrm, platform_sp.get(),
+ m_options.show_args, m_options.verbose);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat(
+ "no process found with pid = %" PRIu64 "\n", pid);
+ result.SetStatus(eReturnStatusFailed);
}
- else
- {
- result.AppendError ("invalid args: process list takes only options\n");
- result.SetStatus (eReturnStatusFailed);
+ } else {
+ ProcessInstanceInfoList proc_infos;
+ const uint32_t matches =
+ platform_sp->FindProcesses(m_options.match_info, proc_infos);
+ const char *match_desc = nullptr;
+ const char *match_name =
+ m_options.match_info.GetProcessInfo().GetName();
+ if (match_name && match_name[0]) {
+ switch (m_options.match_info.GetNameMatchType()) {
+ case eNameMatchIgnore:
+ break;
+ case eNameMatchEquals:
+ match_desc = "matched";
+ break;
+ case eNameMatchContains:
+ match_desc = "contained";
+ break;
+ case eNameMatchStartsWith:
+ match_desc = "started with";
+ break;
+ case eNameMatchEndsWith:
+ match_desc = "ended with";
+ break;
+ case eNameMatchRegularExpression:
+ match_desc = "matched the regular expression";
+ break;
+ }
}
- }
- else
- {
- result.AppendError ("no platform is selected\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
- }
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions(CommandInterpreter &interpreter) :
- Options(interpreter),
- match_info(),
- show_args(false),
- verbose(false)
- {
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
- PosixPlatformCommandOptionValidator *posix_validator = new PosixPlatformCommandOptionValidator();
- for (size_t i=0; g_option_table[i].short_option != 0; ++i)
- {
- switch (g_option_table[i].short_option)
- {
- case 'u':
- case 'U':
- case 'g':
- case 'G':
- g_option_table[i].validator = posix_validator;
- break;
- default:
- break;
- }
- }
- });
- }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
- bool success = false;
-
- switch (short_option)
- {
- case 'p':
- match_info.GetProcessInfo().SetProcessID (StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
- if (!success)
- error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
- break;
-
- case 'P':
- match_info.GetProcessInfo().SetParentProcessID (StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
- if (!success)
- error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
- break;
-
- case 'u':
- match_info.GetProcessInfo().SetUserID (StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success));
- if (!success)
- error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
- break;
-
- case 'U':
- match_info.GetProcessInfo().SetEffectiveUserID (StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success));
- if (!success)
- error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
- break;
-
- case 'g':
- match_info.GetProcessInfo().SetGroupID (StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success));
- if (!success)
- error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
- break;
-
- case 'G':
- match_info.GetProcessInfo().SetEffectiveGroupID (StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success));
- if (!success)
- error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
- break;
-
- case 'a':
- match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
- break;
-
- case 'n':
- match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
- match_info.SetNameMatchType (eNameMatchEquals);
- break;
-
- case 'e':
- match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
- match_info.SetNameMatchType (eNameMatchEndsWith);
- break;
-
- case 's':
- match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
- match_info.SetNameMatchType (eNameMatchStartsWith);
- break;
-
- case 'c':
- match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
- match_info.SetNameMatchType (eNameMatchContains);
- break;
-
- case 'r':
- match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
- match_info.SetNameMatchType (eNameMatchRegularExpression);
- break;
-
- case 'A':
- show_args = true;
- break;
-
- case 'v':
- verbose = true;
- break;
-
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
+ if (matches == 0) {
+ if (match_desc)
+ result.AppendErrorWithFormat(
+ "no processes were found that %s \"%s\" on the \"%s\" "
+ "platform\n",
+ match_desc, match_name,
+ platform_sp->GetPluginName().GetCString());
+ else
+ result.AppendErrorWithFormat(
+ "no processes were found on the \"%s\" platform\n",
+ platform_sp->GetPluginName().GetCString());
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ result.AppendMessageWithFormat(
+ "%u matching process%s found on \"%s\"", matches,
+ matches > 1 ? "es were" : " was",
+ platform_sp->GetName().GetCString());
+ if (match_desc)
+ result.AppendMessageWithFormat(" whose name %s \"%s\"",
+ match_desc, match_name);
+ result.AppendMessageWithFormat("\n");
+ ProcessInstanceInfo::DumpTableHeader(ostrm, platform_sp.get(),
+ m_options.show_args,
+ m_options.verbose);
+ for (uint32_t i = 0; i < matches; ++i) {
+ proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(
+ ostrm, platform_sp.get(), m_options.show_args,
+ m_options.verbose);
+ }
}
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- match_info.Clear();
- show_args = false;
- verbose = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- ProcessInstanceInfoMatch match_info;
- bool show_args;
- bool verbose;
- };
-
- CommandOptions m_options;
-};
+ }
+ }
+ } else {
+ result.AppendError("invalid args: process list takes only options\n");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("no platform is selected\n");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), match_info(), show_args(false), verbose(false) {
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ PosixPlatformCommandOptionValidator *posix_validator =
+ new PosixPlatformCommandOptionValidator();
+ for (auto &Option : g_platform_process_list_options) {
+ switch (Option.short_option) {
+ case 'u':
+ case 'U':
+ case 'g':
+ case 'G':
+ Option.validator = posix_validator;
+ break;
+ default:
+ break;
+ }
+ }
+ });
+ }
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ bool success = false;
+
+ uint32_t id = LLDB_INVALID_PROCESS_ID;
+ success = !option_arg.getAsInteger(0, id);
+ switch (short_option) {
+ case 'p': {
+ match_info.GetProcessInfo().SetProcessID(id);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid process ID string: '%s'",
+ option_arg.str().c_str());
+ break;
+ }
+ case 'P':
+ match_info.GetProcessInfo().SetParentProcessID(id);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid parent process ID string: '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'u':
+ match_info.GetProcessInfo().SetUserID(success ? id : UINT32_MAX);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid user ID string: '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'U':
+ match_info.GetProcessInfo().SetEffectiveUserID(success ? id
+ : UINT32_MAX);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid effective user ID string: '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'g':
+ match_info.GetProcessInfo().SetGroupID(success ? id : UINT32_MAX);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid group ID string: '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'G':
+ match_info.GetProcessInfo().SetEffectiveGroupID(success ? id
+ : UINT32_MAX);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid effective group ID string: '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'a': {
+ TargetSP target_sp =
+ execution_context ? execution_context->GetTargetSP() : TargetSP();
+ DebuggerSP debugger_sp =
+ target_sp ? target_sp->GetDebugger().shared_from_this()
+ : DebuggerSP();
+ PlatformSP platform_sp =
+ debugger_sp ? debugger_sp->GetPlatformList().GetSelectedPlatform()
+ : PlatformSP();
+ match_info.GetProcessInfo().GetArchitecture().SetTriple(
+ option_arg, platform_sp.get());
+ } break;
+
+ case 'n':
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg,
+ false);
+ match_info.SetNameMatchType(eNameMatchEquals);
+ break;
+
+ case 'e':
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg,
+ false);
+ match_info.SetNameMatchType(eNameMatchEndsWith);
+ break;
+
+ case 's':
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg,
+ false);
+ match_info.SetNameMatchType(eNameMatchStartsWith);
+ break;
+
+ case 'c':
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg,
+ false);
+ match_info.SetNameMatchType(eNameMatchContains);
+ break;
+
+ case 'r':
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(option_arg,
+ false);
+ match_info.SetNameMatchType(eNameMatchRegularExpression);
+ break;
+
+ case 'A':
+ show_args = true;
+ break;
+
+ case 'v':
+ verbose = true;
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ match_info.Clear();
+ show_args = false;
+ verbose = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_platform_process_list_options);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ ProcessInstanceInfoMatch match_info;
+ bool show_args;
+ bool verbose;
+ };
-OptionDefinition
-CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_1 , false, "pid" , 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid , "List the process info for a specific process ID." },
-{ LLDB_OPT_SET_2 , true , "name" , 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
-{ LLDB_OPT_SET_3 , true , "ends-with" , 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName , "Find processes with executable basenames that end with a string." },
-{ LLDB_OPT_SET_4 , true , "starts-with", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName , "Find processes with executable basenames that start with a string." },
-{ LLDB_OPT_SET_5 , true , "contains" , 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName , "Find processes with executable basenames that contain a string." },
-{ LLDB_OPT_SET_6 , true , "regex" , 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "parent" , 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "uid" , 'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger , "Find processes that have a matching user ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "euid" , 'U', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective user ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "gid" , 'g', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger , "Find processes that have a matching group ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "egid" , 'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective group ID." },
-{ LLDB_OPT_SET_FROM_TO(2, 6), false, "arch" , 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
-{ LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args" , 'A', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
-{ LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose" , 'v', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone , "Enable verbose output." },
-{ 0 , false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone , nullptr }
+ CommandOptions m_options;
};
//----------------------------------------------------------------------
// "platform process info"
//----------------------------------------------------------------------
-class CommandObjectPlatformProcessInfo : public CommandObjectParsed
-{
+class CommandObjectPlatformProcessInfo : public CommandObjectParsed {
public:
- CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform process info",
- "Get detailed information for one or more process by process ID.",
- "platform process info <pid> [<pid> <pid> ...]",
- 0)
- {
- CommandArgumentEntry arg;
- CommandArgumentData pid_args;
-
- // Define the first (and only) variant of this arg.
- pid_args.arg_type = eArgTypePid;
- pid_args.arg_repetition = eArgRepeatStar;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (pid_args);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ CommandObjectPlatformProcessInfo(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "platform process info",
+ "Get detailed information for one or more process by process ID.",
+ "platform process info <pid> [<pid> <pid> ...]", 0) {
+ CommandArgumentEntry arg;
+ CommandArgumentData pid_args;
+
+ // Define the first (and only) variant of this arg.
+ pid_args.arg_type = eArgTypePid;
+ pid_args.arg_repetition = eArgRepeatStar;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(pid_args);
- ~CommandObjectPlatformProcessInfo() override = default;
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectPlatformProcessInfo() override = default;
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- PlatformSP platform_sp;
- if (target)
- {
- platform_sp = target->GetPlatform();
- }
- if (!platform_sp)
- {
- platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
- }
-
- if (platform_sp)
- {
- const size_t argc = args.GetArgumentCount();
- if (argc > 0)
- {
- Error error;
-
- if (platform_sp->IsConnected())
- {
- Stream &ostrm = result.GetOutputStream();
- bool success;
- for (size_t i=0; i<argc; ++ i)
- {
- const char *arg = args.GetArgumentAtIndex(i);
- lldb::pid_t pid = StringConvert::ToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
- if (success)
- {
- ProcessInstanceInfo proc_info;
- if (platform_sp->GetProcessInfo (pid, proc_info))
- {
- ostrm.Printf ("Process information for process %" PRIu64 ":\n", pid);
- proc_info.Dump (ostrm, platform_sp.get());
- }
- else
- {
- ostrm.Printf ("error: no process information is available for process %" PRIu64 "\n", pid);
- }
- ostrm.EOL();
- }
- else
- {
- result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg);
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- }
- }
- else
- {
- // Not connected...
- result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetPluginName().GetCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- // No args
- result.AppendError ("one or more process id(s) must be specified");
- result.SetStatus (eReturnStatusFailed);
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ PlatformSP platform_sp;
+ if (target) {
+ platform_sp = target->GetPlatform();
+ }
+ if (!platform_sp) {
+ platform_sp =
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
+ }
+
+ if (platform_sp) {
+ const size_t argc = args.GetArgumentCount();
+ if (argc > 0) {
+ Error error;
+
+ if (platform_sp->IsConnected()) {
+ Stream &ostrm = result.GetOutputStream();
+ for (auto &entry : args.entries()) {
+ lldb::pid_t pid;
+ if (entry.ref.getAsInteger(0, pid)) {
+ result.AppendErrorWithFormat("invalid process ID argument '%s'",
+ entry.ref.str().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ break;
+ } else {
+ ProcessInstanceInfo proc_info;
+ if (platform_sp->GetProcessInfo(pid, proc_info)) {
+ ostrm.Printf("Process information for process %" PRIu64 ":\n",
+ pid);
+ proc_info.Dump(ostrm, platform_sp.get());
+ } else {
+ ostrm.Printf("error: no process information is available for "
+ "process %" PRIu64 "\n",
+ pid);
+ }
+ ostrm.EOL();
}
- }
- else
- {
- result.AppendError ("no platform is currently selected");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ }
+ } else {
+ // Not connected...
+ result.AppendErrorWithFormat(
+ "not connected to '%s'",
+ platform_sp->GetPluginName().GetCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ // No args
+ result.AppendError("one or more process id(s) must be specified");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("no platform is currently selected");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
+};
+
+static OptionDefinition g_platform_process_attach_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use." },
+ { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "The process ID of an existing process to attach to." },
+ { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "The name of the process to attach to." },
+ { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Wait for the process with <process-name> to launch." },
+ // clang-format on
};
-class CommandObjectPlatformProcessAttach : public CommandObjectParsed
-{
+class CommandObjectPlatformProcessAttach : public CommandObjectParsed {
public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
- bool success = false;
- switch (short_option)
- {
- case 'p':
- {
- lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
- if (!success || pid == LLDB_INVALID_PROCESS_ID)
- {
- error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
- }
- else
- {
- attach_info.SetProcessID (pid);
- }
- }
- break;
-
- case 'P':
- attach_info.SetProcessPluginName (option_arg);
- break;
-
- case 'n':
- attach_info.GetExecutableFile().SetFile(option_arg, false);
- break;
-
- case 'w':
- attach_info.SetWaitForLaunch(true);
- break;
-
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- attach_info.Clear();
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- bool
- HandleOptionArgumentCompletion (Args &input,
- int cursor_index,
- int char_pos,
- OptionElementVector &opt_element_vector,
- int opt_element_index,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
- int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
-
- // We are only completing the name option for now...
-
- const OptionDefinition *opt_defs = GetDefinitions();
- if (opt_defs[opt_defs_index].short_option == 'n')
- {
- // Are we in the name?
-
- // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
- // use the default plugin.
-
- const char *partial_name = nullptr;
- partial_name = input.GetArgumentAtIndex(opt_arg_pos);
-
- PlatformSP platform_sp (m_interpreter.GetPlatform (true));
- if (platform_sp)
- {
- ProcessInstanceInfoList process_infos;
- ProcessInstanceInfoMatch match_info;
- if (partial_name)
- {
- match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
- match_info.SetNameMatchType(eNameMatchStartsWith);
- }
- platform_sp->FindProcesses (match_info, process_infos);
- const uint32_t num_matches = process_infos.GetSize();
- if (num_matches > 0)
- {
- for (uint32_t i=0; i<num_matches; ++i)
- {
- matches.AppendString (process_infos.GetProcessNameAtIndex(i),
- process_infos.GetProcessNameLengthAtIndex(i));
- }
- }
- }
- }
-
- return false;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- ProcessAttachInfo attach_info;
- };
-
- CommandObjectPlatformProcessAttach (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform process attach",
- "Attach to a process.",
- "platform process attach <cmd-options>"),
- m_options (interpreter)
- {
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ char short_option = (char)m_getopt_table[option_idx].val;
+ switch (short_option) {
+ case 'p': {
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+ if (option_arg.getAsInteger(0, pid)) {
+ error.SetErrorStringWithFormat("invalid process ID '%s'",
+ option_arg.str().c_str());
+ } else {
+ attach_info.SetProcessID(pid);
+ }
+ } break;
+
+ case 'P':
+ attach_info.SetProcessPluginName(option_arg);
+ break;
+
+ case 'n':
+ attach_info.GetExecutableFile().SetFile(option_arg, false);
+ break;
+
+ case 'w':
+ attach_info.SetWaitForLaunch(true);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
}
- ~CommandObjectPlatformProcessAttach() override = default;
-
- bool
- DoExecute (Args& command,
- CommandReturnObject &result) override
- {
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (platform_sp)
- {
- Error err;
- ProcessSP remote_process_sp =
- platform_sp->Attach(m_options.attach_info, m_interpreter.GetDebugger(), nullptr, err);
- if (err.Fail())
- {
- result.AppendError(err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- else if (!remote_process_sp)
- {
- result.AppendError("could not attach: unknown reason");
- result.SetStatus (eReturnStatusFailed);
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ attach_info.Clear();
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_platform_process_attach_options);
+ }
+
+ bool HandleOptionArgumentCompletion(
+ Args &input, int cursor_index, int char_pos,
+ OptionElementVector &opt_element_vector, int opt_element_index,
+ int match_start_point, int max_return_elements,
+ CommandInterpreter &interpreter, bool &word_complete,
+ StringList &matches) override {
+ int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
+ int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
+
+ // We are only completing the name option for now...
+
+ if (GetDefinitions()[opt_defs_index].short_option == 'n') {
+ // Are we in the name?
+
+ // Look to see if there is a -P argument provided, and if so use that
+ // plugin, otherwise
+ // use the default plugin.
+
+ const char *partial_name = nullptr;
+ partial_name = input.GetArgumentAtIndex(opt_arg_pos);
+
+ PlatformSP platform_sp(interpreter.GetPlatform(true));
+ if (platform_sp) {
+ ProcessInstanceInfoList process_infos;
+ ProcessInstanceInfoMatch match_info;
+ if (partial_name) {
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ partial_name, false);
+ match_info.SetNameMatchType(eNameMatchStartsWith);
+ }
+ platform_sp->FindProcesses(match_info, process_infos);
+ const uint32_t num_matches = process_infos.GetSize();
+ if (num_matches > 0) {
+ for (uint32_t i = 0; i < num_matches; ++i) {
+ matches.AppendString(
+ process_infos.GetProcessNameAtIndex(i),
+ process_infos.GetProcessNameLengthAtIndex(i));
}
- else
- result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
}
- else
- {
- result.AppendError ("no platform is currently selected");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ }
+
+ return false;
}
-
- Options *
- GetOptions () override
- {
- return &m_options;
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ ProcessAttachInfo attach_info;
+ };
+
+ CommandObjectPlatformProcessAttach(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "platform process attach",
+ "Attach to a process.",
+ "platform process attach <cmd-options>"),
+ m_options() {}
+
+ ~CommandObjectPlatformProcessAttach() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (platform_sp) {
+ Error err;
+ ProcessSP remote_process_sp = platform_sp->Attach(
+ m_options.attach_info, m_interpreter.GetDebugger(), nullptr, err);
+ if (err.Fail()) {
+ result.AppendError(err.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ } else if (!remote_process_sp) {
+ result.AppendError("could not attach: unknown reason");
+ result.SetStatus(eReturnStatusFailed);
+ } else
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError("no platform is currently selected");
+ result.SetStatus(eReturnStatusFailed);
}
-
-protected:
- CommandOptions m_options;
-};
+ return result.Succeeded();
+ }
+
+ Options *GetOptions() override { return &m_options; }
-OptionDefinition
-CommandObjectPlatformProcessAttach::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "plugin", 'P' , OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
- { LLDB_OPT_SET_1, false, "pid", 'p' , OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "The process ID of an existing process to attach to."},
- { LLDB_OPT_SET_2, false, "name", 'n' , OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "The name of the process to attach to."},
- { LLDB_OPT_SET_2, false, "waitfor", 'w' , OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."},
- { 0, false, nullptr , 0 , 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
+protected:
+ CommandOptions m_options;
};
-class CommandObjectPlatformProcess : public CommandObjectMultiword
-{
+class CommandObjectPlatformProcess : public CommandObjectMultiword {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectPlatformProcess(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "platform process",
- "Commands to query, launch and attach to processes on the current platform.",
- "platform process [attach|launch|list] ...")
- {
- LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
- LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
- LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
- LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
- }
-
- ~CommandObjectPlatformProcess() override = default;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectPlatformProcess(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "platform process",
+ "Commands to query, launch and attach to "
+ "processes on the current platform.",
+ "platform process [attach|launch|list] ...") {
+ LoadSubCommand(
+ "attach",
+ CommandObjectSP(new CommandObjectPlatformProcessAttach(interpreter)));
+ LoadSubCommand(
+ "launch",
+ CommandObjectSP(new CommandObjectPlatformProcessLaunch(interpreter)));
+ LoadSubCommand("info", CommandObjectSP(new CommandObjectPlatformProcessInfo(
+ interpreter)));
+ LoadSubCommand("list", CommandObjectSP(new CommandObjectPlatformProcessList(
+ interpreter)));
+ }
+
+ ~CommandObjectPlatformProcess() override = default;
private:
- //------------------------------------------------------------------
- // For CommandObjectPlatform only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
+ //------------------------------------------------------------------
+ // For CommandObjectPlatform only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(CommandObjectPlatformProcess);
};
//----------------------------------------------------------------------
// "platform shell"
//----------------------------------------------------------------------
-class CommandObjectPlatformShell : public CommandObjectRaw
-{
+static OptionDefinition g_platform_shell_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command." },
+ // clang-format on
+};
+
+class CommandObjectPlatformShell : public CommandObjectRaw {
public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter),
- timeout(10)
- {
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), timeout(10) {}
- ~CommandOptions() override = default;
+ ~CommandOptions() override = default;
- virtual uint32_t
- GetNumDefinitions ()
- {
- return 1;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- Error
- SetOptionValue (uint32_t option_idx,
- const char *option_value) override
- {
- Error error;
-
- const char short_option = (char) g_option_table[option_idx].short_option;
-
- switch (short_option)
- {
- case 't':
- {
- bool success;
- timeout = StringConvert::ToUInt32(option_value, 10, 10, &success);
- if (!success)
- error.SetErrorStringWithFormat("could not convert \"%s\" to a numeric value.", option_value);
- break;
- }
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
- uint32_t timeout;
- };
-
- CommandObjectPlatformShell(CommandInterpreter &interpreter)
- : CommandObjectRaw(interpreter, "platform shell", "Run a shell command on the current platform.",
- "platform shell <shell-command>", 0),
- m_options(interpreter)
- {
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_platform_shell_options);
+ }
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+
+ const char short_option = (char)GetDefinitions()[option_idx].short_option;
+
+ switch (short_option) {
+ case 't':
+ timeout = 10;
+ if (option_arg.getAsInteger(10, timeout))
+ error.SetErrorStringWithFormat(
+ "could not convert \"%s\" to a numeric value.",
+ option_arg.str().c_str());
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectPlatformShell() override = default;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {}
+
+ uint32_t timeout;
+ };
+
+ CommandObjectPlatformShell(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "platform shell",
+ "Run a shell command on the current platform.",
+ "platform shell <shell-command>", 0),
+ m_options() {}
+
+ ~CommandObjectPlatformShell() override = default;
+
+ Options *GetOptions() override { return &m_options; }
- Options *
- GetOptions () override
- {
- return &m_options;
+ bool DoExecute(const char *raw_command_line,
+ CommandReturnObject &result) override {
+ ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext();
+ m_options.NotifyOptionParsingStarting(&exe_ctx);
+
+ const char *expr = nullptr;
+
+ // Print out an usage syntax on an empty command line.
+ if (raw_command_line[0] == '\0') {
+ result.GetOutputStream().Printf("%s\n", this->GetSyntax().str().c_str());
+ return true;
}
-
- bool
- DoExecute (const char *raw_command_line, CommandReturnObject &result) override
- {
- m_options.NotifyOptionParsingStarting();
-
- const char* expr = nullptr;
-
- // Print out an usage syntax on an empty command line.
- if (raw_command_line[0] == '\0')
- {
- result.GetOutputStream().Printf("%s\n", this->GetSyntax());
- return true;
- }
- if (raw_command_line[0] == '-')
- {
- // We have some options and these options MUST end with --.
- const char *end_options = nullptr;
- const char *s = raw_command_line;
- while (s && s[0])
- {
- end_options = ::strstr (s, "--");
- if (end_options)
- {
- end_options += 2; // Get past the "--"
- if (::isspace (end_options[0]))
- {
- expr = end_options;
- while (::isspace (*expr))
- ++expr;
- break;
- }
- }
- s = end_options;
- }
-
- if (end_options)
- {
- Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
- if (!ParseOptions (args, result))
- return false;
- }
- }
-
- if (expr == nullptr)
- expr = raw_command_line;
-
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- Error error;
- if (platform_sp)
- {
- FileSpec working_dir{};
- std::string output;
- int status = -1;
- int signo = -1;
- error = (platform_sp->RunShellCommand (expr, working_dir, &status, &signo, &output, m_options.timeout));
- if (!output.empty())
- result.GetOutputStream().PutCString(output.c_str());
- if (status > 0)
- {
- if (signo > 0)
- {
- const char *signo_cstr = Host::GetSignalAsCString(signo);
- if (signo_cstr)
- result.GetOutputStream().Printf("error: command returned with status %i and signal %s\n", status, signo_cstr);
- else
- result.GetOutputStream().Printf("error: command returned with status %i and signal %i\n", status, signo);
- }
- else
- result.GetOutputStream().Printf("error: command returned with status %i\n", status);
- }
- }
- else
- {
- result.GetOutputStream().Printf("error: cannot run remote shell commands without a platform\n");
- error.SetErrorString("error: cannot run remote shell commands without a platform");
- }
+ if (raw_command_line[0] == '-') {
+ // We have some options and these options MUST end with --.
+ const char *end_options = nullptr;
+ const char *s = raw_command_line;
+ while (s && s[0]) {
+ end_options = ::strstr(s, "--");
+ if (end_options) {
+ end_options += 2; // Get past the "--"
+ if (::isspace(end_options[0])) {
+ expr = end_options;
+ while (::isspace(*expr))
+ ++expr;
+ break;
+ }
+ }
+ s = end_options;
+ }
+
+ if (end_options) {
+ Args args(
+ llvm::StringRef(raw_command_line, end_options - raw_command_line));
+ if (!ParseOptions(args, result))
+ return false;
+ }
+ }
- if (error.Fail())
- {
- result.AppendError(error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- return true;
+ if (expr == nullptr)
+ expr = raw_command_line;
+
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ Error error;
+ if (platform_sp) {
+ FileSpec working_dir{};
+ std::string output;
+ int status = -1;
+ int signo = -1;
+ error = (platform_sp->RunShellCommand(expr, working_dir, &status, &signo,
+ &output, m_options.timeout));
+ if (!output.empty())
+ result.GetOutputStream().PutCString(output);
+ if (status > 0) {
+ if (signo > 0) {
+ const char *signo_cstr = Host::GetSignalAsCString(signo);
+ if (signo_cstr)
+ result.GetOutputStream().Printf(
+ "error: command returned with status %i and signal %s\n",
+ status, signo_cstr);
+ else
+ result.GetOutputStream().Printf(
+ "error: command returned with status %i and signal %i\n",
+ status, signo);
+ } else
+ result.GetOutputStream().Printf(
+ "error: command returned with status %i\n", status);
+ }
+ } else {
+ result.GetOutputStream().Printf(
+ "error: cannot run remote shell commands without a platform\n");
+ error.SetErrorString(
+ "error: cannot run remote shell commands without a platform");
}
- CommandOptions m_options;
-};
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ return true;
+ }
-OptionDefinition
-CommandObjectPlatformShell::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//----------------------------------------------------------------------
// "platform install" - install a target to a remote end
//----------------------------------------------------------------------
-class CommandObjectPlatformInstall : public CommandObjectParsed
-{
+class CommandObjectPlatformInstall : public CommandObjectParsed {
public:
- CommandObjectPlatformInstall (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "platform target-install",
- "Install a target (bundle or executable file) to the remote end.",
- "platform target-install <local-thing> <remote-sandbox>",
- 0)
- {
+ CommandObjectPlatformInstall(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "platform target-install",
+ "Install a target (bundle or executable file) to the remote end.",
+ "platform target-install <local-thing> <remote-sandbox>", 0) {}
+
+ ~CommandObjectPlatformInstall() override = default;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ if (args.GetArgumentCount() != 2) {
+ result.AppendError("platform target-install takes two arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ // TODO: move the bulk of this code over to the platform itself
+ FileSpec src(args.GetArgumentAtIndex(0), true);
+ FileSpec dst(args.GetArgumentAtIndex(1), false);
+ if (!src.Exists()) {
+ result.AppendError("source location does not exist or is not accessible");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+ if (!platform_sp) {
+ result.AppendError("no platform currently selected");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- ~CommandObjectPlatformInstall() override = default;
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- if (args.GetArgumentCount() != 2)
- {
- result.AppendError("platform target-install takes two arguments");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- // TODO: move the bulk of this code over to the platform itself
- FileSpec src(args.GetArgumentAtIndex(0), true);
- FileSpec dst(args.GetArgumentAtIndex(1), false);
- if (!src.Exists())
- {
- result.AppendError("source location does not exist or is not accessible");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
- if (!platform_sp)
- {
- result.AppendError ("no platform currently selected");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- Error error = platform_sp->Install(src, dst);
- if (error.Success())
- {
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendErrorWithFormat("install failed: %s", error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- }
- return result.Succeeded();
+ Error error = platform_sp->Install(src, dst);
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendErrorWithFormat("install failed: %s", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "platform", "Commands to manage and create platforms.",
- "platform [connect|disconnect|info|list|status|select] ...")
-{
- LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
- LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
- LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
- LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
- LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
- LoadSubCommand ("settings", CommandObjectSP (new CommandObjectPlatformSettings (interpreter)));
- LoadSubCommand ("mkdir", CommandObjectSP (new CommandObjectPlatformMkDir (interpreter)));
- LoadSubCommand ("file", CommandObjectSP (new CommandObjectPlatformFile (interpreter)));
- LoadSubCommand ("get-file", CommandObjectSP (new CommandObjectPlatformGetFile (interpreter)));
- LoadSubCommand ("get-size", CommandObjectSP (new CommandObjectPlatformGetSize (interpreter)));
- LoadSubCommand ("put-file", CommandObjectSP (new CommandObjectPlatformPutFile (interpreter)));
- LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
- LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter)));
- LoadSubCommand ("target-install", CommandObjectSP (new CommandObjectPlatformInstall (interpreter)));
+ : CommandObjectMultiword(
+ interpreter, "platform", "Commands to manage and create platforms.",
+ "platform [connect|disconnect|info|list|status|select] ...") {
+ LoadSubCommand("select",
+ CommandObjectSP(new CommandObjectPlatformSelect(interpreter)));
+ LoadSubCommand("list",
+ CommandObjectSP(new CommandObjectPlatformList(interpreter)));
+ LoadSubCommand("status",
+ CommandObjectSP(new CommandObjectPlatformStatus(interpreter)));
+ LoadSubCommand("connect", CommandObjectSP(
+ new CommandObjectPlatformConnect(interpreter)));
+ LoadSubCommand(
+ "disconnect",
+ CommandObjectSP(new CommandObjectPlatformDisconnect(interpreter)));
+ LoadSubCommand("settings", CommandObjectSP(new CommandObjectPlatformSettings(
+ interpreter)));
+ LoadSubCommand("mkdir",
+ CommandObjectSP(new CommandObjectPlatformMkDir(interpreter)));
+ LoadSubCommand("file",
+ CommandObjectSP(new CommandObjectPlatformFile(interpreter)));
+ LoadSubCommand("get-file", CommandObjectSP(new CommandObjectPlatformGetFile(
+ interpreter)));
+ LoadSubCommand("get-size", CommandObjectSP(new CommandObjectPlatformGetSize(
+ interpreter)));
+ LoadSubCommand("put-file", CommandObjectSP(new CommandObjectPlatformPutFile(
+ interpreter)));
+ LoadSubCommand("process", CommandObjectSP(
+ new CommandObjectPlatformProcess(interpreter)));
+ LoadSubCommand("shell",
+ CommandObjectSP(new CommandObjectPlatformShell(interpreter)));
+ LoadSubCommand(
+ "target-install",
+ CommandObjectSP(new CommandObjectPlatformInstall(interpreter)));
}
CommandObjectPlatform::~CommandObjectPlatform() = default;
diff --git a/source/Commands/CommandObjectPlatform.h b/source/Commands/CommandObjectPlatform.h
index 023dff9f9827..03b8ca00c81d 100644
--- a/source/Commands/CommandObjectPlatform.h
+++ b/source/Commands/CommandObjectPlatform.h
@@ -23,15 +23,14 @@ namespace lldb_private {
// CommandObjectPlatform
//-------------------------------------------------------------------------
-class CommandObjectPlatform : public CommandObjectMultiword
-{
+class CommandObjectPlatform : public CommandObjectMultiword {
public:
- CommandObjectPlatform(CommandInterpreter &interpreter);
+ CommandObjectPlatform(CommandInterpreter &interpreter);
- ~CommandObjectPlatform() override;
+ ~CommandObjectPlatform() override;
private:
- DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatform);
+ DISALLOW_COPY_AND_ASSIGN(CommandObjectPlatform);
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectPlugin.cpp b/source/Commands/CommandObjectPlugin.cpp
index 221c9a67d848..7ae968b95fc8 100644
--- a/source/Commands/CommandObjectPlugin.cpp
+++ b/source/Commands/CommandObjectPlugin.cpp
@@ -19,91 +19,76 @@
using namespace lldb;
using namespace lldb_private;
-class CommandObjectPluginLoad : public CommandObjectParsed
-{
+class CommandObjectPluginLoad : public CommandObjectParsed {
public:
- CommandObjectPluginLoad (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "plugin load",
+ CommandObjectPluginLoad(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "plugin load",
"Import a dylib that implements an LLDB plugin.",
- nullptr)
- {
- CommandArgumentEntry arg1;
- CommandArgumentData cmd_arg;
-
- // Define the first (and only) variant of this arg.
- cmd_arg.arg_type = eArgTypeFilename;
- cmd_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (cmd_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- }
+ nullptr) {
+ CommandArgumentEntry arg1;
+ CommandArgumentData cmd_arg;
- ~CommandObjectPluginLoad() override = default;
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
- }
+ // Define the first (and only) variant of this arg.
+ cmd_arg.arg_type = eArgTypeFilename;
+ cmd_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(cmd_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectPluginLoad() override = default;
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ auto completion_str = input[cursor_index].ref;
+ completion_str = completion_str.take_front(cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ completion_str, match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- size_t argc = command.GetArgumentCount();
-
- if (argc != 1)
- {
- result.AppendError ("'plugin load' requires one argument");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- const char* path = command.GetArgumentAtIndex(0);
-
- Error error;
-
- FileSpec dylib_fspec(path,true);
-
- if (m_interpreter.GetDebugger().LoadPlugin(dylib_fspec, error))
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else
- {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- }
-
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ size_t argc = command.GetArgumentCount();
+
+ if (argc != 1) {
+ result.AppendError("'plugin load' requires one argument");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ Error error;
+
+ FileSpec dylib_fspec(command[0].ref, true);
+
+ if (m_interpreter.GetDebugger().LoadPlugin(dylib_fspec, error))
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+
+ return result.Succeeded();
+ }
};
CommandObjectPlugin::CommandObjectPlugin(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "plugin", "Commands for managing LLDB plugins.",
- "plugin <subcommand> [<subcommand-options>]")
-{
- LoadSubCommand ("load", CommandObjectSP (new CommandObjectPluginLoad (interpreter)));
+ : CommandObjectMultiword(interpreter, "plugin",
+ "Commands for managing LLDB plugins.",
+ "plugin <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("load",
+ CommandObjectSP(new CommandObjectPluginLoad(interpreter)));
}
-
+
CommandObjectPlugin::~CommandObjectPlugin() = default;
diff --git a/source/Commands/CommandObjectPlugin.h b/source/Commands/CommandObjectPlugin.h
index 0a96041d2d31..d67aa43365d5 100644
--- a/source/Commands/CommandObjectPlugin.h
+++ b/source/Commands/CommandObjectPlugin.h
@@ -16,19 +16,18 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-types.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/lldb-types.h"
namespace lldb_private {
-
- class CommandObjectPlugin : public CommandObjectMultiword
- {
- public:
- CommandObjectPlugin (CommandInterpreter &interpreter);
-
- ~CommandObjectPlugin() override;
- };
-
+
+class CommandObjectPlugin : public CommandObjectMultiword {
+public:
+ CommandObjectPlugin(CommandInterpreter &interpreter);
+
+ ~CommandObjectPlugin() override;
+};
+
} // namespace lldb_private
#endif // liblldb_CommandObjectPlugin_h_
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index 106e2d86b18c..5b7f1342328b 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -15,15 +15,15 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
-#include "lldb/Core/State.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
@@ -34,284 +34,275 @@
using namespace lldb;
using namespace lldb_private;
-class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed
-{
+class CommandObjectProcessLaunchOrAttach : public CommandObjectParsed {
public:
- CommandObjectProcessLaunchOrAttach (CommandInterpreter &interpreter,
- const char *name,
- const char *help,
- const char *syntax,
- uint32_t flags,
- const char *new_process_action) :
- CommandObjectParsed (interpreter, name, help, syntax, flags),
- m_new_process_action (new_process_action) {}
+ CommandObjectProcessLaunchOrAttach(CommandInterpreter &interpreter,
+ const char *name, const char *help,
+ const char *syntax, uint32_t flags,
+ const char *new_process_action)
+ : CommandObjectParsed(interpreter, name, help, syntax, flags),
+ m_new_process_action(new_process_action) {}
- ~CommandObjectProcessLaunchOrAttach() override = default;
+ ~CommandObjectProcessLaunchOrAttach() override = default;
protected:
- bool
- StopProcessIfNecessary (Process *process, StateType &state, CommandReturnObject &result)
- {
- state = eStateInvalid;
- if (process)
- {
- state = process->GetState();
-
- if (process->IsAlive() && state != eStateConnected)
- {
- char message[1024];
- if (process->GetState() == eStateAttaching)
- ::snprintf (message, sizeof(message), "There is a pending attach, abort it and %s?", m_new_process_action.c_str());
- else if (process->GetShouldDetach())
- ::snprintf (message, sizeof(message), "There is a running process, detach from it and %s?", m_new_process_action.c_str());
- else
- ::snprintf (message, sizeof(message), "There is a running process, kill it and %s?", m_new_process_action.c_str());
-
- if (!m_interpreter.Confirm (message, true))
- {
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- if (process->GetShouldDetach())
- {
- bool keep_stopped = false;
- Error detach_error (process->Detach(keep_stopped));
- if (detach_error.Success())
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- process = nullptr;
- }
- else
- {
- result.AppendErrorWithFormat ("Failed to detach from process: %s\n", detach_error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- Error destroy_error (process->Destroy(false));
- if (destroy_error.Success())
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- process = nullptr;
- }
- else
- {
- result.AppendErrorWithFormat ("Failed to kill process: %s\n", destroy_error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- }
+ bool StopProcessIfNecessary(Process *process, StateType &state,
+ CommandReturnObject &result) {
+ state = eStateInvalid;
+ if (process) {
+ state = process->GetState();
+
+ if (process->IsAlive() && state != eStateConnected) {
+ char message[1024];
+ if (process->GetState() == eStateAttaching)
+ ::snprintf(message, sizeof(message),
+ "There is a pending attach, abort it and %s?",
+ m_new_process_action.c_str());
+ else if (process->GetShouldDetach())
+ ::snprintf(message, sizeof(message),
+ "There is a running process, detach from it and %s?",
+ m_new_process_action.c_str());
+ else
+ ::snprintf(message, sizeof(message),
+ "There is a running process, kill it and %s?",
+ m_new_process_action.c_str());
+
+ if (!m_interpreter.Confirm(message, true)) {
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ if (process->GetShouldDetach()) {
+ bool keep_stopped = false;
+ Error detach_error(process->Detach(keep_stopped));
+ if (detach_error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ process = nullptr;
+ } else {
+ result.AppendErrorWithFormat(
+ "Failed to detach from process: %s\n",
+ detach_error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
}
+ } else {
+ Error destroy_error(process->Destroy(false));
+ if (destroy_error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ process = nullptr;
+ } else {
+ result.AppendErrorWithFormat("Failed to kill process: %s\n",
+ destroy_error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
}
- return result.Succeeded();
+ }
}
+ return result.Succeeded();
+ }
- std::string m_new_process_action;
+ std::string m_new_process_action;
};
//-------------------------------------------------------------------------
// CommandObjectProcessLaunch
//-------------------------------------------------------------------------
#pragma mark CommandObjectProcessLaunch
-class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach
-{
+class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
public:
- CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
- CommandObjectProcessLaunchOrAttach(interpreter,
- "process launch",
- "Launch the executable in the debugger.",
- nullptr,
- eCommandRequiresTarget,
- "restart"),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData run_args_arg;
-
- // Define the first (and only) variant of this arg.
- run_args_arg.arg_type = eArgTypeRunArgs;
- run_args_arg.arg_repetition = eArgRepeatOptional;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (run_args_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ CommandObjectProcessLaunch(CommandInterpreter &interpreter)
+ : CommandObjectProcessLaunchOrAttach(
+ interpreter, "process launch",
+ "Launch the executable in the debugger.", nullptr,
+ eCommandRequiresTarget, "restart"),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData run_args_arg;
+
+ // Define the first (and only) variant of this arg.
+ run_args_arg.arg_type = eArgTypeRunArgs;
+ run_args_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(run_args_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectProcessLaunch() override = default;
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index));
+ completion_str.erase(cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
+
+ Options *GetOptions() override { return &m_options; }
+
+ const char *GetRepeatCommand(Args &current_command_args,
+ uint32_t index) override {
+ // No repeat for "process launch"...
+ return "";
+ }
- ~CommandObjectProcessLaunch() override = default;
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
+protected:
+ bool DoExecute(Args &launch_args, CommandReturnObject &result) override {
+ Debugger &debugger = m_interpreter.GetDebugger();
+ Target *target = debugger.GetSelectedTarget().get();
+ // If our listener is nullptr, users aren't allows to launch
+ ModuleSP exe_module_sp = target->GetExecutableModule();
+
+ if (exe_module_sp == nullptr) {
+ result.AppendError("no file in target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- Options *
- GetOptions () override
- {
- return &m_options;
+ StateType state = eStateInvalid;
+
+ if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
+ return false;
+
+ llvm::StringRef target_settings_argv0 = target->GetArg0();
+
+ // Determine whether we will disable ASLR or leave it in the default state
+ // (i.e. enabled if the platform supports it).
+ // First check if the process launch options explicitly turn on/off
+ // disabling ASLR. If so, use that setting;
+ // otherwise, use the 'settings target.disable-aslr' setting.
+ bool disable_aslr = false;
+ if (m_options.disable_aslr != eLazyBoolCalculate) {
+ // The user specified an explicit setting on the process launch line. Use
+ // it.
+ disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
+ } else {
+ // The user did not explicitly specify whether to disable ASLR. Fall back
+ // to the target.disable-aslr setting.
+ disable_aslr = target->GetDisableASLR();
}
- const char *
- GetRepeatCommand (Args &current_command_args, uint32_t index) override
- {
- // No repeat for "process launch"...
- return "";
+ if (disable_aslr)
+ m_options.launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
+ else
+ m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
+
+ if (target->GetDetachOnError())
+ m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
+
+ if (target->GetDisableSTDIO())
+ m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
+
+ Args environment;
+ target->GetEnvironmentAsArgs(environment);
+ if (environment.GetArgumentCount() > 0)
+ m_options.launch_info.GetEnvironmentEntries().AppendArguments(
+ environment);
+
+ if (!target_settings_argv0.empty()) {
+ m_options.launch_info.GetArguments().AppendArgument(
+ target_settings_argv0);
+ m_options.launch_info.SetExecutableFile(
+ exe_module_sp->GetPlatformFileSpec(), false);
+ } else {
+ m_options.launch_info.SetExecutableFile(
+ exe_module_sp->GetPlatformFileSpec(), true);
}
-protected:
- bool
- DoExecute (Args& launch_args, CommandReturnObject &result) override
- {
- Debugger &debugger = m_interpreter.GetDebugger();
- Target *target = debugger.GetSelectedTarget().get();
- // If our listener is nullptr, users aren't allows to launch
- ModuleSP exe_module_sp = target->GetExecutableModule();
-
- if (exe_module_sp == nullptr)
- {
- result.AppendError ("no file in target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- StateType state = eStateInvalid;
-
- if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result))
- return false;
-
- const char *target_settings_argv0 = target->GetArg0();
-
- // Determine whether we will disable ASLR or leave it in the default state (i.e. enabled if the platform supports it).
- // First check if the process launch options explicitly turn on/off disabling ASLR. If so, use that setting;
- // otherwise, use the 'settings target.disable-aslr' setting.
- bool disable_aslr = false;
- if (m_options.disable_aslr != eLazyBoolCalculate)
- {
- // The user specified an explicit setting on the process launch line. Use it.
- disable_aslr = (m_options.disable_aslr == eLazyBoolYes);
- }
- else
- {
- // The user did not explicitly specify whether to disable ASLR. Fall back to the target.disable-aslr setting.
- disable_aslr = target->GetDisableASLR ();
- }
-
- if (disable_aslr)
- m_options.launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
- else
- m_options.launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
-
- if (target->GetDetachOnError())
- m_options.launch_info.GetFlags().Set (eLaunchFlagDetachOnError);
-
- if (target->GetDisableSTDIO())
- m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
-
- Args environment;
- target->GetEnvironmentAsArgs (environment);
- if (environment.GetArgumentCount() > 0)
- m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
-
- if (target_settings_argv0)
- {
- m_options.launch_info.GetArguments().AppendArgument (target_settings_argv0);
- m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), false);
- }
- else
- {
- m_options.launch_info.SetExecutableFile(exe_module_sp->GetPlatformFileSpec(), true);
- }
-
- if (launch_args.GetArgumentCount() == 0)
- {
- m_options.launch_info.GetArguments().AppendArguments (target->GetProcessLaunchInfo().GetArguments());
- }
- else
- {
- m_options.launch_info.GetArguments().AppendArguments (launch_args);
- // Save the arguments for subsequent runs in the current target.
- target->SetRunArguments (launch_args);
- }
+ if (launch_args.GetArgumentCount() == 0) {
+ m_options.launch_info.GetArguments().AppendArguments(
+ target->GetProcessLaunchInfo().GetArguments());
+ } else {
+ m_options.launch_info.GetArguments().AppendArguments(launch_args);
+ // Save the arguments for subsequent runs in the current target.
+ target->SetRunArguments(launch_args);
+ }
- StreamString stream;
- Error error = target->Launch(m_options.launch_info, &stream);
-
- if (error.Success())
- {
- ProcessSP process_sp (target->GetProcessSP());
- if (process_sp)
- {
- // There is a race condition where this thread will return up the call stack to the main command
- // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
- // a chance to call PushProcessIOHandler().
- process_sp->SyncIOHandler (0, 2000);
-
- const char *data = stream.GetData();
- if (data && strlen(data) > 0)
- result.AppendMessage(stream.GetData());
- const char *archname = exe_module_sp->GetArchitecture().GetArchitectureName();
- result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- result.SetDidChangeProcessState (true);
- }
- else
- {
- result.AppendError("no error returned from Target::Launch, and target has no process");
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError(error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ StreamString stream;
+ Error error = target->Launch(m_options.launch_info, &stream);
+
+ if (error.Success()) {
+ ProcessSP process_sp(target->GetProcessSP());
+ if (process_sp) {
+ // There is a race condition where this thread will return up the call
+ // stack to the main command
+ // handler and show an (lldb) prompt before HandlePrivateEvent (from
+ // PrivateStateThread) has
+ // a chance to call PushProcessIOHandler().
+ process_sp->SyncIOHandler(0, 2000);
+
+ llvm::StringRef data = stream.GetString();
+ if (!data.empty())
+ result.AppendMessage(data);
+ const char *archname =
+ exe_module_sp->GetArchitecture().GetArchitectureName();
+ result.AppendMessageWithFormat(
+ "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(),
+ exe_module_sp->GetFileSpec().GetPath().c_str(), archname);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ result.SetDidChangeProcessState(true);
+ } else {
+ result.AppendError(
+ "no error returned from Target::Launch, and target has no process");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
protected:
- ProcessLaunchCommandOptions m_options;
+ ProcessLaunchCommandOptions m_options;
};
-
//#define SET1 LLDB_OPT_SET_1
//#define SET2 LLDB_OPT_SET_2
//#define SET3 LLDB_OPT_SET_3
//
-//OptionDefinition
-//CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
+// OptionDefinition
+// CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
//{
-//{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', OptionParser::eNoArgument, nullptr, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."},
-//{ SET1 , false, "stdin", 'i', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Redirect stdin for the process to <path>."},
-//{ SET1 , false, "stdout", 'o', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Redirect stdout for the process to <path>."},
-//{ SET1 , false, "stderr", 'e', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Redirect stderr for the process to <path>."},
-//{ SET1 | SET2 | SET3, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
-//{ SET2 , false, "tty", 't', OptionParser::eOptionalArgument, nullptr, 0, eArgTypeDirectoryName, "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."},
-//{ SET3, false, "no-stdio", 'n', OptionParser::eNoArgument, nullptr, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
-//{ SET1 | SET2 | SET3, false, "working-dir", 'w', OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."},
-//{ 0, false, nullptr, 0, 0, nullptr, 0, eArgTypeNone, nullptr }
+// // clang-format off
+// {SET1 | SET2 | SET3, false, "stop-at-entry", 's', OptionParser::eNoArgument,
+// nullptr, 0, eArgTypeNone, "Stop at the entry point of the program
+// when launching a process."},
+// {SET1, false, "stdin", 'i',
+// OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,
+// "Redirect stdin for the process to <path>."},
+// {SET1, false, "stdout", 'o',
+// OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,
+// "Redirect stdout for the process to <path>."},
+// {SET1, false, "stderr", 'e',
+// OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName,
+// "Redirect stderr for the process to <path>."},
+// {SET1 | SET2 | SET3, false, "plugin", 'p',
+// OptionParser::eRequiredArgument, nullptr, 0, eArgTypePlugin, "Name of
+// the process plugin you want to use."},
+// { SET2, false, "tty", 't',
+// OptionParser::eOptionalArgument, nullptr, 0, eArgTypeDirectoryName, "Start
+// the process in a terminal. If <path> is specified, look for a terminal whose
+// name contains <path>, else start the process in a new terminal."},
+// { SET3, false, "no-stdio", 'n', OptionParser::eNoArgument,
+// nullptr, 0, eArgTypeNone, "Do not set up for terminal I/O to go to
+// running process."},
+// {SET1 | SET2 | SET3, false, "working-dir", 'w',
+// OptionParser::eRequiredArgument, nullptr, 0, eArgTypeDirectoryName, "Set the
+// current working directory to <path> when running the inferior."},
+// {0, false, nullptr, 0, 0, nullptr, 0, eArgTypeNone, nullptr}
+// // clang-format on
//};
//
//#undef SET1
@@ -321,746 +312,627 @@ protected:
//-------------------------------------------------------------------------
// CommandObjectProcessAttach
//-------------------------------------------------------------------------
+
+static OptionDefinition g_process_attach_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "continue", 'c', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Immediately continue the process once attached." },
+ { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use." },
+ { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "The process ID of an existing process to attach to." },
+ { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "The name of the process to attach to." },
+ { LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Include existing processes when doing attach -w." },
+ { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Wait for the process with <process-name> to launch." },
+ // clang-format on
+};
+
#pragma mark CommandObjectProcessAttach
-class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach
-{
+class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach {
public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
- bool success = false;
- switch (short_option)
- {
- case 'c':
- attach_info.SetContinueOnceAttached(true);
- break;
-
- case 'p':
- {
- lldb::pid_t pid = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
- if (!success || pid == LLDB_INVALID_PROCESS_ID)
- {
- error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
- }
- else
- {
- attach_info.SetProcessID (pid);
- }
- }
- break;
-
- case 'P':
- attach_info.SetProcessPluginName (option_arg);
- break;
-
- case 'n':
- attach_info.GetExecutableFile().SetFile(option_arg, false);
- break;
-
- case 'w':
- attach_info.SetWaitForLaunch(true);
- break;
-
- case 'i':
- attach_info.SetIgnoreExisting(false);
- break;
-
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option) {
+ case 'c':
+ attach_info.SetContinueOnceAttached(true);
+ break;
+
+ case 'p': {
+ lldb::pid_t pid;
+ if (option_arg.getAsInteger(0, pid)) {
+ error.SetErrorStringWithFormat("invalid process ID '%s'",
+ option_arg.str().c_str());
+ } else {
+ attach_info.SetProcessID(pid);
+ }
+ } break;
+
+ case 'P':
+ attach_info.SetProcessPluginName(option_arg);
+ break;
+
+ case 'n':
+ attach_info.GetExecutableFile().SetFile(option_arg, false);
+ break;
+
+ case 'w':
+ attach_info.SetWaitForLaunch(true);
+ break;
+
+ case 'i':
+ attach_info.SetIgnoreExisting(false);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
+ }
- void
- OptionParsingStarting () override
- {
- attach_info.Clear();
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ attach_info.Clear();
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_process_attach_options);
+ }
- bool
- HandleOptionArgumentCompletion (Args &input,
- int cursor_index,
- int char_pos,
- OptionElementVector &opt_element_vector,
- int opt_element_index,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
- int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
-
- // We are only completing the name option for now...
-
- const OptionDefinition *opt_defs = GetDefinitions();
- if (opt_defs[opt_defs_index].short_option == 'n')
- {
- // Are we in the name?
-
- // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
- // use the default plugin.
-
- const char *partial_name = nullptr;
- partial_name = input.GetArgumentAtIndex(opt_arg_pos);
-
- PlatformSP platform_sp (m_interpreter.GetPlatform (true));
- if (platform_sp)
- {
- ProcessInstanceInfoList process_infos;
- ProcessInstanceInfoMatch match_info;
- if (partial_name)
- {
- match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
- match_info.SetNameMatchType(eNameMatchStartsWith);
- }
- platform_sp->FindProcesses (match_info, process_infos);
- const size_t num_matches = process_infos.GetSize();
- if (num_matches > 0)
- {
- for (size_t i = 0; i < num_matches; ++i)
- {
- matches.AppendString (process_infos.GetProcessNameAtIndex(i),
- process_infos.GetProcessNameLengthAtIndex(i));
- }
- }
- }
+ bool HandleOptionArgumentCompletion(
+ Args &input, int cursor_index, int char_pos,
+ OptionElementVector &opt_element_vector, int opt_element_index,
+ int match_start_point, int max_return_elements,
+ CommandInterpreter &interpreter, bool &word_complete,
+ StringList &matches) override {
+ int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
+ int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
+
+ // We are only completing the name option for now...
+
+ if (GetDefinitions()[opt_defs_index].short_option == 'n') {
+ // Are we in the name?
+
+ // Look to see if there is a -P argument provided, and if so use that
+ // plugin, otherwise
+ // use the default plugin.
+
+ const char *partial_name = nullptr;
+ partial_name = input.GetArgumentAtIndex(opt_arg_pos);
+
+ PlatformSP platform_sp(interpreter.GetPlatform(true));
+ if (platform_sp) {
+ ProcessInstanceInfoList process_infos;
+ ProcessInstanceInfoMatch match_info;
+ if (partial_name) {
+ match_info.GetProcessInfo().GetExecutableFile().SetFile(
+ partial_name, false);
+ match_info.SetNameMatchType(eNameMatchStartsWith);
+ }
+ platform_sp->FindProcesses(match_info, process_infos);
+ const size_t num_matches = process_infos.GetSize();
+ if (num_matches > 0) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ matches.AppendString(
+ process_infos.GetProcessNameAtIndex(i),
+ process_infos.GetProcessNameLengthAtIndex(i));
}
-
- return false;
+ }
}
+ }
- // Options table: Required for subclasses of Options.
+ return false;
+ }
- static OptionDefinition g_option_table[];
+ // Instance variables to hold the values for command options.
- // Instance variables to hold the values for command options.
+ ProcessAttachInfo attach_info;
+ };
- ProcessAttachInfo attach_info;
- };
+ CommandObjectProcessAttach(CommandInterpreter &interpreter)
+ : CommandObjectProcessLaunchOrAttach(
+ interpreter, "process attach", "Attach to a process.",
+ "process attach <cmd-options>", 0, "attach"),
+ m_options() {}
- CommandObjectProcessAttach (CommandInterpreter &interpreter) :
- CommandObjectProcessLaunchOrAttach (interpreter,
- "process attach",
- "Attach to a process.",
- "process attach <cmd-options>",
- 0,
- "attach"),
- m_options (interpreter)
- {
- }
+ ~CommandObjectProcessAttach() override = default;
- ~CommandObjectProcessAttach() override = default;
+ Options *GetOptions() override { return &m_options; }
- Options *
- GetOptions () override
- {
- return &m_options;
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ PlatformSP platform_sp(
+ m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ // N.B. The attach should be synchronous. It doesn't help much to get the
+ // prompt back between initiating the attach
+ // and the target actually stopping. So even if the interpreter is set to
+ // be asynchronous, we wait for the stop
+ // ourselves here.
+
+ StateType state = eStateInvalid;
+ Process *process = m_exe_ctx.GetProcessPtr();
+
+ if (!StopProcessIfNecessary(process, state, result))
+ return false;
+
+ if (target == nullptr) {
+ // If there isn't a current target create one.
+ TargetSP new_target_sp;
+ Error error;
+
+ error = m_interpreter.GetDebugger().GetTargetList().CreateTarget(
+ m_interpreter.GetDebugger(), "", "", false,
+ nullptr, // No platform options
+ new_target_sp);
+ target = new_target_sp.get();
+ if (target == nullptr || error.Fail()) {
+ result.AppendError(error.AsCString("Error creating target"));
+ return false;
+ }
+ m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
-
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- // N.B. The attach should be synchronous. It doesn't help much to get the prompt back between initiating the attach
- // and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop
- // ourselves here.
-
- StateType state = eStateInvalid;
- Process *process = m_exe_ctx.GetProcessPtr();
-
- if (!StopProcessIfNecessary (process, state, result))
- return false;
-
- if (target == nullptr)
- {
- // If there isn't a current target create one.
- TargetSP new_target_sp;
- Error error;
-
- error = m_interpreter.GetDebugger().GetTargetList().CreateTarget(m_interpreter.GetDebugger(),
- nullptr,
- nullptr,
- false,
- nullptr, // No platform options
- new_target_sp);
- target = new_target_sp.get();
- if (target == nullptr || error.Fail())
- {
- result.AppendError(error.AsCString("Error creating target"));
- return false;
- }
- m_interpreter.GetDebugger().GetTargetList().SetSelectedTarget(target);
- }
-
- // Record the old executable module, we want to issue a warning if the process of attaching changed the
- // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.)
-
- ModuleSP old_exec_module_sp = target->GetExecutableModule();
- ArchSpec old_arch_spec = target->GetArchitecture();
-
- if (command.GetArgumentCount())
- {
- result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Record the old executable module, we want to issue a warning if the
+ // process of attaching changed the
+ // current executable (like somebody said "file foo" then attached to a PID
+ // whose executable was bar.)
- m_interpreter.UpdateExecutionContext(nullptr);
- StreamString stream;
- const auto error = target->Attach(m_options.attach_info, &stream);
- if (error.Success())
- {
- ProcessSP process_sp (target->GetProcessSP());
- if (process_sp)
- {
- if (stream.GetData())
- result.AppendMessage(stream.GetData());
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- result.SetDidChangeProcessState (true);
- result.SetAbnormalStopWasExpected(true);
- }
- else
- {
- result.AppendError("no error returned from Target::Attach, and target has no process");
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
+ ModuleSP old_exec_module_sp = target->GetExecutableModule();
+ ArchSpec old_arch_spec = target->GetArchitecture();
- if (!result.Succeeded())
- return false;
-
- // Okay, we're done. Last step is to warn if the executable module has changed:
- char new_path[PATH_MAX];
- ModuleSP new_exec_module_sp (target->GetExecutableModule());
- if (!old_exec_module_sp)
- {
- // We might not have a module if we attached to a raw pid...
- if (new_exec_module_sp)
- {
- new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
- result.AppendMessageWithFormat("Executable module set to \"%s\".\n", new_path);
- }
- }
- else if (old_exec_module_sp->GetFileSpec() != new_exec_module_sp->GetFileSpec())
- {
- char old_path[PATH_MAX];
+ if (command.GetArgumentCount()) {
+ result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: %s\n",
+ m_cmd_name.c_str(), m_cmd_syntax.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- old_exec_module_sp->GetFileSpec().GetPath (old_path, PATH_MAX);
- new_exec_module_sp->GetFileSpec().GetPath (new_path, PATH_MAX);
+ m_interpreter.UpdateExecutionContext(nullptr);
+ StreamString stream;
+ const auto error = target->Attach(m_options.attach_info, &stream);
+ if (error.Success()) {
+ ProcessSP process_sp(target->GetProcessSP());
+ if (process_sp) {
+ result.AppendMessage(stream.GetString());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ result.SetDidChangeProcessState(true);
+ result.SetAbnormalStopWasExpected(true);
+ } else {
+ result.AppendError(
+ "no error returned from Target::Attach, and target has no process");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendErrorWithFormat("attach failed: %s\n", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
- result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n",
- old_path, new_path);
- }
+ if (!result.Succeeded())
+ return false;
+
+ // Okay, we're done. Last step is to warn if the executable module has
+ // changed:
+ char new_path[PATH_MAX];
+ ModuleSP new_exec_module_sp(target->GetExecutableModule());
+ if (!old_exec_module_sp) {
+ // We might not have a module if we attached to a raw pid...
+ if (new_exec_module_sp) {
+ new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
+ result.AppendMessageWithFormat("Executable module set to \"%s\".\n",
+ new_path);
+ }
+ } else if (old_exec_module_sp->GetFileSpec() !=
+ new_exec_module_sp->GetFileSpec()) {
+ char old_path[PATH_MAX];
+
+ old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX);
+ new_exec_module_sp->GetFileSpec().GetPath(new_path, PATH_MAX);
+
+ result.AppendWarningWithFormat(
+ "Executable module changed from \"%s\" to \"%s\".\n", old_path,
+ new_path);
+ }
- if (!old_arch_spec.IsValid())
- {
- result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
- }
- else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
- {
- result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
- old_arch_spec.GetTriple().getTriple().c_str(),
- target->GetArchitecture().GetTriple().getTriple().c_str());
- }
+ if (!old_arch_spec.IsValid()) {
+ result.AppendMessageWithFormat(
+ "Architecture set to: %s.\n",
+ target->GetArchitecture().GetTriple().getTriple().c_str());
+ } else if (!old_arch_spec.IsExactMatch(target->GetArchitecture())) {
+ result.AppendWarningWithFormat(
+ "Architecture changed from %s to %s.\n",
+ old_arch_spec.GetTriple().getTriple().c_str(),
+ target->GetArchitecture().GetTriple().getTriple().c_str());
+ }
- // This supports the use-case scenario of immediately continuing the process once attached.
- if (m_options.attach_info.GetContinueOnceAttached())
- m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
+ // This supports the use-case scenario of immediately continuing the process
+ // once attached.
+ if (m_options.attach_info.GetContinueOnceAttached())
+ m_interpreter.HandleCommand("process continue", eLazyBoolNo, result);
- return result.Succeeded();
- }
-
- CommandOptions m_options;
-};
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectProcessAttach::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_ALL, false, "continue",'c', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Immediately continue the process once attached."},
-{ LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
-{ LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "The process ID of an existing process to attach to."},
-{ LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "The name of the process to attach to."},
-{ LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Include existing processes when doing attach -w."},
-{ LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Wait for the process with <process-name> to launch."},
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectProcessContinue
//-------------------------------------------------------------------------
+
+static OptionDefinition g_process_continue_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread." }
+ // clang-format on
+};
+
#pragma mark CommandObjectProcessContinue
-class CommandObjectProcessContinue : public CommandObjectParsed
-{
+class CommandObjectProcessContinue : public CommandObjectParsed {
public:
- CommandObjectProcessContinue (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process continue",
- "Continue execution of all threads in the current process.",
- "process continue",
- eCommandRequiresProcess |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_options(interpreter)
- {
- }
+ CommandObjectProcessContinue(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "process continue",
+ "Continue execution of all threads in the current process.",
+ "process continue",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options() {}
- ~CommandObjectProcessContinue() override = default;
+ ~CommandObjectProcessContinue() override = default;
protected:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
- bool success = false;
- switch (short_option)
- {
- case 'i':
- m_ignore = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat ("invalid value for ignore option: \"%s\", should be a number.", option_arg);
- break;
-
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_ignore = 0;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- static OptionDefinition g_option_table[];
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option) {
+ case 'i':
+ if (option_arg.getAsInteger(0, m_ignore))
+ error.SetErrorStringWithFormat(
+ "invalid value for ignore option: \"%s\", should be a number.",
+ option_arg.str().c_str());
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
+ }
- uint32_t m_ignore;
- };
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Process *process = m_exe_ctx.GetProcessPtr();
- bool synchronous_execution = m_interpreter.GetSynchronous ();
- StateType state = process->GetState();
- if (state == eStateStopped)
- {
- if (command.GetArgumentCount() != 0)
- {
- result.AppendErrorWithFormat ("The '%s' command does not take any arguments.\n", m_cmd_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_ignore = 0;
+ }
- if (m_options.m_ignore > 0)
- {
- ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
- if (sel_thread_sp)
- {
- StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
- if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
- {
- lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
- BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
- if (bp_site_sp)
- {
- const size_t num_owners = bp_site_sp->GetNumberOfOwners();
- for (size_t i = 0; i < num_owners; i++)
- {
- Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
- if (!bp_ref.IsInternal())
- {
- bp_ref.SetIgnoreCount(m_options.m_ignore);
- }
- }
- }
- }
- }
- }
-
- { // Scope for thread list mutex:
- std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
- const uint32_t num_threads = process->GetThreadList().GetSize();
-
- // Set the actions that the threads should each take when resuming
- for (uint32_t idx=0; idx<num_threads; ++idx)
- {
- const bool override_suspend = false;
- process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState (eStateRunning, override_suspend);
- }
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_process_continue_options);
+ }
- const uint32_t iohandler_id = process->GetIOHandlerID();
-
- StreamString stream;
- Error error;
- if (synchronous_execution)
- error = process->ResumeSynchronous (&stream);
- else
- error = process->Resume ();
-
- if (error.Success())
- {
- // There is a race condition where this thread will return up the call stack to the main command
- // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
- // a chance to call PushProcessIOHandler().
- process->SyncIOHandler(iohandler_id, 2000);
-
- result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
- if (synchronous_execution)
- {
- // If any state changed events had anything to say, add that to the result
- if (stream.GetData())
- result.AppendMessage(stream.GetData());
-
- result.SetDidChangeProcessState (true);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
+ uint32_t m_ignore;
+ };
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Process *process = m_exe_ctx.GetProcessPtr();
+ bool synchronous_execution = m_interpreter.GetSynchronous();
+ StateType state = process->GetState();
+ if (state == eStateStopped) {
+ if (command.GetArgumentCount() != 0) {
+ result.AppendErrorWithFormat(
+ "The '%s' command does not take any arguments.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_options.m_ignore > 0) {
+ ThreadSP sel_thread_sp(GetDefaultThread()->shared_from_this());
+ if (sel_thread_sp) {
+ StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
+ if (stop_info_sp &&
+ stop_info_sp->GetStopReason() == eStopReasonBreakpoint) {
+ lldb::break_id_t bp_site_id =
+ (lldb::break_id_t)stop_info_sp->GetValue();
+ BreakpointSiteSP bp_site_sp(
+ process->GetBreakpointSiteList().FindByID(bp_site_id));
+ if (bp_site_sp) {
+ const size_t num_owners = bp_site_sp->GetNumberOfOwners();
+ for (size_t i = 0; i < num_owners; i++) {
+ Breakpoint &bp_ref =
+ bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
+ if (!bp_ref.IsInternal()) {
+ bp_ref.SetIgnoreCount(m_options.m_ignore);
}
+ }
}
- else
- {
- result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
- StateAsCString(state));
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ }
+ }
+ }
+
+ { // Scope for thread list mutex:
+ std::lock_guard<std::recursive_mutex> guard(
+ process->GetThreadList().GetMutex());
+ const uint32_t num_threads = process->GetThreadList().GetSize();
+
+ // Set the actions that the threads should each take when resuming
+ for (uint32_t idx = 0; idx < num_threads; ++idx) {
+ const bool override_suspend = false;
+ process->GetThreadList().GetThreadAtIndex(idx)->SetResumeState(
+ eStateRunning, override_suspend);
+ }
+ }
+
+ const uint32_t iohandler_id = process->GetIOHandlerID();
+
+ StreamString stream;
+ Error error;
+ if (synchronous_execution)
+ error = process->ResumeSynchronous(&stream);
+ else
+ error = process->Resume();
+
+ if (error.Success()) {
+ // There is a race condition where this thread will return up the call
+ // stack to the main command
+ // handler and show an (lldb) prompt before HandlePrivateEvent (from
+ // PrivateStateThread) has
+ // a chance to call PushProcessIOHandler().
+ process->SyncIOHandler(iohandler_id, 2000);
+
+ result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
+ process->GetID());
+ if (synchronous_execution) {
+ // If any state changed events had anything to say, add that to the
+ // result
+ result.AppendMessage(stream.GetString());
+
+ result.SetDidChangeProcessState(true);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.SetStatus(eReturnStatusSuccessContinuingNoResult);
+ }
+ } else {
+ result.AppendErrorWithFormat("Failed to resume process: %s.\n",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendErrorWithFormat(
+ "Process cannot be continued from its current state (%s).\n",
+ StateAsCString(state));
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
- Options *
- GetOptions () override
- {
- return &m_options;
- }
-
- CommandOptions m_options;
-};
+ Options *GetOptions() override { return &m_options; }
-OptionDefinition
-CommandObjectProcessContinue::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger,
- "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread."},
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectProcessDetach
//-------------------------------------------------------------------------
+static OptionDefinition g_process_detach_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
+ // clang-format on
+};
+
#pragma mark CommandObjectProcessDetach
-class CommandObjectProcessDetach : public CommandObjectParsed
-{
+class CommandObjectProcessDetach : public CommandObjectParsed {
public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- OptionParsingStarting ();
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 's':
- bool tmp_result;
- bool success;
- tmp_result = Args::StringToBoolean(option_arg, false, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid boolean option: \"%s\"", option_arg);
- else
- {
- if (tmp_result)
- m_keep_stopped = eLazyBoolYes;
- else
- m_keep_stopped = eLazyBoolNo;
- }
- break;
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_keep_stopped = eLazyBoolCalculate;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 's':
+ bool tmp_result;
+ bool success;
+ tmp_result = Args::StringToBoolean(option_arg, false, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid boolean option: \"%s\"",
+ option_arg.str().c_str());
+ else {
+ if (tmp_result)
+ m_keep_stopped = eLazyBoolYes;
+ else
+ m_keep_stopped = eLazyBoolNo;
+ }
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
+ }
- // Options table: Required for subclasses of Options.
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_keep_stopped = eLazyBoolCalculate;
+ }
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_process_detach_options);
+ }
- // Instance variables to hold the values for command options.
- LazyBool m_keep_stopped;
- };
+ // Instance variables to hold the values for command options.
+ LazyBool m_keep_stopped;
+ };
- CommandObjectProcessDetach(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "process detach", "Detach from the current target process.",
- "process detach",
- eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched),
- m_options(interpreter)
- {
- }
+ CommandObjectProcessDetach(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process detach",
+ "Detach from the current target process.",
+ "process detach",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched),
+ m_options() {}
- ~CommandObjectProcessDetach() override = default;
+ ~CommandObjectProcessDetach() override = default;
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ Options *GetOptions() override { return &m_options; }
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Process *process = m_exe_ctx.GetProcessPtr();
- // FIXME: This will be a Command Option:
- bool keep_stopped;
- if (m_options.m_keep_stopped == eLazyBoolCalculate)
- {
- // Check the process default:
- keep_stopped = process->GetDetachKeepsStopped();
- }
- else if (m_options.m_keep_stopped == eLazyBoolYes)
- keep_stopped = true;
- else
- keep_stopped = false;
-
- Error error (process->Detach(keep_stopped));
- if (error.Success())
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("Detach failed: %s\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Process *process = m_exe_ctx.GetProcessPtr();
+ // FIXME: This will be a Command Option:
+ bool keep_stopped;
+ if (m_options.m_keep_stopped == eLazyBoolCalculate) {
+ // Check the process default:
+ keep_stopped = process->GetDetachKeepsStopped();
+ } else if (m_options.m_keep_stopped == eLazyBoolYes)
+ keep_stopped = true;
+ else
+ keep_stopped = false;
+
+ Error error(process->Detach(keep_stopped));
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Detach failed: %s\n", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ return result.Succeeded();
+ }
- CommandOptions m_options;
-};
-
-OptionDefinition
-CommandObjectProcessDetach::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." },
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectProcessConnect
//-------------------------------------------------------------------------
+
+static OptionDefinition g_process_connect_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use." },
+ // clang-format on
+};
+
#pragma mark CommandObjectProcessConnect
-class CommandObjectProcessConnect : public CommandObjectParsed
-{
+class CommandObjectProcessConnect : public CommandObjectParsed {
public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'p':
- plugin_name.assign (option_arg);
- break;
-
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- plugin_name.clear();
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- std::string plugin_name;
- };
-
- CommandObjectProcessConnect (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process connect",
- "Connect to a remote debug service.",
- "process connect <remote-url>",
- 0),
- m_options (interpreter)
- {
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'p':
+ plugin_name.assign(option_arg);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
}
- ~CommandObjectProcessConnect() override = default;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ plugin_name.clear();
+ }
- Options *
- GetOptions () override
- {
- return &m_options;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_process_connect_options);
}
-
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- if (command.GetArgumentCount() != 1)
- {
- result.AppendErrorWithFormat ("'%s' takes exactly one argument:\nUsage: %s\n",
- m_cmd_name.c_str(),
- m_cmd_syntax.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- Process *process = m_exe_ctx.GetProcessPtr();
- if (process && process->IsAlive())
- {
- result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
- process->GetID());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Instance variables to hold the values for command options.
- const char *plugin_name = nullptr;
- if (!m_options.plugin_name.empty())
- plugin_name = m_options.plugin_name.c_str();
-
- Error error;
- Debugger& debugger = m_interpreter.GetDebugger();
- PlatformSP platform_sp = m_interpreter.GetPlatform(true);
- ProcessSP process_sp = platform_sp->ConnectProcess(command.GetArgumentAtIndex(0),
- plugin_name,
- debugger,
- debugger.GetSelectedTarget().get(),
- error);
- if (error.Fail() || process_sp == nullptr)
- {
- result.AppendError(error.AsCString("Error connecting to the process"));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- return true;
+ std::string plugin_name;
+ };
+
+ CommandObjectProcessConnect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process connect",
+ "Connect to a remote debug service.",
+ "process connect <remote-url>", 0),
+ m_options() {}
+
+ ~CommandObjectProcessConnect() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (command.GetArgumentCount() != 1) {
+ result.AppendErrorWithFormat(
+ "'%s' takes exactly one argument:\nUsage: %s\n", m_cmd_name.c_str(),
+ m_cmd_syntax.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- CommandOptions m_options;
-};
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process && process->IsAlive()) {
+ result.AppendErrorWithFormat(
+ "Process %" PRIu64
+ " is currently being debugged, kill the process before connecting.\n",
+ process->GetID());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
-OptionDefinition
-CommandObjectProcessConnect::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
- { 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ const char *plugin_name = nullptr;
+ if (!m_options.plugin_name.empty())
+ plugin_name = m_options.plugin_name.c_str();
+
+ Error error;
+ Debugger &debugger = m_interpreter.GetDebugger();
+ PlatformSP platform_sp = m_interpreter.GetPlatform(true);
+ ProcessSP process_sp = platform_sp->ConnectProcess(
+ command.GetArgumentAtIndex(0), plugin_name, debugger,
+ debugger.GetSelectedTarget().get(), error);
+ if (error.Fail() || process_sp == nullptr) {
+ result.AppendError(error.AsCString("Error connecting to the process"));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ return true;
+ }
+
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -1068,162 +940,136 @@ CommandObjectProcessConnect::CommandOptions::g_option_table[] =
//-------------------------------------------------------------------------
#pragma mark CommandObjectProcessPlugin
-class CommandObjectProcessPlugin : public CommandObjectProxy
-{
+class CommandObjectProcessPlugin : public CommandObjectProxy {
public:
- CommandObjectProcessPlugin(CommandInterpreter &interpreter)
- : CommandObjectProxy(interpreter, "process plugin",
- "Send a custom command to the current target process plug-in.", "process plugin <args>", 0)
- {
- }
-
- ~CommandObjectProcessPlugin() override = default;
-
- CommandObject *
- GetProxyCommandObject() override
- {
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process)
- return process->GetPluginCommandObject();
- return nullptr;
- }
+ CommandObjectProcessPlugin(CommandInterpreter &interpreter)
+ : CommandObjectProxy(
+ interpreter, "process plugin",
+ "Send a custom command to the current target process plug-in.",
+ "process plugin <args>", 0) {}
+
+ ~CommandObjectProcessPlugin() override = default;
+
+ CommandObject *GetProxyCommandObject() override {
+ Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process)
+ return process->GetPluginCommandObject();
+ return nullptr;
+ }
};
//-------------------------------------------------------------------------
// CommandObjectProcessLoad
//-------------------------------------------------------------------------
+
+static OptionDefinition g_process_load_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "install", 'i', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypePath, "Install the shared library to the target. If specified without an argument then the library will installed in the current working directory." },
+ // clang-format on
+};
+
#pragma mark CommandObjectProcessLoad
-class CommandObjectProcessLoad : public CommandObjectParsed
-{
+class CommandObjectProcessLoad : public CommandObjectParsed {
public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
- switch (short_option)
- {
- case 'i':
- do_install = true;
- if (option_arg && option_arg[0])
- install_path.SetFile(option_arg, false);
- break;
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- void
- OptionParsingStarting () override
- {
- do_install = false;
- install_path.Clear();
- }
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option) {
+ case 'i':
+ do_install = true;
+ if (!option_arg.empty())
+ install_path.SetFile(option_arg, false);
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ do_install = false;
+ install_path.Clear();
+ }
- // Options table: Required for subclasses of Options.
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
- bool do_install;
- FileSpec install_path;
- };
-
- CommandObjectProcessLoad (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process load",
- "Load a shared library into the current process.",
- "process load <filename> [<filename> ...]",
- eCommandRequiresProcess |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_options (interpreter)
- {
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_process_load_options);
}
- ~CommandObjectProcessLoad() override = default;
+ // Instance variables to hold the values for command options.
+ bool do_install;
+ FileSpec install_path;
+ };
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ CommandObjectProcessLoad(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process load",
+ "Load a shared library into the current process.",
+ "process load <filename> [<filename> ...]",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_options() {}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Process *process = m_exe_ctx.GetProcessPtr();
-
- const size_t argc = command.GetArgumentCount();
- for (uint32_t i = 0; i < argc; ++i)
- {
- Error error;
- PlatformSP platform = process->GetTarget().GetPlatform();
- const char *image_path = command.GetArgumentAtIndex(i);
- uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
-
- if (!m_options.do_install)
- {
- FileSpec image_spec (image_path, false);
- platform->ResolveRemotePath(image_spec, image_spec);
- image_token = platform->LoadImage(process, FileSpec(), image_spec, error);
- }
- else if (m_options.install_path)
- {
- FileSpec image_spec (image_path, true);
- platform->ResolveRemotePath(m_options.install_path, m_options.install_path);
- image_token = platform->LoadImage(process, image_spec, m_options.install_path, error);
- }
- else
- {
- FileSpec image_spec (image_path, true);
- image_token = platform->LoadImage(process, image_spec, FileSpec(), error);
- }
+ ~CommandObjectProcessLoad() override = default;
- if (image_token != LLDB_INVALID_IMAGE_TOKEN)
- {
- result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- return result.Succeeded();
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Process *process = m_exe_ctx.GetProcessPtr();
+
+ for (auto &entry : command.entries()) {
+ Error error;
+ PlatformSP platform = process->GetTarget().GetPlatform();
+ llvm::StringRef image_path = entry.ref;
+ uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
+
+ if (!m_options.do_install) {
+ FileSpec image_spec(image_path, false);
+ platform->ResolveRemotePath(image_spec, image_spec);
+ image_token =
+ platform->LoadImage(process, FileSpec(), image_spec, error);
+ } else if (m_options.install_path) {
+ FileSpec image_spec(image_path, true);
+ platform->ResolveRemotePath(m_options.install_path,
+ m_options.install_path);
+ image_token = platform->LoadImage(process, image_spec,
+ m_options.install_path, error);
+ } else {
+ FileSpec image_spec(image_path, true);
+ image_token =
+ platform->LoadImage(process, image_spec, FileSpec(), error);
+ }
+
+ if (image_token != LLDB_INVALID_IMAGE_TOKEN) {
+ result.AppendMessageWithFormat(
+ "Loading \"%s\"...ok\nImage %u loaded.\n", image_path.str().c_str(),
+ image_token);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("failed to load '%s': %s",
+ image_path.str().c_str(),
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
}
-
- CommandOptions m_options;
-};
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectProcessLoad::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "install", 'i', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypePath, "Install the shared library to the target. If specified without an argument then the library will installed in the current working directory."},
- { 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -1231,60 +1077,47 @@ CommandObjectProcessLoad::CommandOptions::g_option_table[] =
//-------------------------------------------------------------------------
#pragma mark CommandObjectProcessUnload
-class CommandObjectProcessUnload : public CommandObjectParsed
-{
+class CommandObjectProcessUnload : public CommandObjectParsed {
public:
+ CommandObjectProcessUnload(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "process unload",
+ "Unload a shared library from the current process using the index "
+ "returned by a previous call to \"process load\".",
+ "process unload <index>",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
- CommandObjectProcessUnload (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process unload",
- "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
- "process unload <index>",
- eCommandRequiresProcess |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused )
- {
- }
-
- ~CommandObjectProcessUnload() override = default;
+ ~CommandObjectProcessUnload() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Process *process = m_exe_ctx.GetProcessPtr();
-
- const size_t argc = command.GetArgumentCount();
-
- for (uint32_t i = 0; i < argc; ++i)
- {
- const char *image_token_cstr = command.GetArgumentAtIndex(i);
- uint32_t image_token = StringConvert::ToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
- if (image_token == LLDB_INVALID_IMAGE_TOKEN)
- {
- result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- else
- {
- Error error (process->GetTarget().GetPlatform()->UnloadImage(process, image_token));
- if (error.Success())
- {
- result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- }
- }
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Process *process = m_exe_ctx.GetProcessPtr();
+
+ for (auto &entry : command.entries()) {
+ uint32_t image_token;
+ if (entry.ref.getAsInteger(0, image_token)) {
+ result.AppendErrorWithFormat("invalid image index argument '%s'",
+ entry.ref.str().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ break;
+ } else {
+ Error error(process->GetTarget().GetPlatform()->UnloadImage(
+ process, image_token));
+ if (error.Success()) {
+ result.AppendMessageWithFormat(
+ "Unloading shared library with index %u...ok\n", image_token);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("failed to unload image: %s",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ break;
+ }
+ }
}
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
@@ -1292,72 +1125,66 @@ protected:
//-------------------------------------------------------------------------
#pragma mark CommandObjectProcessSignal
-class CommandObjectProcessSignal : public CommandObjectParsed
-{
+class CommandObjectProcessSignal : public CommandObjectParsed {
public:
- CommandObjectProcessSignal(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "process signal", "Send a UNIX signal to the current target process.",
- nullptr, eCommandRequiresProcess | eCommandTryTargetAPILock)
- {
- CommandArgumentEntry arg;
- CommandArgumentData signal_arg;
-
- // Define the first (and only) variant of this arg.
- signal_arg.arg_type = eArgTypeUnixSignal;
- signal_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (signal_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ CommandObjectProcessSignal(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process signal",
+ "Send a UNIX signal to the current target process.",
+ nullptr, eCommandRequiresProcess |
+ eCommandTryTargetAPILock) {
+ CommandArgumentEntry arg;
+ CommandArgumentData signal_arg;
+
+ // Define the first (and only) variant of this arg.
+ signal_arg.arg_type = eArgTypeUnixSignal;
+ signal_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(signal_arg);
- ~CommandObjectProcessSignal() override = default;
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectProcessSignal() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Process *process = m_exe_ctx.GetProcessPtr();
-
- if (command.GetArgumentCount() == 1)
- {
- int signo = LLDB_INVALID_SIGNAL_NUMBER;
-
- const char *signal_name = command.GetArgumentAtIndex(0);
- if (::isxdigit (signal_name[0]))
- signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
- else
- signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
-
- if (signo == LLDB_INVALID_SIGNAL_NUMBER)
- {
- result.AppendErrorWithFormat ("Invalid signal argument '%s'.\n", command.GetArgumentAtIndex(0));
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- Error error (process->Signal (signo));
- if (error.Success())
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("Failed to send signal %i: %s\n", signo, error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- }
- else
- {
- result.AppendErrorWithFormat("'%s' takes exactly one signal number argument:\nUsage: %s\n", m_cmd_name.c_str(),
- m_cmd_syntax.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Process *process = m_exe_ctx.GetProcessPtr();
+
+ if (command.GetArgumentCount() == 1) {
+ int signo = LLDB_INVALID_SIGNAL_NUMBER;
+
+ const char *signal_name = command.GetArgumentAtIndex(0);
+ if (::isxdigit(signal_name[0]))
+ signo =
+ StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0);
+ else
+ signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name);
+
+ if (signo == LLDB_INVALID_SIGNAL_NUMBER) {
+ result.AppendErrorWithFormat("Invalid signal argument '%s'.\n",
+ command.GetArgumentAtIndex(0));
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ Error error(process->Signal(signo));
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Failed to send signal %i: %s\n", signo,
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+ } else {
+ result.AppendErrorWithFormat(
+ "'%s' takes exactly one signal number argument:\nUsage: %s\n",
+ m_cmd_name.c_str(), m_cmd_syntax.c_str());
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
@@ -1365,53 +1192,43 @@ protected:
//-------------------------------------------------------------------------
#pragma mark CommandObjectProcessInterrupt
-class CommandObjectProcessInterrupt : public CommandObjectParsed
-{
+class CommandObjectProcessInterrupt : public CommandObjectParsed {
public:
- CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "process interrupt", "Interrupt the current target process.",
- "process interrupt",
- eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
- {
- }
+ CommandObjectProcessInterrupt(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process interrupt",
+ "Interrupt the current target process.",
+ "process interrupt",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched) {}
- ~CommandObjectProcessInterrupt() override = default;
+ ~CommandObjectProcessInterrupt() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Process *process = m_exe_ctx.GetProcessPtr();
- if (process == nullptr)
- {
- result.AppendError ("no process to halt");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process == nullptr) {
+ result.AppendError("no process to halt");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- bool clear_thread_plans = true;
- Error error(process->Halt (clear_thread_plans));
- if (error.Success())
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("Failed to halt process: %s\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
- m_cmd_name.c_str(),
- m_cmd_syntax.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ if (command.GetArgumentCount() == 0) {
+ bool clear_thread_plans = true;
+ Error error(process->Halt(clear_thread_plans));
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Failed to halt process: %s\n",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
+ m_cmd_name.c_str(), m_cmd_syntax.c_str());
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
@@ -1419,51 +1236,42 @@ protected:
//-------------------------------------------------------------------------
#pragma mark CommandObjectProcessKill
-class CommandObjectProcessKill : public CommandObjectParsed
-{
+class CommandObjectProcessKill : public CommandObjectParsed {
public:
- CommandObjectProcessKill(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "process kill", "Terminate the current target process.", "process kill",
- eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched)
- {
- }
+ CommandObjectProcessKill(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process kill",
+ "Terminate the current target process.",
+ "process kill",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched) {}
- ~CommandObjectProcessKill() override = default;
+ ~CommandObjectProcessKill() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Process *process = m_exe_ctx.GetProcessPtr();
- if (process == nullptr)
- {
- result.AppendError ("no process to kill");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process == nullptr) {
+ result.AppendError("no process to kill");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- Error error (process->Destroy(true));
- if (error.Success())
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("Failed to kill process: %s\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
- m_cmd_name.c_str(),
- m_cmd_syntax.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ if (command.GetArgumentCount() == 0) {
+ Error error(process->Destroy(true));
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Failed to kill process: %s\n",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendErrorWithFormat("'%s' takes no arguments:\nUsage: %s\n",
+ m_cmd_name.c_str(), m_cmd_syntax.c_str());
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
@@ -1471,61 +1279,45 @@ protected:
//-------------------------------------------------------------------------
#pragma mark CommandObjectProcessSaveCore
-class CommandObjectProcessSaveCore : public CommandObjectParsed
-{
+class CommandObjectProcessSaveCore : public CommandObjectParsed {
public:
- CommandObjectProcessSaveCore (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "process save-core",
- "Save the current process as a core file using an appropriate file type.",
- "process save-core FILE",
- eCommandRequiresProcess |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched)
- {
- }
+ CommandObjectProcessSaveCore(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process save-core",
+ "Save the current process as a core file using an "
+ "appropriate file type.",
+ "process save-core FILE",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched) {}
- ~CommandObjectProcessSaveCore() override = default;
+ ~CommandObjectProcessSaveCore() override = default;
protected:
- bool
- DoExecute (Args& command,
- CommandReturnObject &result) override
- {
- ProcessSP process_sp = m_exe_ctx.GetProcessSP();
- if (process_sp)
- {
- if (command.GetArgumentCount() == 1)
- {
- FileSpec output_file(command.GetArgumentAtIndex(0), false);
- Error error = PluginManager::SaveCore(process_sp, output_file);
- if (error.Success())
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("Failed to save core file for process: %s\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("'%s' takes one arguments:\nUsage: %s\n",
- m_cmd_name.c_str(),
- m_cmd_syntax.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("invalid process");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ ProcessSP process_sp = m_exe_ctx.GetProcessSP();
+ if (process_sp) {
+ if (command.GetArgumentCount() == 1) {
+ FileSpec output_file(command.GetArgumentAtIndex(0), false);
+ Error error = PluginManager::SaveCore(process_sp, output_file);
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat(
+ "Failed to save core file for process: %s\n", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendErrorWithFormat("'%s' takes one arguments:\nUsage: %s\n",
+ m_cmd_name.c_str(), m_cmd_syntax.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError("invalid process");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
@@ -1533,359 +1325,333 @@ protected:
//-------------------------------------------------------------------------
#pragma mark CommandObjectProcessStatus
-class CommandObjectProcessStatus : public CommandObjectParsed
-{
+class CommandObjectProcessStatus : public CommandObjectParsed {
public:
- CommandObjectProcessStatus(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "process status",
- "Show status and stop location for the current target process.", "process status",
- eCommandRequiresProcess | eCommandTryTargetAPILock)
- {
- }
-
- ~CommandObjectProcessStatus() override = default;
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Stream &strm = result.GetOutputStream();
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
- Process *process = m_exe_ctx.GetProcessPtr();
- const bool only_threads_with_stop_reason = true;
- const uint32_t start_frame = 0;
- const uint32_t num_frames = 1;
- const uint32_t num_frames_with_source = 1;
- process->GetStatus(strm);
- process->GetThreadStatus (strm,
- only_threads_with_stop_reason,
- start_frame,
- num_frames,
- num_frames_with_source);
- return result.Succeeded();
- }
+ CommandObjectProcessStatus(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "process status",
+ "Show status and stop location for the current target process.",
+ "process status",
+ eCommandRequiresProcess | eCommandTryTargetAPILock) {}
+
+ ~CommandObjectProcessStatus() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Stream &strm = result.GetOutputStream();
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ // No need to check "process" for validity as eCommandRequiresProcess
+ // ensures it is valid
+ Process *process = m_exe_ctx.GetProcessPtr();
+ const bool only_threads_with_stop_reason = true;
+ const uint32_t start_frame = 0;
+ const uint32_t num_frames = 1;
+ const uint32_t num_frames_with_source = 1;
+ const bool stop_format = true;
+ process->GetStatus(strm);
+ process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
+ num_frames, num_frames_with_source, stop_format);
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectProcessHandle
//-------------------------------------------------------------------------
-#pragma mark CommandObjectProcessHandle
-
-class CommandObjectProcessHandle : public CommandObjectParsed
-{
-public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- OptionParsingStarting ();
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 's':
- stop = option_arg;
- break;
- case 'n':
- notify = option_arg;
- break;
- case 'p':
- pass = option_arg;
- break;
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- stop.clear();
- notify.clear();
- pass.clear();
- }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- std::string stop;
- std::string notify;
- std::string pass;
- };
-
- CommandObjectProcessHandle(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "process handle",
- "Manage LLDB handling of OS signals for the current target process. Defaults to showing current policy.",
- nullptr),
- m_options(interpreter)
- {
- SetHelpLong ("\nIf no signals are specified, update them all. If no update "
- "option is specified, list the current values.");
- CommandArgumentEntry arg;
- CommandArgumentData signal_arg;
+static OptionDefinition g_process_handle_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
+ { LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
+ { LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." }
+ // clang-format on
+};
- signal_arg.arg_type = eArgTypeUnixSignal;
- signal_arg.arg_repetition = eArgRepeatStar;
+#pragma mark CommandObjectProcessHandle
- arg.push_back (signal_arg);
-
- m_arguments.push_back (arg);
+class CommandObjectProcessHandle : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 's':
+ stop = option_arg;
+ break;
+ case 'n':
+ notify = option_arg;
+ break;
+ case 'p':
+ pass = option_arg;
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
}
- ~CommandObjectProcessHandle() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ stop.clear();
+ notify.clear();
+ pass.clear();
}
- bool
- VerifyCommandOptionValue (const std::string &option, int &real_value)
- {
- bool okay = true;
- bool success = false;
- bool tmp_value = Args::StringToBoolean (option.c_str(), false, &success);
-
- if (success && tmp_value)
- real_value = 1;
- else if (success && !tmp_value)
- real_value = 0;
- else
- {
- // If the value isn't 'true' or 'false', it had better be 0 or 1.
- real_value = StringConvert::ToUInt32 (option.c_str(), 3);
- if (real_value != 0 && real_value != 1)
- okay = false;
- }
-
- return okay;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_process_handle_options);
}
- void
- PrintSignalHeader (Stream &str)
- {
- str.Printf ("NAME PASS STOP NOTIFY\n");
- str.Printf ("=========== ===== ===== ======\n");
- }
-
- void
- PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp)
- {
- bool stop;
- bool suppress;
- bool notify;
-
- str.Printf ("%-11s ", sig_name);
- if (signals_sp->GetSignalInfo(signo, suppress, stop, notify))
- {
- bool pass = !suppress;
- str.Printf ("%s %s %s",
- (pass ? "true " : "false"),
- (stop ? "true " : "false"),
- (notify ? "true " : "false"));
- }
- str.Printf ("\n");
+ // Instance variables to hold the values for command options.
+
+ std::string stop;
+ std::string notify;
+ std::string pass;
+ };
+
+ CommandObjectProcessHandle(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process handle",
+ "Manage LLDB handling of OS signals for the "
+ "current target process. Defaults to showing "
+ "current policy.",
+ nullptr),
+ m_options() {
+ SetHelpLong("\nIf no signals are specified, update them all. If no update "
+ "option is specified, list the current values.");
+ CommandArgumentEntry arg;
+ CommandArgumentData signal_arg;
+
+ signal_arg.arg_type = eArgTypeUnixSignal;
+ signal_arg.arg_repetition = eArgRepeatStar;
+
+ arg.push_back(signal_arg);
+
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectProcessHandle() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ bool VerifyCommandOptionValue(const std::string &option, int &real_value) {
+ bool okay = true;
+ bool success = false;
+ bool tmp_value = Args::StringToBoolean(option, false, &success);
+
+ if (success && tmp_value)
+ real_value = 1;
+ else if (success && !tmp_value)
+ real_value = 0;
+ else {
+ // If the value isn't 'true' or 'false', it had better be 0 or 1.
+ real_value = StringConvert::ToUInt32(option.c_str(), 3);
+ if (real_value != 0 && real_value != 1)
+ okay = false;
}
- void
- PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp)
+ return okay;
+ }
+
+ void PrintSignalHeader(Stream &str) {
+ str.Printf("NAME PASS STOP NOTIFY\n");
+ str.Printf("=========== ===== ===== ======\n");
+ }
+
+ void PrintSignal(Stream &str, int32_t signo, const char *sig_name,
+ const UnixSignalsSP &signals_sp) {
+ bool stop;
+ bool suppress;
+ bool notify;
+
+ str.Printf("%-11s ", sig_name);
+ if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) {
+ bool pass = !suppress;
+ str.Printf("%s %s %s", (pass ? "true " : "false"),
+ (stop ? "true " : "false"), (notify ? "true " : "false"));
+ }
+ str.Printf("\n");
+ }
+
+ void PrintSignalInformation(Stream &str, Args &signal_args,
+ int num_valid_signals,
+ const UnixSignalsSP &signals_sp) {
+ PrintSignalHeader(str);
+
+ if (num_valid_signals > 0) {
+ size_t num_args = signal_args.GetArgumentCount();
+ for (size_t i = 0; i < num_args; ++i) {
+ int32_t signo = signals_sp->GetSignalNumberFromName(
+ signal_args.GetArgumentAtIndex(i));
+ if (signo != LLDB_INVALID_SIGNAL_NUMBER)
+ PrintSignal(str, signo, signal_args.GetArgumentAtIndex(i),
+ signals_sp);
+ }
+ } else // Print info for ALL signals
{
- PrintSignalHeader (str);
-
- if (num_valid_signals > 0)
- {
- size_t num_args = signal_args.GetArgumentCount();
- for (size_t i = 0; i < num_args; ++i)
- {
- int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp);
- }
- }
- else // Print info for ALL signals
- {
- int32_t signo = signals_sp->GetFirstSignalNumber();
- while (signo != LLDB_INVALID_SIGNAL_NUMBER)
- {
- PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp);
- signo = signals_sp->GetNextSignalNumber(signo);
- }
- }
+ int32_t signo = signals_sp->GetFirstSignalNumber();
+ while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
+ PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo),
+ signals_sp);
+ signo = signals_sp->GetNextSignalNumber(signo);
+ }
}
+ }
protected:
- bool
- DoExecute (Args &signal_args, CommandReturnObject &result) override
- {
- TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
-
- if (!target_sp)
- {
- result.AppendError ("No current target;"
- " cannot handle signals until you have a valid target and process.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- ProcessSP process_sp = target_sp->GetProcessSP();
-
- if (!process_sp)
- {
- result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &signal_args, CommandReturnObject &result) override {
+ TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
+
+ if (!target_sp) {
+ result.AppendError("No current target;"
+ " cannot handle signals until you have a valid target "
+ "and process.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- int stop_action = -1; // -1 means leave the current setting alone
- int pass_action = -1; // -1 means leave the current setting alone
- int notify_action = -1; // -1 means leave the current setting alone
+ ProcessSP process_sp = target_sp->GetProcessSP();
- if (! m_options.stop.empty()
- && ! VerifyCommandOptionValue (m_options.stop, stop_action))
- {
- result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (!process_sp) {
+ result.AppendError("No current process; cannot handle signals until you "
+ "have a valid process.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (! m_options.notify.empty()
- && ! VerifyCommandOptionValue (m_options.notify, notify_action))
- {
- result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ int stop_action = -1; // -1 means leave the current setting alone
+ int pass_action = -1; // -1 means leave the current setting alone
+ int notify_action = -1; // -1 means leave the current setting alone
- if (! m_options.pass.empty()
- && ! VerifyCommandOptionValue (m_options.pass, pass_action))
- {
- result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (!m_options.stop.empty() &&
+ !VerifyCommandOptionValue(m_options.stop, stop_action)) {
+ result.AppendError("Invalid argument for command option --stop; must be "
+ "true or false.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- size_t num_args = signal_args.GetArgumentCount();
- UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
- int num_signals_set = 0;
-
- if (num_args > 0)
- {
- for (size_t i = 0; i < num_args; ++i)
- {
- int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i));
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- {
- // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees
- // the value is either 0 or 1.
- if (stop_action != -1)
- signals_sp->SetShouldStop(signo, stop_action);
- if (pass_action != -1)
- {
- bool suppress = !pass_action;
- signals_sp->SetShouldSuppress(signo, suppress);
- }
- if (notify_action != -1)
- signals_sp->SetShouldNotify(signo, notify_action);
- ++num_signals_set;
- }
- else
- {
- result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
- }
- }
- }
- else
- {
- // No signal specified, if any command options were specified, update ALL signals.
- if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1))
- {
- if (m_interpreter.Confirm ("Do you really want to update all the signals?", false))
- {
- int32_t signo = signals_sp->GetFirstSignalNumber();
- while (signo != LLDB_INVALID_SIGNAL_NUMBER)
- {
- if (notify_action != -1)
- signals_sp->SetShouldNotify(signo, notify_action);
- if (stop_action != -1)
- signals_sp->SetShouldStop(signo, stop_action);
- if (pass_action != -1)
- {
- bool suppress = !pass_action;
- signals_sp->SetShouldSuppress(signo, suppress);
- }
- signo = signals_sp->GetNextSignalNumber(signo);
- }
- }
+ if (!m_options.notify.empty() &&
+ !VerifyCommandOptionValue(m_options.notify, notify_action)) {
+ result.AppendError("Invalid argument for command option --notify; must "
+ "be true or false.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (!m_options.pass.empty() &&
+ !VerifyCommandOptionValue(m_options.pass, pass_action)) {
+ result.AppendError("Invalid argument for command option --pass; must be "
+ "true or false.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ size_t num_args = signal_args.GetArgumentCount();
+ UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
+ int num_signals_set = 0;
+
+ if (num_args > 0) {
+ for (const auto &arg : signal_args) {
+ int32_t signo = signals_sp->GetSignalNumberFromName(arg.c_str());
+ if (signo != LLDB_INVALID_SIGNAL_NUMBER) {
+ // Casting the actions as bools here should be okay, because
+ // VerifyCommandOptionValue guarantees
+ // the value is either 0 or 1.
+ if (stop_action != -1)
+ signals_sp->SetShouldStop(signo, stop_action);
+ if (pass_action != -1) {
+ bool suppress = !pass_action;
+ signals_sp->SetShouldSuppress(signo, suppress);
+ }
+ if (notify_action != -1)
+ signals_sp->SetShouldNotify(signo, notify_action);
+ ++num_signals_set;
+ } else {
+ result.AppendErrorWithFormat("Invalid signal name '%s'\n",
+ arg.c_str());
+ }
+ }
+ } else {
+ // No signal specified, if any command options were specified, update ALL
+ // signals.
+ if ((notify_action != -1) || (stop_action != -1) || (pass_action != -1)) {
+ if (m_interpreter.Confirm(
+ "Do you really want to update all the signals?", false)) {
+ int32_t signo = signals_sp->GetFirstSignalNumber();
+ while (signo != LLDB_INVALID_SIGNAL_NUMBER) {
+ if (notify_action != -1)
+ signals_sp->SetShouldNotify(signo, notify_action);
+ if (stop_action != -1)
+ signals_sp->SetShouldStop(signo, stop_action);
+ if (pass_action != -1) {
+ bool suppress = !pass_action;
+ signals_sp->SetShouldSuppress(signo, suppress);
}
+ signo = signals_sp->GetNextSignalNumber(signo);
+ }
}
+ }
+ }
- PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp);
-
- if (num_signals_set > 0)
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- else
- result.SetStatus (eReturnStatusFailed);
+ PrintSignalInformation(result.GetOutputStream(), signal_args,
+ num_signals_set, signals_sp);
- return result.Succeeded();
- }
+ if (num_signals_set > 0)
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
- CommandOptions m_options;
-};
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectProcessHandle::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
-{ LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
-{ LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectMultiwordProcess
//-------------------------------------------------------------------------
-CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "process", "Commands for interacting with processes on the current platform.",
- "process <subcommand> [<subcommand-options>]")
-{
- LoadSubCommand ("attach", CommandObjectSP (new CommandObjectProcessAttach (interpreter)));
- LoadSubCommand ("launch", CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
- LoadSubCommand ("continue", CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
- LoadSubCommand ("connect", CommandObjectSP (new CommandObjectProcessConnect (interpreter)));
- LoadSubCommand ("detach", CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
- LoadSubCommand ("load", CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
- LoadSubCommand ("unload", CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
- LoadSubCommand ("signal", CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
- LoadSubCommand ("handle", CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
- LoadSubCommand ("status", CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
- LoadSubCommand ("interrupt", CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
- LoadSubCommand ("kill", CommandObjectSP (new CommandObjectProcessKill (interpreter)));
- LoadSubCommand ("plugin", CommandObjectSP (new CommandObjectProcessPlugin (interpreter)));
- LoadSubCommand ("save-core", CommandObjectSP (new CommandObjectProcessSaveCore (interpreter)));
+CommandObjectMultiwordProcess::CommandObjectMultiwordProcess(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "process",
+ "Commands for interacting with processes on the current platform.",
+ "process <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("attach",
+ CommandObjectSP(new CommandObjectProcessAttach(interpreter)));
+ LoadSubCommand("launch",
+ CommandObjectSP(new CommandObjectProcessLaunch(interpreter)));
+ LoadSubCommand("continue", CommandObjectSP(new CommandObjectProcessContinue(
+ interpreter)));
+ LoadSubCommand("connect",
+ CommandObjectSP(new CommandObjectProcessConnect(interpreter)));
+ LoadSubCommand("detach",
+ CommandObjectSP(new CommandObjectProcessDetach(interpreter)));
+ LoadSubCommand("load",
+ CommandObjectSP(new CommandObjectProcessLoad(interpreter)));
+ LoadSubCommand("unload",
+ CommandObjectSP(new CommandObjectProcessUnload(interpreter)));
+ LoadSubCommand("signal",
+ CommandObjectSP(new CommandObjectProcessSignal(interpreter)));
+ LoadSubCommand("handle",
+ CommandObjectSP(new CommandObjectProcessHandle(interpreter)));
+ LoadSubCommand("status",
+ CommandObjectSP(new CommandObjectProcessStatus(interpreter)));
+ LoadSubCommand("interrupt", CommandObjectSP(new CommandObjectProcessInterrupt(
+ interpreter)));
+ LoadSubCommand("kill",
+ CommandObjectSP(new CommandObjectProcessKill(interpreter)));
+ LoadSubCommand("plugin",
+ CommandObjectSP(new CommandObjectProcessPlugin(interpreter)));
+ LoadSubCommand("save-core", CommandObjectSP(new CommandObjectProcessSaveCore(
+ interpreter)));
}
CommandObjectMultiwordProcess::~CommandObjectMultiwordProcess() = default;
diff --git a/source/Commands/CommandObjectProcess.h b/source/Commands/CommandObjectProcess.h
index 804c34261bad..0f520f63e1dd 100644
--- a/source/Commands/CommandObjectProcess.h
+++ b/source/Commands/CommandObjectProcess.h
@@ -22,12 +22,11 @@ namespace lldb_private {
// CommandObjectMultiwordProcess
//-------------------------------------------------------------------------
-class CommandObjectMultiwordProcess : public CommandObjectMultiword
-{
+class CommandObjectMultiwordProcess : public CommandObjectMultiword {
public:
- CommandObjectMultiwordProcess (CommandInterpreter &interpreter);
+ CommandObjectMultiwordProcess(CommandInterpreter &interpreter);
- ~CommandObjectMultiwordProcess() override;
+ ~CommandObjectMultiwordProcess() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectQuit.cpp b/source/Commands/CommandObjectQuit.cpp
index a650398724fe..be55dab61683 100644
--- a/source/Commands/CommandObjectQuit.cpp
+++ b/source/Commands/CommandObjectQuit.cpp
@@ -25,75 +25,62 @@ using namespace lldb_private;
//-------------------------------------------------------------------------
CommandObjectQuit::CommandObjectQuit(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "quit", "Quit the LLDB debugger.", "quit")
-{
-}
+ : CommandObjectParsed(interpreter, "quit", "Quit the LLDB debugger.",
+ "quit") {}
-CommandObjectQuit::~CommandObjectQuit ()
-{
-}
+CommandObjectQuit::~CommandObjectQuit() {}
// returns true if there is at least one alive process
-// is_a_detach will be true if all alive processes will be detached when you quit
+// is_a_detach will be true if all alive processes will be detached when you
+// quit
// and false if at least one process will be killed instead
-bool
-CommandObjectQuit::ShouldAskForConfirmation (bool& is_a_detach)
-{
- if (m_interpreter.GetPromptOnQuit() == false)
- return false;
- bool should_prompt = false;
- is_a_detach = true;
- for (uint32_t debugger_idx = 0;
- debugger_idx < Debugger::GetNumDebuggers();
- debugger_idx++)
- {
- DebuggerSP debugger_sp(Debugger::GetDebuggerAtIndex(debugger_idx));
- if (!debugger_sp)
- continue;
- const TargetList& target_list(debugger_sp->GetTargetList());
- for (uint32_t target_idx = 0;
- target_idx < static_cast<uint32_t>(target_list.GetNumTargets());
- target_idx++)
- {
- TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
- if (!target_sp)
- continue;
- ProcessSP process_sp(target_sp->GetProcessSP());
- if (process_sp
- && process_sp->IsValid()
- && process_sp->IsAlive()
- && process_sp->WarnBeforeDetach())
- {
- should_prompt = true;
- if (process_sp->GetShouldDetach() == false)
- {
- // if we need to kill at least one process, just say so and return
- is_a_detach = false;
- return should_prompt;
- }
- }
+bool CommandObjectQuit::ShouldAskForConfirmation(bool &is_a_detach) {
+ if (m_interpreter.GetPromptOnQuit() == false)
+ return false;
+ bool should_prompt = false;
+ is_a_detach = true;
+ for (uint32_t debugger_idx = 0; debugger_idx < Debugger::GetNumDebuggers();
+ debugger_idx++) {
+ DebuggerSP debugger_sp(Debugger::GetDebuggerAtIndex(debugger_idx));
+ if (!debugger_sp)
+ continue;
+ const TargetList &target_list(debugger_sp->GetTargetList());
+ for (uint32_t target_idx = 0;
+ target_idx < static_cast<uint32_t>(target_list.GetNumTargets());
+ target_idx++) {
+ TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
+ if (!target_sp)
+ continue;
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ if (process_sp && process_sp->IsValid() && process_sp->IsAlive() &&
+ process_sp->WarnBeforeDetach()) {
+ should_prompt = true;
+ if (process_sp->GetShouldDetach() == false) {
+ // if we need to kill at least one process, just say so and return
+ is_a_detach = false;
+ return should_prompt;
}
+ }
}
- return should_prompt;
+ }
+ return should_prompt;
}
-bool
-CommandObjectQuit::DoExecute (Args& command, CommandReturnObject &result)
-{
- bool is_a_detach = true;
- if (ShouldAskForConfirmation (is_a_detach))
- {
- StreamString message;
- message.Printf("Quitting LLDB will %s one or more processes. Do you really want to proceed", (is_a_detach ? "detach from" : "kill"));
- if (!m_interpreter.Confirm(message.GetData(), true))
- {
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) {
+ bool is_a_detach = true;
+ if (ShouldAskForConfirmation(is_a_detach)) {
+ StreamString message;
+ message.Printf("Quitting LLDB will %s one or more processes. Do you really "
+ "want to proceed",
+ (is_a_detach ? "detach from" : "kill"));
+ if (!m_interpreter.Confirm(message.GetString(), true)) {
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- const uint32_t event_type = CommandInterpreter::eBroadcastBitQuitCommandReceived;
- m_interpreter.BroadcastEvent (event_type);
- result.SetStatus (eReturnStatusQuit);
- return true;
+ }
+ const uint32_t event_type =
+ CommandInterpreter::eBroadcastBitQuitCommandReceived;
+ m_interpreter.BroadcastEvent(event_type);
+ result.SetStatus(eReturnStatusQuit);
+ return true;
}
-
diff --git a/source/Commands/CommandObjectQuit.h b/source/Commands/CommandObjectQuit.h
index df9216b7e7e3..f2998f8690fb 100644
--- a/source/Commands/CommandObjectQuit.h
+++ b/source/Commands/CommandObjectQuit.h
@@ -22,21 +22,16 @@ namespace lldb_private {
// CommandObjectQuit
//-------------------------------------------------------------------------
-class CommandObjectQuit : public CommandObjectParsed
-{
+class CommandObjectQuit : public CommandObjectParsed {
public:
+ CommandObjectQuit(CommandInterpreter &interpreter);
- CommandObjectQuit (CommandInterpreter &interpreter);
-
- ~CommandObjectQuit() override;
+ ~CommandObjectQuit() override;
protected:
- bool
- DoExecute(Args& args,
- CommandReturnObject &result) override;
-
- bool
- ShouldAskForConfirmation (bool& is_a_detach);
+ bool DoExecute(Args &args, CommandReturnObject &result) override;
+
+ bool ShouldAskForConfirmation(bool &is_a_detach);
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp
index ff8df2a6acaa..0ba6526d347d 100644
--- a/source/Commands/CommandObjectRegister.cpp
+++ b/source/Commands/CommandObjectRegister.cpp
@@ -15,17 +15,17 @@
// Project includes
#include "CommandObjectRegister.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
-#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -38,430 +38,363 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// "register read"
//----------------------------------------------------------------------
-class CommandObjectRegisterRead : public CommandObjectParsed
-{
-public:
- CommandObjectRegisterRead (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "register read",
- "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.",
- nullptr,
- eCommandRequiresFrame |
- eCommandRequiresRegContext |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_option_group (interpreter),
- m_format_options (eFormatDefault),
- m_command_options ()
- {
- CommandArgumentEntry arg;
- CommandArgumentData register_arg;
-
- // Define the first (and only) variant of this arg.
- register_arg.arg_type = eArgTypeRegisterName;
- register_arg.arg_repetition = eArgRepeatStar;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (register_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
-
- // Add the "--format"
- m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_ALL);
- m_option_group.Append (&m_command_options);
- m_option_group.Finalize();
- }
-
- ~CommandObjectRegisterRead() override = default;
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
+static OptionDefinition g_register_read_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display register names using the alternate register name if there is one." },
+ { LLDB_OPT_SET_1, false, "set", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex, "Specify which register sets to dump by index." },
+ { LLDB_OPT_SET_2, false, "all", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show all register sets." },
+ // clang-format on
+};
- bool
- DumpRegister (const ExecutionContext &exe_ctx,
- Stream &strm,
- RegisterContext *reg_ctx,
- const RegisterInfo *reg_info)
- {
- if (reg_info)
- {
- RegisterValue reg_value;
-
- if (reg_ctx->ReadRegister (reg_info, reg_value))
- {
- strm.Indent ();
-
- bool prefix_with_altname = (bool)m_command_options.alternate_name;
- bool prefix_with_name = !prefix_with_altname;
- reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat(), 8);
- if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint))
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process && reg_info->byte_size == process->GetAddressByteSize())
- {
- addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
- if (reg_addr != LLDB_INVALID_ADDRESS)
- {
- Address so_reg_addr;
- if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
- {
- strm.PutCString (" ");
- so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
- }
- }
- }
- }
- strm.EOL();
- return true;
+class CommandObjectRegisterRead : public CommandObjectParsed {
+public:
+ CommandObjectRegisterRead(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "register read",
+ "Dump the contents of one or more register values from the current "
+ "frame. If no register is specified, dumps them all.",
+ nullptr,
+ eCommandRequiresFrame | eCommandRequiresRegContext |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_option_group(), m_format_options(eFormatDefault),
+ m_command_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData register_arg;
+
+ // Define the first (and only) variant of this arg.
+ register_arg.arg_type = eArgTypeRegisterName;
+ register_arg.arg_repetition = eArgRepeatStar;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(register_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+
+ // Add the "--format"
+ m_option_group.Append(&m_format_options,
+ OptionGroupFormat::OPTION_GROUP_FORMAT |
+ OptionGroupFormat::OPTION_GROUP_GDB_FMT,
+ LLDB_OPT_SET_ALL);
+ m_option_group.Append(&m_command_options);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectRegisterRead() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+ bool DumpRegister(const ExecutionContext &exe_ctx, Stream &strm,
+ RegisterContext *reg_ctx, const RegisterInfo *reg_info) {
+ if (reg_info) {
+ RegisterValue reg_value;
+
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ strm.Indent();
+
+ bool prefix_with_altname = (bool)m_command_options.alternate_name;
+ bool prefix_with_name = !prefix_with_altname;
+ reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname,
+ m_format_options.GetFormat(), 8);
+ if ((reg_info->encoding == eEncodingUint) ||
+ (reg_info->encoding == eEncodingSint)) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && reg_info->byte_size == process->GetAddressByteSize()) {
+ addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
+ if (reg_addr != LLDB_INVALID_ADDRESS) {
+ Address so_reg_addr;
+ if (exe_ctx.GetTargetRef()
+ .GetSectionLoadList()
+ .ResolveLoadAddress(reg_addr, so_reg_addr)) {
+ strm.PutCString(" ");
+ so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(),
+ Address::DumpStyleResolvedDescription);
+ }
}
+ }
}
- return false;
+ strm.EOL();
+ return true;
+ }
}
-
- bool
- DumpRegisterSet (const ExecutionContext &exe_ctx,
- Stream &strm,
- RegisterContext *reg_ctx,
- size_t set_idx,
- bool primitive_only=false)
- {
- uint32_t unavailable_count = 0;
- uint32_t available_count = 0;
-
- if (!reg_ctx)
- return false; // thread has no registers (i.e. core files are corrupt, incomplete crash logs...)
-
- const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
- if (reg_set)
- {
- strm.Printf ("%s:\n", (reg_set->name ? reg_set->name : "unknown") );
- strm.IndentMore ();
- const size_t num_registers = reg_set->num_registers;
- for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
- {
- const uint32_t reg = reg_set->registers[reg_idx];
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg);
- // Skip the dumping of derived register if primitive_only is true.
- if (primitive_only && reg_info && reg_info->value_regs)
- continue;
-
- if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
- ++available_count;
- else
- ++unavailable_count;
- }
- strm.IndentLess ();
- if (unavailable_count)
- {
- strm.Indent ();
- strm.Printf("%u registers were unavailable.\n", unavailable_count);
- }
- strm.EOL();
- }
- return available_count > 0;
+ return false;
+ }
+
+ bool DumpRegisterSet(const ExecutionContext &exe_ctx, Stream &strm,
+ RegisterContext *reg_ctx, size_t set_idx,
+ bool primitive_only = false) {
+ uint32_t unavailable_count = 0;
+ uint32_t available_count = 0;
+
+ if (!reg_ctx)
+ return false; // thread has no registers (i.e. core files are corrupt,
+ // incomplete crash logs...)
+
+ const RegisterSet *const reg_set = reg_ctx->GetRegisterSet(set_idx);
+ if (reg_set) {
+ strm.Printf("%s:\n", (reg_set->name ? reg_set->name : "unknown"));
+ strm.IndentMore();
+ const size_t num_registers = reg_set->num_registers;
+ for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) {
+ const uint32_t reg = reg_set->registers[reg_idx];
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg);
+ // Skip the dumping of derived register if primitive_only is true.
+ if (primitive_only && reg_info && reg_info->value_regs)
+ continue;
+
+ if (DumpRegister(exe_ctx, strm, reg_ctx, reg_info))
+ ++available_count;
+ else
+ ++unavailable_count;
+ }
+ strm.IndentLess();
+ if (unavailable_count) {
+ strm.Indent();
+ strm.Printf("%u registers were unavailable.\n", unavailable_count);
+ }
+ strm.EOL();
}
+ return available_count > 0;
+ }
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Stream &strm = result.GetOutputStream();
- RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
-
- const RegisterInfo *reg_info = nullptr;
- if (command.GetArgumentCount() == 0)
- {
- size_t set_idx;
-
- size_t num_register_sets = 1;
- const size_t set_array_size = m_command_options.set_indexes.GetSize();
- if (set_array_size > 0)
- {
- for (size_t i = 0; i < set_array_size; ++i)
- {
- set_idx = m_command_options.set_indexes[i]->GetUInt64Value(UINT32_MAX, nullptr);
- if (set_idx < reg_ctx->GetRegisterSetCount())
- {
- if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx))
- {
- if (errno)
- result.AppendErrorWithFormat ("register read failed: %s\n", strerror(errno));
- else
- result.AppendError ("unknown error while reading registers.\n");
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- }
- else
- {
- result.AppendErrorWithFormat("invalid register set index: %" PRIu64 "\n", (uint64_t)set_idx);
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- }
- }
- else
- {
- if (m_command_options.dump_all_sets)
- num_register_sets = reg_ctx->GetRegisterSetCount();
-
- for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
- {
- // When dump_all_sets option is set, dump primitive as well as derived registers.
- DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue());
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Stream &strm = result.GetOutputStream();
+ RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
+
+ const RegisterInfo *reg_info = nullptr;
+ if (command.GetArgumentCount() == 0) {
+ size_t set_idx;
+
+ size_t num_register_sets = 1;
+ const size_t set_array_size = m_command_options.set_indexes.GetSize();
+ if (set_array_size > 0) {
+ for (size_t i = 0; i < set_array_size; ++i) {
+ set_idx = m_command_options.set_indexes[i]->GetUInt64Value(UINT32_MAX,
+ nullptr);
+ if (set_idx < reg_ctx->GetRegisterSetCount()) {
+ if (!DumpRegisterSet(m_exe_ctx, strm, reg_ctx, set_idx)) {
+ if (errno)
+ result.AppendErrorWithFormat("register read failed: %s\n",
+ strerror(errno));
+ else
+ result.AppendError("unknown error while reading registers.\n");
+ result.SetStatus(eReturnStatusFailed);
+ break;
}
+ } else {
+ result.AppendErrorWithFormat(
+ "invalid register set index: %" PRIu64 "\n", (uint64_t)set_idx);
+ result.SetStatus(eReturnStatusFailed);
+ break;
+ }
}
- else
- {
- if (m_command_options.dump_all_sets)
- {
- result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n");
- result.SetStatus (eReturnStatusFailed);
- }
- else if (m_command_options.set_indexes.GetSize() > 0)
- {
- result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n");
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
- {
- // in most LLDB commands we accept $rbx as the name for register RBX - and here we would
- // reject it and non-existant. we should be more consistent towards the user and allow them
- // to say reg read $rbx - internally, however, we should be strict and not allow ourselves
- // to call our registers $rbx in our own API
- if (*arg_cstr == '$')
- arg_cstr = arg_cstr+1;
- reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
-
- if (reg_info)
- {
- if (!DumpRegister (m_exe_ctx, strm, reg_ctx, reg_info))
- strm.Printf("%-12s = error: unavailable\n", reg_info->name);
- }
- else
- {
- result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
- }
- }
- }
+ } else {
+ if (m_command_options.dump_all_sets)
+ num_register_sets = reg_ctx->GetRegisterSetCount();
+
+ for (set_idx = 0; set_idx < num_register_sets; ++set_idx) {
+ // When dump_all_sets option is set, dump primitive as well as derived
+ // registers.
+ DumpRegisterSet(m_exe_ctx, strm, reg_ctx, set_idx,
+ !m_command_options.dump_all_sets.GetCurrentValue());
+ }
+ }
+ } else {
+ if (m_command_options.dump_all_sets) {
+ result.AppendError("the --all option can't be used when registers "
+ "names are supplied as arguments\n");
+ result.SetStatus(eReturnStatusFailed);
+ } else if (m_command_options.set_indexes.GetSize() > 0) {
+ result.AppendError("the --set <set> option can't be used when "
+ "registers names are supplied as arguments\n");
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ for (auto &entry : command) {
+ // in most LLDB commands we accept $rbx as the name for register RBX -
+ // and here we would reject it and non-existant. we should be more
+ // consistent towards the user and allow them to say reg read $rbx -
+ // internally, however, we should be strict and not allow ourselves
+ // to call our registers $rbx in our own API
+ auto arg_str = entry.ref;
+ arg_str.consume_front("$");
+
+ reg_info = reg_ctx->GetRegisterInfoByName(arg_str);
+
+ if (reg_info) {
+ if (!DumpRegister(m_exe_ctx, strm, reg_ctx, reg_info))
+ strm.Printf("%-12s = error: unavailable\n", reg_info->name);
+ } else {
+ result.AppendErrorWithFormat("Invalid register name '%s'.\n",
+ arg_str.str().c_str());
+ }
}
- return result.Succeeded();
+ }
}
+ return result.Succeeded();
+ }
- class CommandOptions : public OptionGroup
- {
- public:
- CommandOptions () :
- OptionGroup(),
- set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)),
- dump_all_sets (false, false), // Initial and default values are false
- alternate_name (false, false)
- {
- }
+ class CommandOptions : public OptionGroup {
+ public:
+ CommandOptions()
+ : OptionGroup(),
+ set_indexes(OptionValue::ConvertTypeToMask(OptionValue::eTypeUInt64)),
+ dump_all_sets(false, false), // Initial and default values are false
+ alternate_name(false, false) {}
- ~CommandOptions() override = default;
+ ~CommandOptions() override = default;
- uint32_t
- GetNumDefinitions () override;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_register_read_options);
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- void
- OptionParsingStarting (CommandInterpreter &interpreter) override
- {
- set_indexes.Clear();
- dump_all_sets.Clear();
- alternate_name.Clear();
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ set_indexes.Clear();
+ dump_all_sets.Clear();
+ alternate_name.Clear();
+ }
- Error
- SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_value) override
- {
- Error error;
- const int short_option = g_option_table[option_idx].short_option;
- switch (short_option)
- {
- case 's':
- {
- OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error));
- if (value_sp)
- set_indexes.AppendValue (value_sp);
- }
- break;
-
- case 'a':
- // When we don't use OptionValue::SetValueFromCString(const char *) to
- // set an option value, it won't be marked as being set in the options
- // so we make a call to let users know the value was set via option
- dump_all_sets.SetCurrentValue (true);
- dump_all_sets.SetOptionWasSet ();
- break;
-
- case 'A':
- // When we don't use OptionValue::SetValueFromCString(const char *) to
- // set an option value, it won't be marked as being set in the options
- // so we make a call to let users know the value was set via option
- alternate_name.SetCurrentValue (true);
- dump_all_sets.SetOptionWasSet ();
- break;
-
- default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
- break;
- }
- return error;
- }
-
- // Options table: Required for subclasses of Options.
-
- static const OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
- OptionValueArray set_indexes;
- OptionValueBoolean dump_all_sets;
- OptionValueBoolean alternate_name;
- };
-
- OptionGroupOptions m_option_group;
- OptionGroupFormat m_format_options;
- CommandOptions m_command_options;
-};
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = GetDefinitions()[option_idx].short_option;
+ switch (short_option) {
+ case 's': {
+ OptionValueSP value_sp(OptionValueUInt64::Create(option_value, error));
+ if (value_sp)
+ set_indexes.AppendValue(value_sp);
+ } break;
+
+ case 'a':
+ // When we don't use OptionValue::SetValueFromCString(const char *) to
+ // set an option value, it won't be marked as being set in the options
+ // so we make a call to let users know the value was set via option
+ dump_all_sets.SetCurrentValue(true);
+ dump_all_sets.SetOptionWasSet();
+ break;
+
+ case 'A':
+ // When we don't use OptionValue::SetValueFromCString(const char *) to
+ // set an option value, it won't be marked as being set in the options
+ // so we make a call to let users know the value was set via option
+ alternate_name.SetCurrentValue(true);
+ dump_all_sets.SetOptionWasSet();
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'",
+ short_option);
+ break;
+ }
+ return error;
+ }
-const OptionDefinition
-CommandObjectRegisterRead::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone , "Display register names using the alternate register name if there is one."},
- { LLDB_OPT_SET_1 , false, "set" , 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex , "Specify which register sets to dump by index."},
- { LLDB_OPT_SET_2 , false, "all" , 'a', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone , "Show all register sets."},
-};
+ // Instance variables to hold the values for command options.
+ OptionValueArray set_indexes;
+ OptionValueBoolean dump_all_sets;
+ OptionValueBoolean alternate_name;
+ };
-uint32_t
-CommandObjectRegisterRead::CommandOptions::GetNumDefinitions ()
-{
- return llvm::array_lengthof(g_option_table);
-}
+ OptionGroupOptions m_option_group;
+ OptionGroupFormat m_format_options;
+ CommandOptions m_command_options;
+};
//----------------------------------------------------------------------
// "register write"
//----------------------------------------------------------------------
-class CommandObjectRegisterWrite : public CommandObjectParsed
-{
+class CommandObjectRegisterWrite : public CommandObjectParsed {
public:
- CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "register write",
- "Modify a single register value.",
- nullptr,
- eCommandRequiresFrame |
- eCommandRequiresRegContext |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused)
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentData register_arg;
- CommandArgumentData value_arg;
-
- // Define the first (and only) variant of this arg.
- register_arg.arg_type = eArgTypeRegisterName;
- register_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (register_arg);
-
- // Define the first (and only) variant of this arg.
- value_arg.arg_type = eArgTypeValue;
- value_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg2.push_back (value_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
- }
-
- ~CommandObjectRegisterWrite() override = default;
+ CommandObjectRegisterWrite(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "register write",
+ "Modify a single register value.", nullptr,
+ eCommandRequiresFrame | eCommandRequiresRegContext |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused) {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData register_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ register_arg.arg_type = eArgTypeRegisterName;
+ register_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(register_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ }
+
+ ~CommandObjectRegisterWrite() override = default;
protected:
- bool
- DoExecute(Args& command, CommandReturnObject &result) override
- {
- DataExtractor reg_data;
- RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
-
- if (command.GetArgumentCount() != 2)
- {
- result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
- result.SetStatus (eReturnStatusFailed);
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ DataExtractor reg_data;
+ RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
+
+ if (command.GetArgumentCount() != 2) {
+ result.AppendError(
+ "register write takes exactly 2 arguments: <reg-name> <value>");
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ auto reg_name = command[0].ref;
+ auto value_str = command[1].ref;
+
+ // in most LLDB commands we accept $rbx as the name for register RBX - and
+ // here we would reject it and non-existant. we should be more consistent
+ // towards the user and allow them to say reg write $rbx - internally,
+ // however, we should be strict and not allow ourselves to call our
+ // registers $rbx in our own API
+ reg_name.consume_front("$");
+
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
+
+ if (reg_info) {
+ RegisterValue reg_value;
+
+ Error error(reg_value.SetValueFromString(reg_info, value_str));
+ if (error.Success()) {
+ if (reg_ctx->WriteRegister(reg_info, reg_value)) {
+ // Toss all frames and anything else in the thread
+ // after a register has been written.
+ m_exe_ctx.GetThreadRef().Flush();
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
+ }
}
- else
- {
- const char *reg_name = command.GetArgumentAtIndex(0);
- const char *value_str = command.GetArgumentAtIndex(1);
-
- // in most LLDB commands we accept $rbx as the name for register RBX - and here we would
- // reject it and non-existant. we should be more consistent towards the user and allow them
- // to say reg write $rbx - internally, however, we should be strict and not allow ourselves
- // to call our registers $rbx in our own API
- if (reg_name && *reg_name == '$')
- reg_name = reg_name+1;
-
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
-
- if (reg_info)
- {
- RegisterValue reg_value;
-
- Error error (reg_value.SetValueFromCString (reg_info, value_str));
- if (error.Success())
- {
- if (reg_ctx->WriteRegister (reg_info, reg_value))
- {
- // Toss all frames and anything else in the thread
- // after a register has been written.
- m_exe_ctx.GetThreadRef().Flush();
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- return true;
- }
- }
- if (error.AsCString())
- {
- result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
- reg_name,
- value_str,
- error.AsCString());
- }
- else
- {
- result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'",
- reg_name,
- value_str);
- }
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
- result.SetStatus (eReturnStatusFailed);
- }
+ if (error.AsCString()) {
+ result.AppendErrorWithFormat(
+ "Failed to write register '%s' with value '%s': %s\n",
+ reg_name.str().c_str(), value_str.str().c_str(),
+ error.AsCString());
+ } else {
+ result.AppendErrorWithFormat(
+ "Failed to write register '%s' with value '%s'",
+ reg_name.str().c_str(), value_str.str().c_str());
}
- return result.Succeeded();
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ result.AppendErrorWithFormat("Register not found for '%s'.\n",
+ reg_name.str().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ }
}
+ return result.Succeeded();
+ }
};
//----------------------------------------------------------------------
@@ -469,11 +402,13 @@ protected:
//----------------------------------------------------------------------
CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter)
: CommandObjectMultiword(interpreter, "register",
- "Commands to access registers for the current thread and stack frame.",
- "register [read|write] ...")
-{
- LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
- LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
+ "Commands to access registers for the current "
+ "thread and stack frame.",
+ "register [read|write] ...") {
+ LoadSubCommand("read",
+ CommandObjectSP(new CommandObjectRegisterRead(interpreter)));
+ LoadSubCommand("write",
+ CommandObjectSP(new CommandObjectRegisterWrite(interpreter)));
}
CommandObjectRegister::~CommandObjectRegister() = default;
diff --git a/source/Commands/CommandObjectRegister.h b/source/Commands/CommandObjectRegister.h
index e7b6974bc998..81f2f6bae223 100644
--- a/source/Commands/CommandObjectRegister.h
+++ b/source/Commands/CommandObjectRegister.h
@@ -22,21 +22,20 @@ namespace lldb_private {
// CommandObjectRegister
//-------------------------------------------------------------------------
-class CommandObjectRegister : public CommandObjectMultiword
-{
+class CommandObjectRegister : public CommandObjectMultiword {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectRegister(CommandInterpreter &interpreter);
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectRegister(CommandInterpreter &interpreter);
- ~CommandObjectRegister() override;
+ ~CommandObjectRegister() override;
private:
- //------------------------------------------------------------------
- // For CommandObjectRegister only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (CommandObjectRegister);
+ //------------------------------------------------------------------
+ // For CommandObjectRegister only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(CommandObjectRegister);
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp
index b76af2075255..23fdcb9e895c 100644
--- a/source/Commands/CommandObjectSettings.cpp
+++ b/source/Commands/CommandObjectSettings.cpp
@@ -15,9 +15,9 @@
#include "llvm/ADT/StringRef.h"
// Project includes
+#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/OptionValueProperties.h"
using namespace lldb;
@@ -27,39 +27,47 @@ using namespace lldb_private;
// CommandObjectSettingsSet
//-------------------------------------------------------------------------
-class CommandObjectSettingsSet : public CommandObjectRaw
-{
+static OptionDefinition g_settings_set_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Apply the new value to the global default value." }
+ // clang-format on
+};
+
+class CommandObjectSettingsSet : public CommandObjectRaw {
public:
- CommandObjectSettingsSet(CommandInterpreter &interpreter)
- : CommandObjectRaw(interpreter, "settings set", "Set the value of the specified debugger setting.", nullptr),
- m_options(interpreter)
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentData var_name_arg;
- CommandArgumentData value_arg;
-
- // Define the first (and only) variant of this arg.
- var_name_arg.arg_type = eArgTypeSettingVariableName;
- var_name_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (var_name_arg);
-
- // Define the first (and only) variant of this arg.
- value_arg.arg_type = eArgTypeValue;
- value_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg2.push_back (value_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
-
- SetHelpLong (
-"\nWhen setting a dictionary or array variable, you can set multiple entries \
-at once by giving the values to the set command. For example:" R"(
+ CommandObjectSettingsSet(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings set",
+ "Set the value of the specified debugger setting."),
+ m_options() {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+
+ SetHelpLong(
+ "\nWhen setting a dictionary or array variable, you can set multiple entries \
+at once by giving the values to the set command. For example:"
+ R"(
(lldb) settings set target.run-args value1 value2 value3
(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
@@ -72,1106 +80,972 @@ at once by giving the values to the set command. For example:" R"(
'MYPATH=~/.:/usr/bin'
'SOME_ENV_VAR=12345'
-)" "Warning: The 'set' command re-sets the entire array or dictionary. If you \
+)"
+ "Warning: The 'set' command re-sets the entire array or dictionary. If you \
just want to add, remove or update individual values (or add something to \
the end), use one of the other settings sub-commands: append, replace, \
-insert-before or insert-after."
- );
+insert-before or insert-after.");
+ }
- }
+ ~CommandObjectSettingsSet() override = default;
+
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
+
+ Options *GetOptions() override { return &m_options; }
- ~CommandObjectSettingsSet() override = default;
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_global(false) {}
- // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
- bool
- WantsCompletion() override { return true; }
+ ~CommandOptions() override = default;
- Options *
- GetOptions () override
- {
- return &m_options;
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'g':
+ m_global = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized options '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_global (false)
- {
- }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'g':
- m_global = true;
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized options '%c'", short_option);
- break;
- }
-
- return error;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_global = false;
+ }
- void
- OptionParsingStarting () override
- {
- m_global = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_settings_set_options);
+ }
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool m_global;
- };
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
-
- const size_t argc = input.GetArgumentCount();
- const char *arg = nullptr;
- int setting_var_idx;
- for (setting_var_idx = 1; setting_var_idx < static_cast<int>(argc);
- ++setting_var_idx)
- {
- arg = input.GetArgumentAtIndex(setting_var_idx);
- if (arg && arg[0] != '-')
- break; // We found our setting variable name index
- }
- if (cursor_index == setting_var_idx)
- {
- // Attempting to complete setting variable name
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- }
- else
- {
- arg = input.GetArgumentAtIndex(cursor_index);
-
- if (arg)
- {
- if (arg[0] == '-')
- {
- // Complete option name
- }
- else
- {
- // Complete setting value
- const char *setting_var_name = input.GetArgumentAtIndex(setting_var_idx);
- Error error;
- lldb::OptionValueSP value_sp (m_interpreter.GetDebugger().GetPropertyValue(&m_exe_ctx, setting_var_name, false, error));
- if (value_sp)
- {
- value_sp->AutoComplete (m_interpreter,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- word_complete,
- matches);
- }
- }
- }
+ // Instance variables to hold the values for command options.
+
+ bool m_global;
+ };
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index),
+ cursor_char_position);
+
+ const size_t argc = input.GetArgumentCount();
+ const char *arg = nullptr;
+ int setting_var_idx;
+ for (setting_var_idx = 1; setting_var_idx < static_cast<int>(argc);
+ ++setting_var_idx) {
+ arg = input.GetArgumentAtIndex(setting_var_idx);
+ if (arg && arg[0] != '-')
+ break; // We found our setting variable name index
+ }
+ if (cursor_index == setting_var_idx) {
+ // Attempting to complete setting variable name
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements,
+ nullptr, word_complete, matches);
+ } else {
+ arg = input.GetArgumentAtIndex(cursor_index);
+
+ if (arg) {
+ if (arg[0] == '-') {
+ // Complete option name
+ } else {
+ // Complete setting value
+ const char *setting_var_name =
+ input.GetArgumentAtIndex(setting_var_idx);
+ Error error;
+ lldb::OptionValueSP value_sp(
+ m_interpreter.GetDebugger().GetPropertyValue(
+ &m_exe_ctx, setting_var_name, false, error));
+ if (value_sp) {
+ value_sp->AutoComplete(m_interpreter, completion_str.c_str(),
+ match_start_point, max_return_elements,
+ word_complete, matches);
+ }
}
- return matches.GetSize();
+ }
}
-
+ return matches.GetSize();
+ }
+
protected:
- bool
- DoExecute (const char *command, CommandReturnObject &result) override
- {
- Args cmd_args(command);
-
- // Process possible options.
- if (!ParseOptions (cmd_args, result))
- return false;
-
- const size_t argc = cmd_args.GetArgumentCount ();
- if ((argc < 2) && (!m_options.m_global))
- {
- result.AppendError ("'settings set' takes more arguments");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(const char *command, CommandReturnObject &result) override {
+ Args cmd_args(command);
+
+ // Process possible options.
+ if (!ParseOptions(cmd_args, result))
+ return false;
+
+ const size_t argc = cmd_args.GetArgumentCount();
+ if ((argc < 2) && (!m_options.m_global)) {
+ result.AppendError("'settings set' takes more arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == nullptr) || (var_name[0] == '\0'))
- {
- result.AppendError ("'settings set' command requires a valid variable name");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError(
+ "'settings set' command requires a valid variable name");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- // Split the raw command into var_name and value pair.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr = Args::StripSpaces(var_value_string, true, false, false);
-
- Error error;
- if (m_options.m_global)
- {
- error = m_interpreter.GetDebugger().SetPropertyValue(nullptr,
- eVarSetOperationAssign,
- var_name,
- var_value_cstr);
- }
-
- if (error.Success())
- {
- // FIXME this is the same issue as the one in commands script import
- // we could be setting target.load-script-from-symbol-file which would cause
- // Python scripts to be loaded, which could run LLDB commands
- // (e.g. settings set target.process.python-os-plugin-path) and cause a crash
- // if we did not clear the command's exe_ctx first
- ExecutionContext exe_ctx(m_exe_ctx);
- m_exe_ctx.Clear();
- error = m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx,
- eVarSetOperationAssign,
- var_name,
- var_value_cstr);
- }
+ // Split the raw command into var_name and value pair.
+ llvm::StringRef raw_str(command);
+ std::string var_value_string = raw_str.split(var_name).second.str();
+ const char *var_value_cstr =
+ Args::StripSpaces(var_value_string, true, false, false);
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
+ Error error;
+ if (m_options.m_global) {
+ error = m_interpreter.GetDebugger().SetPropertyValue(
+ nullptr, eVarSetOperationAssign, var_name, var_value_cstr);
+ }
- return result.Succeeded();
+ if (error.Success()) {
+ // FIXME this is the same issue as the one in commands script import
+ // we could be setting target.load-script-from-symbol-file which would
+ // cause
+ // Python scripts to be loaded, which could run LLDB commands
+ // (e.g. settings set target.process.python-os-plugin-path) and cause a
+ // crash
+ // if we did not clear the command's exe_ctx first
+ ExecutionContext exe_ctx(m_exe_ctx);
+ m_exe_ctx.Clear();
+ error = m_interpreter.GetDebugger().SetPropertyValue(
+ &exe_ctx, eVarSetOperationAssign, var_name, var_value_cstr);
}
-private:
- CommandOptions m_options;
-};
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectSettingsSet::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Apply the new value to the global default value." },
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectSettingsShow -- Show current values
//-------------------------------------------------------------------------
-class CommandObjectSettingsShow : public CommandObjectParsed
-{
+class CommandObjectSettingsShow : public CommandObjectParsed {
public:
- CommandObjectSettingsShow(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "settings show",
- "Show matching debugger settings and their current values. Defaults to showing all settings.", nullptr)
- {
- CommandArgumentEntry arg1;
- CommandArgumentData var_name_arg;
-
- // Define the first (and only) variant of this arg.
- var_name_arg.arg_type = eArgTypeSettingVariableName;
- var_name_arg.arg_repetition = eArgRepeatOptional;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (var_name_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- }
-
- ~CommandObjectSettingsShow() override = default;
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
- }
+ CommandObjectSettingsShow(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "settings show",
+ "Show matching debugger settings and their current "
+ "values. Defaults to showing all settings.",
+ nullptr) {
+ CommandArgumentEntry arg1;
+ CommandArgumentData var_name_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectSettingsShow() override = default;
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index),
+ cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
-
- const size_t argc = args.GetArgumentCount ();
- if (argc > 0)
- {
- for (size_t i = 0; i < argc; ++i)
- {
- const char *property_path = args.GetArgumentAtIndex (i);
-
- Error error(m_interpreter.GetDebugger().DumpPropertyValue (&m_exe_ctx, result.GetOutputStream(), property_path, OptionValue::eDumpGroupValue));
- if (error.Success())
- {
- result.GetOutputStream().EOL();
- }
- else
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- }
- else
- {
- m_interpreter.GetDebugger().DumpAllPropertyValues (&m_exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue);
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ if (!args.empty()) {
+ for (const auto &arg : args) {
+ Error error(m_interpreter.GetDebugger().DumpPropertyValue(
+ &m_exe_ctx, result.GetOutputStream(), arg.ref,
+ OptionValue::eDumpGroupValue));
+ if (error.Success()) {
+ result.GetOutputStream().EOL();
+ } else {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
}
-
- return result.Succeeded();
+ }
+ } else {
+ m_interpreter.GetDebugger().DumpAllPropertyValues(
+ &m_exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue);
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectSettingsList -- List settable variables
//-------------------------------------------------------------------------
-class CommandObjectSettingsList : public CommandObjectParsed
-{
+class CommandObjectSettingsList : public CommandObjectParsed {
public:
- CommandObjectSettingsList(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "settings list",
- "List and describe matching debugger settings. Defaults to all listing all settings.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandArgumentData var_name_arg;
- CommandArgumentData prefix_name_arg;
-
- // Define the first variant of this arg.
- var_name_arg.arg_type = eArgTypeSettingVariableName;
- var_name_arg.arg_repetition = eArgRepeatOptional;
-
- // Define the second variant of this arg.
- prefix_name_arg.arg_type = eArgTypeSettingPrefix;
- prefix_name_arg.arg_repetition = eArgRepeatOptional;
-
- arg.push_back (var_name_arg);
- arg.push_back (prefix_name_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectSettingsList() override = default;
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
- }
+ CommandObjectSettingsList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "settings list",
+ "List and describe matching debugger settings. "
+ "Defaults to all listing all settings.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData prefix_name_arg;
+
+ // Define the first variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatOptional;
+
+ // Define the second variant of this arg.
+ prefix_name_arg.arg_type = eArgTypeSettingPrefix;
+ prefix_name_arg.arg_repetition = eArgRepeatOptional;
+
+ arg.push_back(var_name_arg);
+ arg.push_back(prefix_name_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectSettingsList() override = default;
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index),
+ cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
-
- const bool will_modify = false;
- const size_t argc = args.GetArgumentCount ();
- if (argc > 0)
- {
- const bool dump_qualified_name = true;
-
- for (size_t i = 0; i < argc; ++i)
- {
- const char *property_path = args.GetArgumentAtIndex (i);
-
- const Property *property = m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath (&m_exe_ctx, will_modify, property_path);
-
- if (property)
- {
- property->DumpDescription (m_interpreter, result.GetOutputStream(), 0, dump_qualified_name);
- }
- else
- {
- result.AppendErrorWithFormat ("invalid property path '%s'", property_path);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- }
- else
- {
- m_interpreter.GetDebugger().DumpAllDescriptions (m_interpreter, result.GetOutputStream());
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+
+ const bool will_modify = false;
+ const size_t argc = args.GetArgumentCount();
+ if (argc > 0) {
+ const bool dump_qualified_name = true;
+
+ // TODO: Convert to StringRef based enumeration. Requires converting
+ // GetPropertyAtPath first.
+ for (size_t i = 0; i < argc; ++i) {
+ const char *property_path = args.GetArgumentAtIndex(i);
+
+ const Property *property =
+ m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath(
+ &m_exe_ctx, will_modify, property_path);
+
+ if (property) {
+ property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
+ dump_qualified_name);
+ } else {
+ result.AppendErrorWithFormat("invalid property path '%s'",
+ property_path);
+ result.SetStatus(eReturnStatusFailed);
}
-
- return result.Succeeded();
+ }
+ } else {
+ m_interpreter.GetDebugger().DumpAllDescriptions(m_interpreter,
+ result.GetOutputStream());
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectSettingsRemove
//-------------------------------------------------------------------------
-class CommandObjectSettingsRemove : public CommandObjectRaw
-{
+class CommandObjectSettingsRemove : public CommandObjectRaw {
public:
- CommandObjectSettingsRemove(CommandInterpreter &interpreter)
- : CommandObjectRaw(interpreter, "settings remove",
- "Remove a value from a setting, specified by array index or dictionary key.", nullptr)
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentData var_name_arg;
- CommandArgumentData index_arg;
- CommandArgumentData key_arg;
-
- // Define the first (and only) variant of this arg.
- var_name_arg.arg_type = eArgTypeSettingVariableName;
- var_name_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (var_name_arg);
-
- // Define the first variant of this arg.
- index_arg.arg_type = eArgTypeSettingIndex;
- index_arg.arg_repetition = eArgRepeatPlain;
-
- // Define the second variant of this arg.
- key_arg.arg_type = eArgTypeSettingKey;
- key_arg.arg_repetition = eArgRepeatPlain;
-
- // Push both variants into this arg
- arg2.push_back (index_arg);
- arg2.push_back (key_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
+ CommandObjectSettingsRemove(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings remove",
+ "Remove a value from a setting, specified by array "
+ "index or dictionary key.") {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData index_arg;
+ CommandArgumentData key_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first variant of this arg.
+ index_arg.arg_type = eArgTypeSettingIndex;
+ index_arg.arg_repetition = eArgRepeatPlain;
+
+ // Define the second variant of this arg.
+ key_arg.arg_type = eArgTypeSettingKey;
+ key_arg.arg_repetition = eArgRepeatPlain;
+
+ // Push both variants into this arg
+ arg2.push_back(index_arg);
+ arg2.push_back(key_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ }
+
+ ~CommandObjectSettingsRemove() override = default;
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index),
+ cursor_char_position);
+
+ // Attempting to complete variable name
+ if (cursor_index < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements,
+ nullptr, word_complete, matches);
+ return matches.GetSize();
+ }
+
+protected:
+ bool DoExecute(const char *command, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+
+ Args cmd_args(command);
+
+ // Process possible options.
+ if (!ParseOptions(cmd_args, result))
+ return false;
+
+ const size_t argc = cmd_args.GetArgumentCount();
+ if (argc == 0) {
+ result.AppendError("'settings set' takes an array or dictionary item, or "
+ "an array followed by one or more indexes, or a "
+ "dictionary followed by one or more key names to "
+ "remove");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- ~CommandObjectSettingsRemove() override = default;
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
-
- // Attempting to complete variable name
- if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
-
- return matches.GetSize();
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError(
+ "'settings set' command requires a valid variable name");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-protected:
- bool
- DoExecute (const char *command, CommandReturnObject &result) override
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
-
- Args cmd_args(command);
-
- // Process possible options.
- if (!ParseOptions (cmd_args, result))
- return false;
-
- const size_t argc = cmd_args.GetArgumentCount ();
- if (argc == 0)
- {
- result.AppendError ("'settings set' takes an array or dictionary item, or an array followed by one or more indexes, or a dictionary followed by one or more key names to remove");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == nullptr) || (var_name[0] == '\0'))
- {
- result.AppendError ("'settings set' command requires a valid variable name");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- // Split the raw command into var_name and value pair.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
-
- Error error (m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
- eVarSetOperationRemove,
- var_name,
- var_value_cstr));
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- return result.Succeeded();
+ // Split the raw command into var_name and value pair.
+ llvm::StringRef raw_str(command);
+ std::string var_value_string = raw_str.split(var_name).second.str();
+ const char *var_value_cstr =
+ Args::StripSpaces(var_value_string, true, true, false);
+
+ Error error(m_interpreter.GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectSettingsReplace
//-------------------------------------------------------------------------
-class CommandObjectSettingsReplace : public CommandObjectRaw
-{
+class CommandObjectSettingsReplace : public CommandObjectRaw {
public:
- CommandObjectSettingsReplace(CommandInterpreter &interpreter)
- : CommandObjectRaw(interpreter, "settings replace",
- "Replace the debugger setting value specified by array index or dictionary key.", nullptr)
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentEntry arg3;
- CommandArgumentData var_name_arg;
- CommandArgumentData index_arg;
- CommandArgumentData key_arg;
- CommandArgumentData value_arg;
-
- // Define the first (and only) variant of this arg.
- var_name_arg.arg_type = eArgTypeSettingVariableName;
- var_name_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (var_name_arg);
-
- // Define the first (variant of this arg.
- index_arg.arg_type = eArgTypeSettingIndex;
- index_arg.arg_repetition = eArgRepeatPlain;
-
- // Define the second (variant of this arg.
- key_arg.arg_type = eArgTypeSettingKey;
- key_arg.arg_repetition = eArgRepeatPlain;
-
- // Put both variants into this arg
- arg2.push_back (index_arg);
- arg2.push_back (key_arg);
-
- // Define the first (and only) variant of this arg.
- value_arg.arg_type = eArgTypeValue;
- value_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg3.push_back (value_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
- m_arguments.push_back (arg3);
- }
-
- ~CommandObjectSettingsReplace() override = default;
-
- // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
- bool
- WantsCompletion() override { return true; }
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
-
- // Attempting to complete variable name
- if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
-
- return matches.GetSize();
- }
+ CommandObjectSettingsReplace(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings replace",
+ "Replace the debugger setting value specified by "
+ "array index or dictionary key.") {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentEntry arg3;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData index_arg;
+ CommandArgumentData key_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first (variant of this arg.
+ index_arg.arg_type = eArgTypeSettingIndex;
+ index_arg.arg_repetition = eArgRepeatPlain;
+
+ // Define the second (variant of this arg.
+ key_arg.arg_type = eArgTypeSettingKey;
+ key_arg.arg_repetition = eArgRepeatPlain;
+
+ // Put both variants into this arg
+ arg2.push_back(index_arg);
+ arg2.push_back(key_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg3.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ m_arguments.push_back(arg3);
+ }
+
+ ~CommandObjectSettingsReplace() override = default;
+
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index),
+ cursor_char_position);
+
+ // Attempting to complete variable name
+ if (cursor_index < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements,
+ nullptr, word_complete, matches);
+
+ return matches.GetSize();
+ }
protected:
- bool
- DoExecute (const char *command, CommandReturnObject &result) override
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
-
- Args cmd_args(command);
- const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == nullptr) || (var_name[0] == '\0'))
- {
- result.AppendError ("'settings replace' command requires a valid variable name; No value supplied");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- // Split the raw command into var_name, index_value, and value triple.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
-
- Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
- eVarSetOperationReplace,
- var_name,
- var_value_cstr));
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
-
- }
+ bool DoExecute(const char *command, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+
+ Args cmd_args(command);
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError("'settings replace' command requires a valid variable "
+ "name; No value supplied");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- return result.Succeeded();
+ // Split the raw command into var_name, index_value, and value triple.
+ llvm::StringRef raw_str(command);
+ std::string var_value_string = raw_str.split(var_name).second.str();
+ const char *var_value_cstr =
+ Args::StripSpaces(var_value_string, true, true, false);
+
+ Error error(m_interpreter.GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectSettingsInsertBefore
//-------------------------------------------------------------------------
-class CommandObjectSettingsInsertBefore : public CommandObjectRaw
-{
+class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
public:
- CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
- : CommandObjectRaw(interpreter, "settings insert-before", "Insert one or more values into an debugger array "
- "setting immediately before the specified element "
- "index.",
- nullptr)
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentEntry arg3;
- CommandArgumentData var_name_arg;
- CommandArgumentData index_arg;
- CommandArgumentData value_arg;
-
- // Define the first (and only) variant of this arg.
- var_name_arg.arg_type = eArgTypeSettingVariableName;
- var_name_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (var_name_arg);
-
- // Define the first (variant of this arg.
- index_arg.arg_type = eArgTypeSettingIndex;
- index_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg2.push_back (index_arg);
-
- // Define the first (and only) variant of this arg.
- value_arg.arg_type = eArgTypeValue;
- value_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg3.push_back (value_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
- m_arguments.push_back (arg3);
- }
-
- ~CommandObjectSettingsInsertBefore() override = default;
-
- // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
- bool
- WantsCompletion() override { return true; }
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
-
- // Attempting to complete variable name
- if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
-
- return matches.GetSize();
- }
+ CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings insert-before",
+ "Insert one or more values into an debugger array "
+ "setting immediately before the specified element "
+ "index.") {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentEntry arg3;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData index_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first (variant of this arg.
+ index_arg.arg_type = eArgTypeSettingIndex;
+ index_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(index_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg3.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ m_arguments.push_back(arg3);
+ }
+
+ ~CommandObjectSettingsInsertBefore() override = default;
+
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index),
+ cursor_char_position);
+
+ // Attempting to complete variable name
+ if (cursor_index < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements,
+ nullptr, word_complete, matches);
+
+ return matches.GetSize();
+ }
protected:
- bool
- DoExecute (const char *command, CommandReturnObject &result) override
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
-
- Args cmd_args(command);
- const size_t argc = cmd_args.GetArgumentCount ();
-
- if (argc < 3)
- {
- result.AppendError ("'settings insert-before' takes more arguments");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(const char *command, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
- const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == nullptr) || (var_name[0] == '\0'))
- {
- result.AppendError ("'settings insert-before' command requires a valid variable name; No value supplied");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ Args cmd_args(command);
+ const size_t argc = cmd_args.GetArgumentCount();
- // Split the raw command into var_name, index_value, and value triple.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
-
- Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
- eVarSetOperationInsertBefore,
- var_name,
- var_value_cstr));
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (argc < 3) {
+ result.AppendError("'settings insert-before' takes more arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- return result.Succeeded();
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError("'settings insert-before' command requires a valid "
+ "variable name; No value supplied");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ // Split the raw command into var_name, index_value, and value triple.
+ llvm::StringRef raw_str(command);
+ std::string var_value_string = raw_str.split(var_name).second.str();
+ const char *var_value_cstr =
+ Args::StripSpaces(var_value_string, true, true, false);
+
+ Error error(m_interpreter.GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectSettingInsertAfter
//-------------------------------------------------------------------------
-class CommandObjectSettingsInsertAfter : public CommandObjectRaw
-{
+class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
public:
- CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
- : CommandObjectRaw(
- interpreter, "settings insert-after",
- "Insert one or more values into a debugger array settings after the specified element index.", nullptr)
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentEntry arg3;
- CommandArgumentData var_name_arg;
- CommandArgumentData index_arg;
- CommandArgumentData value_arg;
-
- // Define the first (and only) variant of this arg.
- var_name_arg.arg_type = eArgTypeSettingVariableName;
- var_name_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (var_name_arg);
-
- // Define the first (variant of this arg.
- index_arg.arg_type = eArgTypeSettingIndex;
- index_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg2.push_back (index_arg);
-
- // Define the first (and only) variant of this arg.
- value_arg.arg_type = eArgTypeValue;
- value_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg3.push_back (value_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
- m_arguments.push_back (arg3);
- }
+ CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings insert-after",
+ "Insert one or more values into a debugger array "
+ "settings after the specified element index.") {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentEntry arg3;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData index_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first (variant of this arg.
+ index_arg.arg_type = eArgTypeSettingIndex;
+ index_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(index_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg3.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ m_arguments.push_back(arg3);
+ }
+
+ ~CommandObjectSettingsInsertAfter() override = default;
+
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index),
+ cursor_char_position);
+
+ // Attempting to complete variable name
+ if (cursor_index < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements,
+ nullptr, word_complete, matches);
+
+ return matches.GetSize();
+ }
- ~CommandObjectSettingsInsertAfter() override = default;
-
- // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
- bool
- WantsCompletion() override { return true; }
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
-
- // Attempting to complete variable name
- if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
-
- return matches.GetSize();
- }
-
protected:
- bool
- DoExecute (const char *command, CommandReturnObject &result) override
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
-
- Args cmd_args(command);
- const size_t argc = cmd_args.GetArgumentCount ();
-
- if (argc < 3)
- {
- result.AppendError ("'settings insert-after' takes more arguments");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(const char *command, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
- const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == nullptr) || (var_name[0] == '\0'))
- {
- result.AppendError ("'settings insert-after' command requires a valid variable name; No value supplied");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ Args cmd_args(command);
+ const size_t argc = cmd_args.GetArgumentCount();
- // Split the raw command into var_name, index_value, and value triple.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
-
- Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
- eVarSetOperationInsertAfter,
- var_name,
- var_value_cstr));
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (argc < 3) {
+ result.AppendError("'settings insert-after' takes more arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- return result.Succeeded();
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError("'settings insert-after' command requires a valid "
+ "variable name; No value supplied");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ // Split the raw command into var_name, index_value, and value triple.
+ llvm::StringRef raw_str(command);
+ std::string var_value_string = raw_str.split(var_name).second.str();
+ const char *var_value_cstr =
+ Args::StripSpaces(var_value_string, true, true, false);
+
+ Error error(m_interpreter.GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectSettingsAppend
//-------------------------------------------------------------------------
-class CommandObjectSettingsAppend : public CommandObjectRaw
-{
+class CommandObjectSettingsAppend : public CommandObjectRaw {
public:
- CommandObjectSettingsAppend(CommandInterpreter &interpreter)
- : CommandObjectRaw(interpreter, "settings append",
- "Append one or more values to a debugger array, dictionary, or string setting.", nullptr)
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentData var_name_arg;
- CommandArgumentData value_arg;
-
- // Define the first (and only) variant of this arg.
- var_name_arg.arg_type = eArgTypeSettingVariableName;
- var_name_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg1.push_back (var_name_arg);
-
- // Define the first (and only) variant of this arg.
- value_arg.arg_type = eArgTypeValue;
- value_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg2.push_back (value_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
- }
-
- ~CommandObjectSettingsAppend() override = default;
-
- // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
- bool
- WantsCompletion() override { return true; }
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
-
- // Attempting to complete variable name
- if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
-
- return matches.GetSize();
- }
+ CommandObjectSettingsAppend(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "settings append",
+ "Append one or more values to a debugger array, "
+ "dictionary, or string setting.") {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData var_name_arg;
+ CommandArgumentData value_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(var_name_arg);
+
+ // Define the first (and only) variant of this arg.
+ value_arg.arg_type = eArgTypeValue;
+ value_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg2.push_back(value_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ }
+
+ ~CommandObjectSettingsAppend() override = default;
+
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index),
+ cursor_char_position);
+
+ // Attempting to complete variable name
+ if (cursor_index < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements,
+ nullptr, word_complete, matches);
+
+ return matches.GetSize();
+ }
protected:
- bool
- DoExecute (const char *command, CommandReturnObject &result) override
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- Args cmd_args(command);
- const size_t argc = cmd_args.GetArgumentCount ();
-
- if (argc < 2)
- {
- result.AppendError ("'settings append' takes more arguments");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- const char *var_name = cmd_args.GetArgumentAtIndex (0);
- if ((var_name == nullptr) || (var_name[0] == '\0'))
- {
- result.AppendError ("'settings append' command requires a valid variable name; No value supplied");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(const char *command, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ Args cmd_args(command);
+ const size_t argc = cmd_args.GetArgumentCount();
+
+ if (argc < 2) {
+ result.AppendError("'settings append' takes more arguments");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- // Do not perform cmd_args.Shift() since StringRef is manipulating the
- // raw character string later on.
-
- // Split the raw command into var_name and value pair.
- llvm::StringRef raw_str(command);
- std::string var_value_string = raw_str.split(var_name).second.str();
- const char *var_value_cstr = Args::StripSpaces(var_value_string, true, true, false);
-
- Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
- eVarSetOperationAppend,
- var_name,
- var_value_cstr));
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ const char *var_name = cmd_args.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError("'settings append' command requires a valid variable "
+ "name; No value supplied");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- return result.Succeeded();
+ // Do not perform cmd_args.Shift() since StringRef is manipulating the
+ // raw character string later on.
+
+ // Split the raw command into var_name and value pair.
+ llvm::StringRef raw_str(command);
+ std::string var_value_string = raw_str.split(var_name).second.str();
+ const char *var_value_cstr =
+ Args::StripSpaces(var_value_string, true, true, false);
+
+ Error error(m_interpreter.GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectSettingsClear
//-------------------------------------------------------------------------
-class CommandObjectSettingsClear : public CommandObjectParsed
-{
+class CommandObjectSettingsClear : public CommandObjectParsed {
public:
- CommandObjectSettingsClear(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "settings clear", "Clear a debugger setting array, dictionary, or string.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandArgumentData var_name_arg;
-
- // Define the first (and only) variant of this arg.
- var_name_arg.arg_type = eArgTypeSettingVariableName;
- var_name_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (var_name_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectSettingsClear() override = default;
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
-
- // Attempting to complete variable name
- if (cursor_index < 2)
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eSettingsNameCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
-
- return matches.GetSize();
- }
+ CommandObjectSettingsClear(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "settings clear",
+ "Clear a debugger setting array, dictionary, or string.", nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData var_name_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(var_name_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectSettingsClear() override = default;
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index),
+ cursor_char_position);
+
+ // Attempting to complete variable name
+ if (cursor_index < 2)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements,
+ nullptr, word_complete, matches);
+
+ return matches.GetSize();
+ }
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- const size_t argc = command.GetArgumentCount ();
-
- if (argc != 1)
- {
- result.AppendError ("'settings clear' takes exactly one argument");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc != 1) {
+ result.AppendError("'settings clear' takes exactly one argument");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- const char *var_name = command.GetArgumentAtIndex (0);
- if ((var_name == nullptr) || (var_name[0] == '\0'))
- {
- result.AppendError ("'settings clear' command requires a valid variable name; No value supplied");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- Error error(m_interpreter.GetDebugger().SetPropertyValue(&m_exe_ctx,
- eVarSetOperationClear,
- var_name,
- nullptr));
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ const char *var_name = command.GetArgumentAtIndex(0);
+ if ((var_name == nullptr) || (var_name[0] == '\0')) {
+ result.AppendError("'settings clear' command requires a valid variable "
+ "name; No value supplied");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- return result.Succeeded();
+ Error error(m_interpreter.GetDebugger().SetPropertyValue(
+ &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectMultiwordSettings
//-------------------------------------------------------------------------
-CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "settings", "Commands for managing LLDB settings.",
- "settings <subcommand> [<command-options>]")
-{
- LoadSubCommand ("set", CommandObjectSP (new CommandObjectSettingsSet (interpreter)));
- LoadSubCommand ("show", CommandObjectSP (new CommandObjectSettingsShow (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectSettingsList (interpreter)));
- LoadSubCommand ("remove", CommandObjectSP (new CommandObjectSettingsRemove (interpreter)));
- LoadSubCommand ("replace", CommandObjectSP (new CommandObjectSettingsReplace (interpreter)));
- LoadSubCommand ("insert-before", CommandObjectSP (new CommandObjectSettingsInsertBefore (interpreter)));
- LoadSubCommand ("insert-after", CommandObjectSP (new CommandObjectSettingsInsertAfter (interpreter)));
- LoadSubCommand ("append", CommandObjectSP (new CommandObjectSettingsAppend (interpreter)));
- LoadSubCommand ("clear", CommandObjectSP (new CommandObjectSettingsClear (interpreter)));
+CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "settings",
+ "Commands for managing LLDB settings.",
+ "settings <subcommand> [<command-options>]") {
+ LoadSubCommand("set",
+ CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
+ LoadSubCommand("show",
+ CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
+ LoadSubCommand("list",
+ CommandObjectSP(new CommandObjectSettingsList(interpreter)));
+ LoadSubCommand("remove",
+ CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
+ LoadSubCommand("replace", CommandObjectSP(
+ new CommandObjectSettingsReplace(interpreter)));
+ LoadSubCommand(
+ "insert-before",
+ CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
+ LoadSubCommand(
+ "insert-after",
+ CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
+ LoadSubCommand("append",
+ CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
+ LoadSubCommand("clear",
+ CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
}
CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;
diff --git a/source/Commands/CommandObjectSettings.h b/source/Commands/CommandObjectSettings.h
index 93ee91981c10..3376cccd1799 100644
--- a/source/Commands/CommandObjectSettings.h
+++ b/source/Commands/CommandObjectSettings.h
@@ -18,20 +18,17 @@
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/Options.h"
-
namespace lldb_private {
//-------------------------------------------------------------------------
// CommandObjectMultiwordSettings
//-------------------------------------------------------------------------
-class CommandObjectMultiwordSettings : public CommandObjectMultiword
-{
+class CommandObjectMultiwordSettings : public CommandObjectMultiword {
public:
+ CommandObjectMultiwordSettings(CommandInterpreter &interpreter);
- CommandObjectMultiwordSettings (CommandInterpreter &interpreter);
-
- ~CommandObjectMultiwordSettings() override;
+ ~CommandObjectMultiwordSettings() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index cef9d09d0e55..6ff32080905e 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -18,10 +18,12 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/SourceManager.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/CommandCompletions.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
@@ -29,8 +31,6 @@
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/TargetList.h"
-#include "lldb/Interpreter/CommandCompletions.h"
-#include "lldb/Interpreter/Options.h"
using namespace lldb;
using namespace lldb_private;
@@ -40,682 +40,622 @@ using namespace lldb_private;
// CommandObjectSourceInfo - debug line entries dumping command
//----------------------------------------------------------------------
-class CommandObjectSourceInfo : public CommandObjectParsed
-{
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) : Options(interpreter) {}
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = g_option_table[option_idx].short_option;
- switch (short_option)
- {
- case 'l':
- start_line = StringConvert::ToUInt32(option_arg, 0);
- if (start_line == 0)
- error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg);
- break;
-
- case 'e':
- end_line = StringConvert::ToUInt32(option_arg, 0);
- if (end_line == 0)
- error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg);
- break;
-
- case 'c':
- num_lines = StringConvert::ToUInt32(option_arg, 0);
- if (num_lines == 0)
- error.SetErrorStringWithFormat("invalid line count: '%s'", option_arg);
- break;
-
- case 'f':
- file_name = option_arg;
- break;
-
- case 'n':
- symbol_name = option_arg;
- break;
-
- case 'a':
- {
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- address = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- }
- break;
- case 's':
- modules.push_back(std::string(option_arg));
- break;
- default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
- break;
- }
-
- return error;
- }
+static OptionDefinition g_source_info_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "The number of line entries to display." },
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source in the given module or shared library (can be specified more than once)." },
+ { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." },
+ { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "The line number at which to start the displaying lines." },
+ { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "The line number at which to stop displaying lines." },
+ { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." },
+ { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." },
+ // clang-format on
+};
- void
- OptionParsingStarting () override
- {
- file_spec.Clear();
- file_name.clear();
- symbol_name.clear();
- address = LLDB_INVALID_ADDRESS;
- start_line = 0;
- end_line = 0;
- num_lines = 0;
- modules.clear();
- }
+class CommandObjectSourceInfo : public CommandObjectParsed {
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = GetDefinitions()[option_idx].short_option;
+ switch (short_option) {
+ case 'l':
+ if (option_arg.getAsInteger(0, start_line))
+ error.SetErrorStringWithFormat("invalid line number: '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'e':
+ if (option_arg.getAsInteger(0, end_line))
+ error.SetErrorStringWithFormat("invalid line number: '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'c':
+ if (option_arg.getAsInteger(0, num_lines))
+ error.SetErrorStringWithFormat("invalid line count: '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'f':
+ file_name = option_arg;
+ break;
+
+ case 'n':
+ symbol_name = option_arg;
+ break;
+
+ case 'a': {
+ address = Args::StringToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
+ } break;
+ case 's':
+ modules.push_back(std::string(option_arg));
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
- const OptionDefinition *
- GetDefinitions () override
- {
- return g_option_table;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ file_spec.Clear();
+ file_name.clear();
+ symbol_name.clear();
+ address = LLDB_INVALID_ADDRESS;
+ start_line = 0;
+ end_line = 0;
+ num_lines = 0;
+ modules.clear();
+ }
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_source_info_options);
+ }
- // Instance variables to hold the values for command options.
- FileSpec file_spec;
- std::string file_name;
- std::string symbol_name;
- lldb::addr_t address;
- uint32_t start_line;
- uint32_t end_line;
- uint32_t num_lines;
- STLStringArray modules;
- };
+ // Instance variables to hold the values for command options.
+ FileSpec file_spec;
+ std::string file_name;
+ std::string symbol_name;
+ lldb::addr_t address;
+ uint32_t start_line;
+ uint32_t end_line;
+ uint32_t num_lines;
+ STLStringArray modules;
+ };
public:
- CommandObjectSourceInfo(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "source info", "Display source line information for the current target "
- "process. Defaults to instruction pointer in current stack "
- "frame.",
- nullptr, eCommandRequiresTarget),
- m_options(interpreter)
- {
- }
+ CommandObjectSourceInfo(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "source info",
+ "Display source line information for the current target "
+ "process. Defaults to instruction pointer in current stack "
+ "frame.",
+ nullptr, eCommandRequiresTarget),
+ m_options() {}
- ~CommandObjectSourceInfo() override = default;
+ ~CommandObjectSourceInfo() override = default;
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ Options *GetOptions() override { return &m_options; }
protected:
- // Dump the line entries in each symbol context.
- // Return the number of entries found.
- // If module_list is set, only dump lines contained in one of the modules.
- // If file_spec is set, only dump lines in the file.
- // If the start_line option was specified, don't print lines less than start_line.
- // If the end_line option was specified, don't print lines greater than end_line.
- // If the num_lines option was specified, dont print more than num_lines entries.
- uint32_t
- DumpLinesInSymbolContexts (Stream &strm, const SymbolContextList &sc_list,
- const ModuleList &module_list, const FileSpec &file_spec)
- {
- uint32_t start_line = m_options.start_line;
- uint32_t end_line = m_options.end_line;
- uint32_t num_lines = m_options.num_lines;
- Target *target = m_exe_ctx.GetTargetPtr();
-
- uint32_t num_matches = 0;
- bool has_path = false;
- if (file_spec)
- {
- assert(file_spec.GetFilename().AsCString());
- has_path = (file_spec.GetDirectory().AsCString() != nullptr);
- }
-
- // Dump all the line entries for the file in the list.
- ConstString last_module_file_name;
- uint32_t num_scs = sc_list.GetSize();
- for (uint32_t i = 0; i < num_scs; ++i)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(i, sc);
- if (sc.comp_unit)
- {
- Module *module = sc.module_sp.get();
- CompileUnit *cu = sc.comp_unit;
- const LineEntry &line_entry = sc.line_entry;
- assert(module && cu);
-
- // Are we looking for specific modules, files or lines?
- if (module_list.GetSize() && module_list.GetIndexForModule(module) == LLDB_INVALID_INDEX32)
- continue;
- if (file_spec && !lldb_private::FileSpec::Equal(file_spec, line_entry.file, has_path))
- continue;
- if (start_line > 0 && line_entry.line < start_line)
- continue;
- if (end_line > 0 && line_entry.line > end_line)
- continue;
- if (num_lines > 0 && num_matches > num_lines)
- continue;
-
- // Print a new header if the module changed.
- const ConstString &module_file_name = module->GetFileSpec().GetFilename();
- assert(module_file_name);
- if (module_file_name != last_module_file_name)
- {
- if (num_matches > 0)
- strm << "\n\n";
- strm << "Lines found in module `" << module_file_name << "\n";
- }
- // Dump the line entry.
- line_entry.GetDescription(&strm, lldb::eDescriptionLevelBrief, cu,
- target, /*show_address_only=*/false);
- strm << "\n";
- last_module_file_name = module_file_name;
- num_matches++;
- }
- }
- return num_matches;
+ // Dump the line entries in each symbol context.
+ // Return the number of entries found.
+ // If module_list is set, only dump lines contained in one of the modules.
+ // If file_spec is set, only dump lines in the file.
+ // If the start_line option was specified, don't print lines less than
+ // start_line.
+ // If the end_line option was specified, don't print lines greater than
+ // end_line.
+ // If the num_lines option was specified, dont print more than num_lines
+ // entries.
+ uint32_t DumpLinesInSymbolContexts(Stream &strm,
+ const SymbolContextList &sc_list,
+ const ModuleList &module_list,
+ const FileSpec &file_spec) {
+ uint32_t start_line = m_options.start_line;
+ uint32_t end_line = m_options.end_line;
+ uint32_t num_lines = m_options.num_lines;
+ Target *target = m_exe_ctx.GetTargetPtr();
+
+ uint32_t num_matches = 0;
+ bool has_path = false;
+ if (file_spec) {
+ assert(file_spec.GetFilename().AsCString());
+ has_path = (file_spec.GetDirectory().AsCString() != nullptr);
}
-
- // Dump the requested line entries for the file in the compilation unit.
- // Return the number of entries found.
- // If module_list is set, only dump lines contained in one of the modules.
- // If the start_line option was specified, don't print lines less than start_line.
- // If the end_line option was specified, don't print lines greater than end_line.
- // If the num_lines option was specified, dont print more than num_lines entries.
- uint32_t
- DumpFileLinesInCompUnit (Stream &strm, Module *module, CompileUnit *cu, const FileSpec &file_spec)
- {
- uint32_t start_line = m_options.start_line;
- uint32_t end_line = m_options.end_line;
- uint32_t num_lines = m_options.num_lines;
- Target *target = m_exe_ctx.GetTargetPtr();
-
- uint32_t num_matches = 0;
- assert(module);
- if (cu)
- {
- assert(file_spec.GetFilename().AsCString());
- bool has_path = (file_spec.GetDirectory().AsCString() != nullptr);
- const FileSpecList &cu_file_list = cu->GetSupportFiles();
- size_t file_idx = cu_file_list.FindFileIndex(0, file_spec, has_path);
- if (file_idx != UINT32_MAX)
- {
- // Update the file to how it appears in the CU.
- const FileSpec &cu_file_spec = cu_file_list.GetFileSpecAtIndex(file_idx);
-
- // Dump all matching lines at or above start_line for the file in the CU.
- const ConstString &file_spec_name = file_spec.GetFilename();
- const ConstString &module_file_name = module->GetFileSpec().GetFilename();
- bool cu_header_printed = false;
- uint32_t line = start_line;
- while (true)
- {
- LineEntry line_entry;
-
- // Find the lowest index of a line entry with a line equal to
- // or higher than 'line'.
- uint32_t start_idx = 0;
- start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec,
- /*exact=*/false, &line_entry);
- if (start_idx == UINT32_MAX)
- // No more line entries for our file in this CU.
- break;
-
- if (end_line > 0 && line_entry.line > end_line)
- break;
-
- // Loop through to find any other entries for this line, dumping each.
- line = line_entry.line;
- do
- {
- num_matches++;
- if (num_lines > 0 && num_matches > num_lines)
- break;
- assert(lldb_private::FileSpec::Equal(cu_file_spec, line_entry.file, has_path));
- if (!cu_header_printed)
- {
- if (num_matches > 0)
- strm << "\n\n";
- strm << "Lines found for file " << file_spec_name
- << " in compilation unit " << cu->GetFilename()
- << " in `" << module_file_name << "\n";
- cu_header_printed = true;
- }
- line_entry.GetDescription(&strm, lldb::eDescriptionLevelBrief, cu,
- target, /*show_address_only=*/false);
- strm << "\n";
-
- // Anymore after this one?
- start_idx++;
- start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec,
- /*exact=*/true, &line_entry);
- } while (start_idx != UINT32_MAX);
-
- // Try the next higher line, starting over at start_idx 0.
- line++;
- }
- }
+
+ // Dump all the line entries for the file in the list.
+ ConstString last_module_file_name;
+ uint32_t num_scs = sc_list.GetSize();
+ for (uint32_t i = 0; i < num_scs; ++i) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(i, sc);
+ if (sc.comp_unit) {
+ Module *module = sc.module_sp.get();
+ CompileUnit *cu = sc.comp_unit;
+ const LineEntry &line_entry = sc.line_entry;
+ assert(module && cu);
+
+ // Are we looking for specific modules, files or lines?
+ if (module_list.GetSize() &&
+ module_list.GetIndexForModule(module) == LLDB_INVALID_INDEX32)
+ continue;
+ if (file_spec &&
+ !lldb_private::FileSpec::Equal(file_spec, line_entry.file,
+ has_path))
+ continue;
+ if (start_line > 0 && line_entry.line < start_line)
+ continue;
+ if (end_line > 0 && line_entry.line > end_line)
+ continue;
+ if (num_lines > 0 && num_matches > num_lines)
+ continue;
+
+ // Print a new header if the module changed.
+ const ConstString &module_file_name =
+ module->GetFileSpec().GetFilename();
+ assert(module_file_name);
+ if (module_file_name != last_module_file_name) {
+ if (num_matches > 0)
+ strm << "\n\n";
+ strm << "Lines found in module `" << module_file_name << "\n";
}
- return num_matches;
+ // Dump the line entry.
+ line_entry.GetDescription(&strm, lldb::eDescriptionLevelBrief, cu,
+ target, /*show_address_only=*/false);
+ strm << "\n";
+ last_module_file_name = module_file_name;
+ num_matches++;
+ }
}
-
- // Dump the requested line entries for the file in the module.
- // Return the number of entries found.
- // If module_list is set, only dump lines contained in one of the modules.
- // If the start_line option was specified, don't print lines less than start_line.
- // If the end_line option was specified, don't print lines greater than end_line.
- // If the num_lines option was specified, dont print more than num_lines entries.
- uint32_t
- DumpFileLinesInModule (Stream &strm, Module *module, const FileSpec &file_spec)
- {
- uint32_t num_matches = 0;
- if (module)
- {
- // Look through all the compilation units (CUs) in this module for ones that
- // contain lines of code from this source file.
- for (size_t i = 0; i < module->GetNumCompileUnits(); i++)
- {
- // Look for a matching source file in this CU.
- CompUnitSP cu_sp(module->GetCompileUnitAtIndex(i));
- if (cu_sp)
- {
- num_matches += DumpFileLinesInCompUnit(strm, module, cu_sp.get(), file_spec);
- }
+ return num_matches;
+ }
+
+ // Dump the requested line entries for the file in the compilation unit.
+ // Return the number of entries found.
+ // If module_list is set, only dump lines contained in one of the modules.
+ // If the start_line option was specified, don't print lines less than
+ // start_line.
+ // If the end_line option was specified, don't print lines greater than
+ // end_line.
+ // If the num_lines option was specified, dont print more than num_lines
+ // entries.
+ uint32_t DumpFileLinesInCompUnit(Stream &strm, Module *module,
+ CompileUnit *cu, const FileSpec &file_spec) {
+ uint32_t start_line = m_options.start_line;
+ uint32_t end_line = m_options.end_line;
+ uint32_t num_lines = m_options.num_lines;
+ Target *target = m_exe_ctx.GetTargetPtr();
+
+ uint32_t num_matches = 0;
+ assert(module);
+ if (cu) {
+ assert(file_spec.GetFilename().AsCString());
+ bool has_path = (file_spec.GetDirectory().AsCString() != nullptr);
+ const FileSpecList &cu_file_list = cu->GetSupportFiles();
+ size_t file_idx = cu_file_list.FindFileIndex(0, file_spec, has_path);
+ if (file_idx != UINT32_MAX) {
+ // Update the file to how it appears in the CU.
+ const FileSpec &cu_file_spec =
+ cu_file_list.GetFileSpecAtIndex(file_idx);
+
+ // Dump all matching lines at or above start_line for the file in the
+ // CU.
+ const ConstString &file_spec_name = file_spec.GetFilename();
+ const ConstString &module_file_name =
+ module->GetFileSpec().GetFilename();
+ bool cu_header_printed = false;
+ uint32_t line = start_line;
+ while (true) {
+ LineEntry line_entry;
+
+ // Find the lowest index of a line entry with a line equal to
+ // or higher than 'line'.
+ uint32_t start_idx = 0;
+ start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec,
+ /*exact=*/false, &line_entry);
+ if (start_idx == UINT32_MAX)
+ // No more line entries for our file in this CU.
+ break;
+
+ if (end_line > 0 && line_entry.line > end_line)
+ break;
+
+ // Loop through to find any other entries for this line, dumping each.
+ line = line_entry.line;
+ do {
+ num_matches++;
+ if (num_lines > 0 && num_matches > num_lines)
+ break;
+ assert(lldb_private::FileSpec::Equal(cu_file_spec, line_entry.file,
+ has_path));
+ if (!cu_header_printed) {
+ if (num_matches > 0)
+ strm << "\n\n";
+ strm << "Lines found for file " << file_spec_name
+ << " in compilation unit " << cu->GetFilename() << " in `"
+ << module_file_name << "\n";
+ cu_header_printed = true;
}
+ line_entry.GetDescription(&strm, lldb::eDescriptionLevelBrief, cu,
+ target, /*show_address_only=*/false);
+ strm << "\n";
+
+ // Anymore after this one?
+ start_idx++;
+ start_idx = cu->FindLineEntry(start_idx, line, &cu_file_spec,
+ /*exact=*/true, &line_entry);
+ } while (start_idx != UINT32_MAX);
+
+ // Try the next higher line, starting over at start_idx 0.
+ line++;
}
- return num_matches;
+ }
}
-
- // Given an address and a list of modules, append the symbol contexts of all line entries
- // containing the address found in the modules and return the count of matches. If none
- // is found, return an error in 'error_strm'.
- size_t
- GetSymbolContextsForAddress (const ModuleList &module_list, lldb::addr_t addr,
- SymbolContextList &sc_list, StreamString &error_strm)
- {
- Address so_addr;
- size_t num_matches = 0;
- assert(module_list.GetSize() > 0);
- Target *target = m_exe_ctx.GetTargetPtr();
- if (target->GetSectionLoadList().IsEmpty())
- {
- // The target isn't loaded yet, we need to lookup the file address in
- // all modules. Note: the module list option does not apply to addresses.
- const size_t num_modules = module_list.GetSize();
- for (size_t i = 0; i < num_modules; ++i)
- {
- ModuleSP module_sp(module_list.GetModuleAtIndex(i));
- if (!module_sp)
- continue;
- if (module_sp->ResolveFileAddress(addr, so_addr))
- {
- SymbolContext sc;
- sc.Clear(true);
- if (module_sp->ResolveSymbolContextForAddress(so_addr, eSymbolContextEverything, sc) &
- eSymbolContextLineEntry)
- {
- sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/false);
- ++num_matches;
- }
- }
- }
- if (num_matches == 0)
- error_strm.Printf("Source information for file address 0x%" PRIx64
- " not found in any modules.\n", addr);
+ return num_matches;
+ }
+
+ // Dump the requested line entries for the file in the module.
+ // Return the number of entries found.
+ // If module_list is set, only dump lines contained in one of the modules.
+ // If the start_line option was specified, don't print lines less than
+ // start_line.
+ // If the end_line option was specified, don't print lines greater than
+ // end_line.
+ // If the num_lines option was specified, dont print more than num_lines
+ // entries.
+ uint32_t DumpFileLinesInModule(Stream &strm, Module *module,
+ const FileSpec &file_spec) {
+ uint32_t num_matches = 0;
+ if (module) {
+ // Look through all the compilation units (CUs) in this module for ones
+ // that
+ // contain lines of code from this source file.
+ for (size_t i = 0; i < module->GetNumCompileUnits(); i++) {
+ // Look for a matching source file in this CU.
+ CompUnitSP cu_sp(module->GetCompileUnitAtIndex(i));
+ if (cu_sp) {
+ num_matches +=
+ DumpFileLinesInCompUnit(strm, module, cu_sp.get(), file_spec);
}
- else
- {
- // The target has some things loaded, resolve this address to a
- // compile unit + file + line and display
- if (target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
- {
- ModuleSP module_sp(so_addr.GetModule());
- // Check to make sure this module is in our list.
- if (module_sp &&
- module_list.GetIndexForModule(module_sp.get()) != LLDB_INVALID_INDEX32)
- {
- SymbolContext sc;
- sc.Clear(true);
- if (module_sp->ResolveSymbolContextForAddress(so_addr, eSymbolContextEverything, sc) &
- eSymbolContextLineEntry)
- {
- sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/false);
- ++num_matches;
- }
- else
- {
- StreamString addr_strm;
- so_addr.Dump(&addr_strm, nullptr, Address::DumpStyleModuleWithFileAddress);
- error_strm.Printf("Address 0x%" PRIx64 " resolves to %s, but there is"
- " no source information available for this address.\n",
- addr, addr_strm.GetData());
- }
- }
- else
- {
- StreamString addr_strm;
- so_addr.Dump(&addr_strm, nullptr, Address::DumpStyleModuleWithFileAddress);
- error_strm.Printf("Address 0x%" PRIx64 " resolves to %s, but it cannot"
- " be found in any modules.\n",
- addr, addr_strm.GetData());
- }
- }
- else
- error_strm.Printf("Unable to resolve address 0x%" PRIx64 ".\n", addr);
- }
- return num_matches;
+ }
}
-
- // Dump the line entries found in functions matching the name specified in the option.
- bool
- DumpLinesInFunctions (CommandReturnObject &result)
- {
- SymbolContextList sc_list_funcs;
- ConstString name(m_options.symbol_name.c_str());
- SymbolContextList sc_list_lines;
- Target *target = m_exe_ctx.GetTargetPtr();
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
-
- // Note: module_list can't be const& because FindFunctionSymbols isn't const.
- ModuleList module_list = (m_module_list.GetSize() > 0) ?
- m_module_list : target->GetImages();
- size_t num_matches = module_list.FindFunctions(name,
- eFunctionNameTypeAuto,
- /*include_symbols=*/false,
- /*include_inlines=*/true,
- /*append=*/true,
- sc_list_funcs);
- if (!num_matches)
- {
- // If we didn't find any functions with that name, try searching for
- // symbols that line up exactly with function addresses.
- SymbolContextList sc_list_symbols;
- size_t num_symbol_matches = module_list.FindFunctionSymbols(name,
- eFunctionNameTypeAuto,
- sc_list_symbols);
- for (size_t i = 0; i < num_symbol_matches; i++)
- {
- SymbolContext sc;
- sc_list_symbols.GetContextAtIndex(i, sc);
- if (sc.symbol && sc.symbol->ValueIsAddress())
- {
- const Address &base_address = sc.symbol->GetAddressRef();
- Function *function = base_address.CalculateSymbolContextFunction();
- if (function)
- {
- sc_list_funcs.Append(SymbolContext(function));
- num_matches++;
- }
- }
- }
+ return num_matches;
+ }
+
+ // Given an address and a list of modules, append the symbol contexts of all
+ // line entries
+ // containing the address found in the modules and return the count of
+ // matches. If none
+ // is found, return an error in 'error_strm'.
+ size_t GetSymbolContextsForAddress(const ModuleList &module_list,
+ lldb::addr_t addr,
+ SymbolContextList &sc_list,
+ StreamString &error_strm) {
+ Address so_addr;
+ size_t num_matches = 0;
+ assert(module_list.GetSize() > 0);
+ Target *target = m_exe_ctx.GetTargetPtr();
+ if (target->GetSectionLoadList().IsEmpty()) {
+ // The target isn't loaded yet, we need to lookup the file address in
+ // all modules. Note: the module list option does not apply to addresses.
+ const size_t num_modules = module_list.GetSize();
+ for (size_t i = 0; i < num_modules; ++i) {
+ ModuleSP module_sp(module_list.GetModuleAtIndex(i));
+ if (!module_sp)
+ continue;
+ if (module_sp->ResolveFileAddress(addr, so_addr)) {
+ SymbolContext sc;
+ sc.Clear(true);
+ if (module_sp->ResolveSymbolContextForAddress(
+ so_addr, eSymbolContextEverything, sc) &
+ eSymbolContextLineEntry) {
+ sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/false);
+ ++num_matches;
+ }
}
- if (num_matches == 0)
- {
- result.AppendErrorWithFormat("Could not find function named \'%s\'.\n",
- m_options.symbol_name.c_str());
- return false;
+ }
+ if (num_matches == 0)
+ error_strm.Printf("Source information for file address 0x%" PRIx64
+ " not found in any modules.\n",
+ addr);
+ } else {
+ // The target has some things loaded, resolve this address to a
+ // compile unit + file + line and display
+ if (target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
+ ModuleSP module_sp(so_addr.GetModule());
+ // Check to make sure this module is in our list.
+ if (module_sp &&
+ module_list.GetIndexForModule(module_sp.get()) !=
+ LLDB_INVALID_INDEX32) {
+ SymbolContext sc;
+ sc.Clear(true);
+ if (module_sp->ResolveSymbolContextForAddress(
+ so_addr, eSymbolContextEverything, sc) &
+ eSymbolContextLineEntry) {
+ sc_list.AppendIfUnique(sc, /*merge_symbol_into_function=*/false);
+ ++num_matches;
+ } else {
+ StreamString addr_strm;
+ so_addr.Dump(&addr_strm, nullptr,
+ Address::DumpStyleModuleWithFileAddress);
+ error_strm.Printf(
+ "Address 0x%" PRIx64 " resolves to %s, but there is"
+ " no source information available for this address.\n",
+ addr, addr_strm.GetData());
+ }
+ } else {
+ StreamString addr_strm;
+ so_addr.Dump(&addr_strm, nullptr,
+ Address::DumpStyleModuleWithFileAddress);
+ error_strm.Printf("Address 0x%" PRIx64
+ " resolves to %s, but it cannot"
+ " be found in any modules.\n",
+ addr, addr_strm.GetData());
}
- for (size_t i = 0; i < num_matches; i++)
- {
- SymbolContext sc;
- sc_list_funcs.GetContextAtIndex(i, sc);
- bool context_found_for_symbol = false;
- // Loop through all the ranges in the function.
- AddressRange range;
- for (uint32_t r = 0;
- sc.GetAddressRange(eSymbolContextEverything,
- r,
- /*use_inline_block_range=*/true,
- range);
- ++r)
- {
- // Append the symbol contexts for each address in the range to sc_list_lines.
- const Address &base_address = range.GetBaseAddress();
- const addr_t size = range.GetByteSize();
- lldb::addr_t start_addr = base_address.GetLoadAddress(target);
- if (start_addr == LLDB_INVALID_ADDRESS)
- start_addr = base_address.GetFileAddress();
- lldb::addr_t end_addr = start_addr + size;
- for (lldb::addr_t addr = start_addr; addr < end_addr; addr += addr_byte_size)
- {
- StreamString error_strm;
- if (!GetSymbolContextsForAddress(module_list, addr, sc_list_lines, error_strm))
- result.AppendWarningWithFormat("in symbol '%s': %s",
- sc.GetFunctionName().AsCString(),
- error_strm.GetData());
- else
- context_found_for_symbol = true;
- }
- }
- if (!context_found_for_symbol)
- result.AppendWarningWithFormat("Unable to find line information"
- " for matching symbol '%s'.\n",
- sc.GetFunctionName().AsCString());
- }
- if (sc_list_lines.GetSize() == 0)
- {
- result.AppendErrorWithFormat("No line information could be found"
- " for any symbols matching '%s'.\n",
- name.AsCString());
- return false;
- }
- FileSpec file_spec;
- if (!DumpLinesInSymbolContexts(result.GetOutputStream(),
- sc_list_lines, module_list, file_spec))
- {
- result.AppendErrorWithFormat("Unable to dump line information for symbol '%s'.\n",
- name.AsCString());
- return false;
- }
- return true;
+ } else
+ error_strm.Printf("Unable to resolve address 0x%" PRIx64 ".\n", addr);
}
-
- // Dump the line entries found for the address specified in the option.
- bool
- DumpLinesForAddress (CommandReturnObject &result)
- {
- Target *target = m_exe_ctx.GetTargetPtr();
- SymbolContextList sc_list;
-
- StreamString error_strm;
- if (!GetSymbolContextsForAddress(target->GetImages(), m_options.address, sc_list, error_strm))
- {
- result.AppendErrorWithFormat("%s.\n", error_strm.GetData());
- return false;
- }
- ModuleList module_list;
- FileSpec file_spec;
- if (!DumpLinesInSymbolContexts(result.GetOutputStream(),
- sc_list, module_list, file_spec))
- {
- result.AppendErrorWithFormat("No modules contain load address 0x%" PRIx64 ".\n",
- m_options.address);
- return false;
+ return num_matches;
+ }
+
+ // Dump the line entries found in functions matching the name specified in the
+ // option.
+ bool DumpLinesInFunctions(CommandReturnObject &result) {
+ SymbolContextList sc_list_funcs;
+ ConstString name(m_options.symbol_name.c_str());
+ SymbolContextList sc_list_lines;
+ Target *target = m_exe_ctx.GetTargetPtr();
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+
+ // Note: module_list can't be const& because FindFunctionSymbols isn't
+ // const.
+ ModuleList module_list =
+ (m_module_list.GetSize() > 0) ? m_module_list : target->GetImages();
+ size_t num_matches =
+ module_list.FindFunctions(name, eFunctionNameTypeAuto,
+ /*include_symbols=*/false,
+ /*include_inlines=*/true,
+ /*append=*/true, sc_list_funcs);
+ if (!num_matches) {
+ // If we didn't find any functions with that name, try searching for
+ // symbols that line up exactly with function addresses.
+ SymbolContextList sc_list_symbols;
+ size_t num_symbol_matches = module_list.FindFunctionSymbols(
+ name, eFunctionNameTypeAuto, sc_list_symbols);
+ for (size_t i = 0; i < num_symbol_matches; i++) {
+ SymbolContext sc;
+ sc_list_symbols.GetContextAtIndex(i, sc);
+ if (sc.symbol && sc.symbol->ValueIsAddress()) {
+ const Address &base_address = sc.symbol->GetAddressRef();
+ Function *function = base_address.CalculateSymbolContextFunction();
+ if (function) {
+ sc_list_funcs.Append(SymbolContext(function));
+ num_matches++;
+ }
}
- return true;
+ }
}
-
- // Dump the line entries found in the file specified in the option.
- bool
- DumpLinesForFile (CommandReturnObject &result)
- {
- FileSpec file_spec(m_options.file_name, false);
- const char *filename = m_options.file_name.c_str();
- Target *target = m_exe_ctx.GetTargetPtr();
- const ModuleList &module_list = (m_module_list.GetSize() > 0) ?
- m_module_list : target->GetImages();
-
- bool displayed_something = false;
- const size_t num_modules = module_list.GetSize();
- for (uint32_t i = 0; i < num_modules; ++i)
- {
- // Dump lines for this module.
- Module *module = module_list.GetModulePointerAtIndex(i);
- assert(module);
- if (DumpFileLinesInModule(result.GetOutputStream(), module, file_spec))
- displayed_something = true;
- }
- if (!displayed_something)
- {
- result.AppendErrorWithFormat("No source filenames matched '%s'.\n", filename);
- return false;
- }
- return true;
+ if (num_matches == 0) {
+ result.AppendErrorWithFormat("Could not find function named \'%s\'.\n",
+ m_options.symbol_name.c_str());
+ return false;
}
-
- // Dump the line entries for the current frame.
- bool
- DumpLinesForFrame (CommandReturnObject &result)
- {
- StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
- if (cur_frame == nullptr)
- {
- result.AppendError("No selected frame to use to find the default source.");
- return false;
- }
- else if (!cur_frame->HasDebugInformation())
- {
- result.AppendError("No debug info for the selected frame.");
- return false;
- }
- else
- {
- const SymbolContext &sc = cur_frame->GetSymbolContext(eSymbolContextLineEntry);
- SymbolContextList sc_list;
- sc_list.Append(sc);
- ModuleList module_list;
- FileSpec file_spec;
- if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list, module_list, file_spec))
- {
- result.AppendError("No source line info available for the selected frame.");
- return false;
- }
+ for (size_t i = 0; i < num_matches; i++) {
+ SymbolContext sc;
+ sc_list_funcs.GetContextAtIndex(i, sc);
+ bool context_found_for_symbol = false;
+ // Loop through all the ranges in the function.
+ AddressRange range;
+ for (uint32_t r = 0;
+ sc.GetAddressRange(eSymbolContextEverything, r,
+ /*use_inline_block_range=*/true, range);
+ ++r) {
+ // Append the symbol contexts for each address in the range to
+ // sc_list_lines.
+ const Address &base_address = range.GetBaseAddress();
+ const addr_t size = range.GetByteSize();
+ lldb::addr_t start_addr = base_address.GetLoadAddress(target);
+ if (start_addr == LLDB_INVALID_ADDRESS)
+ start_addr = base_address.GetFileAddress();
+ lldb::addr_t end_addr = start_addr + size;
+ for (lldb::addr_t addr = start_addr; addr < end_addr;
+ addr += addr_byte_size) {
+ StreamString error_strm;
+ if (!GetSymbolContextsForAddress(module_list, addr, sc_list_lines,
+ error_strm))
+ result.AppendWarningWithFormat("in symbol '%s': %s",
+ sc.GetFunctionName().AsCString(),
+ error_strm.GetData());
+ else
+ context_found_for_symbol = true;
}
- return true;
+ }
+ if (!context_found_for_symbol)
+ result.AppendWarningWithFormat("Unable to find line information"
+ " for matching symbol '%s'.\n",
+ sc.GetFunctionName().AsCString());
+ }
+ if (sc_list_lines.GetSize() == 0) {
+ result.AppendErrorWithFormat("No line information could be found"
+ " for any symbols matching '%s'.\n",
+ name.AsCString());
+ return false;
+ }
+ FileSpec file_spec;
+ if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list_lines,
+ module_list, file_spec)) {
+ result.AppendErrorWithFormat(
+ "Unable to dump line information for symbol '%s'.\n",
+ name.AsCString());
+ return false;
+ }
+ return true;
+ }
+
+ // Dump the line entries found for the address specified in the option.
+ bool DumpLinesForAddress(CommandReturnObject &result) {
+ Target *target = m_exe_ctx.GetTargetPtr();
+ SymbolContextList sc_list;
+
+ StreamString error_strm;
+ if (!GetSymbolContextsForAddress(target->GetImages(), m_options.address,
+ sc_list, error_strm)) {
+ result.AppendErrorWithFormat("%s.\n", error_strm.GetData());
+ return false;
+ }
+ ModuleList module_list;
+ FileSpec file_spec;
+ if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list,
+ module_list, file_spec)) {
+ result.AppendErrorWithFormat("No modules contain load address 0x%" PRIx64
+ ".\n",
+ m_options.address);
+ return false;
}
+ return true;
+ }
+
+ // Dump the line entries found in the file specified in the option.
+ bool DumpLinesForFile(CommandReturnObject &result) {
+ FileSpec file_spec(m_options.file_name, false);
+ const char *filename = m_options.file_name.c_str();
+ Target *target = m_exe_ctx.GetTargetPtr();
+ const ModuleList &module_list =
+ (m_module_list.GetSize() > 0) ? m_module_list : target->GetImages();
+
+ bool displayed_something = false;
+ const size_t num_modules = module_list.GetSize();
+ for (uint32_t i = 0; i < num_modules; ++i) {
+ // Dump lines for this module.
+ Module *module = module_list.GetModulePointerAtIndex(i);
+ assert(module);
+ if (DumpFileLinesInModule(result.GetOutputStream(), module, file_spec))
+ displayed_something = true;
+ }
+ if (!displayed_something) {
+ result.AppendErrorWithFormat("No source filenames matched '%s'.\n",
+ filename);
+ return false;
+ }
+ return true;
+ }
+
+ // Dump the line entries for the current frame.
+ bool DumpLinesForFrame(CommandReturnObject &result) {
+ StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
+ if (cur_frame == nullptr) {
+ result.AppendError(
+ "No selected frame to use to find the default source.");
+ return false;
+ } else if (!cur_frame->HasDebugInformation()) {
+ result.AppendError("No debug info for the selected frame.");
+ return false;
+ } else {
+ const SymbolContext &sc =
+ cur_frame->GetSymbolContext(eSymbolContextLineEntry);
+ SymbolContextList sc_list;
+ sc_list.Append(sc);
+ ModuleList module_list;
+ FileSpec file_spec;
+ if (!DumpLinesInSymbolContexts(result.GetOutputStream(), sc_list,
+ module_list, file_spec)) {
+ result.AppendError(
+ "No source line info available for the selected frame.");
+ return false;
+ }
+ }
+ return true;
+ }
- bool
- DoExecute (Args &command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- if (argc != 0)
- {
- result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n",
- GetCommandName());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
- Target *target = m_exe_ctx.GetTargetPtr();
- if (target == nullptr)
- {
- target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError("invalid target, create a debug target using the "
- "'target create' command.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
+ if (argc != 0) {
+ result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n",
+ GetCommandName().str().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
-
- // Collect the list of modules to search.
- m_module_list.Clear();
- if (!m_options.modules.empty())
- {
- for (size_t i = 0, e = m_options.modules.size(); i < e; ++i)
- {
- FileSpec module_file_spec(m_options.modules[i].c_str(), false);
- if (module_file_spec)
- {
- ModuleSpec module_spec(module_file_spec);
- if (target->GetImages().FindModules(module_spec, m_module_list) == 0)
- result.AppendWarningWithFormat("No module found for '%s'.\n",
- m_options.modules[i].c_str());
- }
- }
- if (!m_module_list.GetSize())
- {
- result.AppendError("No modules match the input.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- else if (target->GetImages().GetSize() == 0)
- {
- result.AppendError("The target has no associated executable images.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Target *target = m_exe_ctx.GetTargetPtr();
+ if (target == nullptr) {
+ target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
- // Check the arguments to see what lines we should dump.
- if (!m_options.symbol_name.empty())
- {
- // Print lines for symbol.
- if (DumpLinesInFunctions(result))
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else
- result.SetStatus(eReturnStatusFailed);
- }
- else if (m_options.address != LLDB_INVALID_ADDRESS)
- {
- // Print lines for an address.
- if (DumpLinesForAddress(result))
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else
- result.SetStatus(eReturnStatusFailed);
- }
- else if (!m_options.file_name.empty())
- {
- // Dump lines for a file.
- if (DumpLinesForFile(result))
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else
- result.SetStatus(eReturnStatusFailed);
- }
- else
- {
- // Dump the line for the current frame.
- if (DumpLinesForFrame(result))
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else
- result.SetStatus(eReturnStatusFailed);
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+
+ // Collect the list of modules to search.
+ m_module_list.Clear();
+ if (!m_options.modules.empty()) {
+ for (size_t i = 0, e = m_options.modules.size(); i < e; ++i) {
+ FileSpec module_file_spec(m_options.modules[i], false);
+ if (module_file_spec) {
+ ModuleSpec module_spec(module_file_spec);
+ if (target->GetImages().FindModules(module_spec, m_module_list) == 0)
+ result.AppendWarningWithFormat("No module found for '%s'.\n",
+ m_options.modules[i].c_str());
}
- return result.Succeeded();
+ }
+ if (!m_module_list.GetSize()) {
+ result.AppendError("No modules match the input.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else if (target->GetImages().GetSize() == 0) {
+ result.AppendError("The target has no associated executable images.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- CommandOptions m_options;
- ModuleList m_module_list;
-};
+ // Check the arguments to see what lines we should dump.
+ if (!m_options.symbol_name.empty()) {
+ // Print lines for symbol.
+ if (DumpLinesInFunctions(result))
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
+ } else if (m_options.address != LLDB_INVALID_ADDRESS) {
+ // Print lines for an address.
+ if (DumpLinesForAddress(result))
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
+ } else if (!m_options.file_name.empty()) {
+ // Dump lines for a file.
+ if (DumpLinesForFile(result))
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ // Dump the line for the current frame.
+ if (DumpLinesForFrame(result))
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
-OptionDefinition CommandObjectSourceInfo::CommandOptions::g_option_table[] = {
- {LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,
- "The number of line entries to display."},
- {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr,
- CommandCompletions::eModuleCompletion, eArgTypeShlibName,
- "Look up the source in the given module or shared library (can be "
- "specified more than once)."},
- {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr,
- CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
- {LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
- "The line number at which to start the displaying lines."},
- {LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
- "The line number at which to stop displaying lines."},
- {LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr,
- CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."},
- {LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
- "Lookup the address and display the source information for the "
- "corresponding file and line."},
- {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
+ CommandOptions m_options;
+ ModuleList m_module_list;
};
#pragma mark CommandObjectSourceList
@@ -723,754 +663,650 @@ OptionDefinition CommandObjectSourceInfo::CommandOptions::g_option_table[] = {
// CommandObjectSourceList
//-------------------------------------------------------------------------
-class CommandObjectSourceList : public CommandObjectParsed
-{
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- }
+static OptionDefinition g_source_list_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "The number of source lines to display." },
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library." },
+ { LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints." },
+ { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." },
+ { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "The line number at which to start the display source." },
+ { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." },
+ { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." },
+ { LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source." },
+ // clang-format on
+};
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = g_option_table[option_idx].short_option;
- switch (short_option)
- {
- case 'l':
- start_line = StringConvert::ToUInt32 (option_arg, 0);
- if (start_line == 0)
- error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg);
- break;
-
- case 'c':
- num_lines = StringConvert::ToUInt32 (option_arg, 0);
- if (num_lines == 0)
- error.SetErrorStringWithFormat("invalid line count: '%s'", option_arg);
- break;
-
- case 'f':
- file_name = option_arg;
- break;
-
- case 'n':
- symbol_name = option_arg;
- break;
-
- case 'a':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- address = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- }
- break;
- case 's':
- modules.push_back (std::string (option_arg));
- break;
-
- case 'b':
- show_bp_locs = true;
- break;
- case 'r':
- reverse = true;
- break;
- default:
- error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
- break;
- }
+class CommandObjectSourceList : public CommandObjectParsed {
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = GetDefinitions()[option_idx].short_option;
+ switch (short_option) {
+ case 'l':
+ if (option_arg.getAsInteger(0, start_line))
+ error.SetErrorStringWithFormat("invalid line number: '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'c':
+ if (option_arg.getAsInteger(0, num_lines))
+ error.SetErrorStringWithFormat("invalid line count: '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'f':
+ file_name = option_arg;
+ break;
+
+ case 'n':
+ symbol_name = option_arg;
+ break;
+
+ case 'a': {
+ address = Args::StringToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
+ } break;
+ case 's':
+ modules.push_back(std::string(option_arg));
+ break;
+
+ case 'b':
+ show_bp_locs = true;
+ break;
+ case 'r':
+ reverse = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
- return error;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ file_spec.Clear();
+ file_name.clear();
+ symbol_name.clear();
+ address = LLDB_INVALID_ADDRESS;
+ start_line = 0;
+ num_lines = 0;
+ show_bp_locs = false;
+ reverse = false;
+ modules.clear();
+ }
- void
- OptionParsingStarting () override
- {
- file_spec.Clear();
- file_name.clear();
- symbol_name.clear();
- address = LLDB_INVALID_ADDRESS;
- start_line = 0;
- num_lines = 0;
- show_bp_locs = false;
- reverse = false;
- modules.clear();
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_source_list_options);
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ // Instance variables to hold the values for command options.
+ FileSpec file_spec;
+ std::string file_name;
+ std::string symbol_name;
+ lldb::addr_t address;
+ uint32_t start_line;
+ uint32_t num_lines;
+ STLStringArray modules;
+ bool show_bp_locs;
+ bool reverse;
+ };
- static OptionDefinition g_option_table[];
+public:
+ CommandObjectSourceList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "source list",
+ "Display source code for the current target "
+ "process as specified by options.",
+ nullptr, eCommandRequiresTarget),
+ m_options() {}
+
+ ~CommandObjectSourceList() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ const char *GetRepeatCommand(Args &current_command_args,
+ uint32_t index) override {
+ // This is kind of gross, but the command hasn't been parsed yet so we can't
+ // look at the option values for this invocation... I have to scan the
+ // arguments directly.
+ auto iter =
+ llvm::find_if(current_command_args, [](const Args::ArgEntry &e) {
+ return e.ref == "-r" || e.ref == "--reverse";
+ });
+ if (iter == current_command_args.end())
+ return m_cmd_name.c_str();
+
+ if (m_reverse_name.empty()) {
+ m_reverse_name = m_cmd_name;
+ m_reverse_name.append(" -r");
+ }
+ return m_reverse_name.c_str();
+ }
- // Instance variables to hold the values for command options.
- FileSpec file_spec;
- std::string file_name;
- std::string symbol_name;
- lldb::addr_t address;
- uint32_t start_line;
- uint32_t num_lines;
- STLStringArray modules;
- bool show_bp_locs;
- bool reverse;
- };
+protected:
+ struct SourceInfo {
+ ConstString function;
+ LineEntry line_entry;
-public:
- CommandObjectSourceList(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "source list",
- "Display source code for the current target process as specified by options.", nullptr,
- eCommandRequiresTarget),
- m_options(interpreter)
- {
+ SourceInfo(const ConstString &name, const LineEntry &line_entry)
+ : function(name), line_entry(line_entry) {}
+
+ SourceInfo() : function(), line_entry() {}
+
+ bool IsValid() const { return (bool)function && line_entry.IsValid(); }
+
+ bool operator==(const SourceInfo &rhs) const {
+ return function == rhs.function &&
+ line_entry.original_file == rhs.line_entry.original_file &&
+ line_entry.line == rhs.line_entry.line;
}
- ~CommandObjectSourceList() override = default;
+ bool operator!=(const SourceInfo &rhs) const {
+ return function != rhs.function ||
+ line_entry.original_file != rhs.line_entry.original_file ||
+ line_entry.line != rhs.line_entry.line;
+ }
- Options *
- GetOptions () override
- {
- return &m_options;
+ bool operator<(const SourceInfo &rhs) const {
+ if (function.GetCString() < rhs.function.GetCString())
+ return true;
+ if (line_entry.file.GetDirectory().GetCString() <
+ rhs.line_entry.file.GetDirectory().GetCString())
+ return true;
+ if (line_entry.file.GetFilename().GetCString() <
+ rhs.line_entry.file.GetFilename().GetCString())
+ return true;
+ if (line_entry.line < rhs.line_entry.line)
+ return true;
+ return false;
}
+ };
- const char *
- GetRepeatCommand (Args &current_command_args, uint32_t index) override
- {
- // This is kind of gross, but the command hasn't been parsed yet so we can't look at the option
- // values for this invocation... I have to scan the arguments directly.
- size_t num_args = current_command_args.GetArgumentCount();
- bool is_reverse = false;
- for (size_t i = 0; i < num_args; i++)
- {
- const char *arg = current_command_args.GetArgumentAtIndex(i);
- if (arg && (strcmp(arg, "-r") == 0 || strcmp(arg, "--reverse") == 0))
- {
- is_reverse = true;
- }
- }
- if (is_reverse)
- {
- if (m_reverse_name.empty())
- {
- m_reverse_name = m_cmd_name;
- m_reverse_name.append (" -r");
- }
- return m_reverse_name.c_str();
- }
- else
- return m_cmd_name.c_str();
+ size_t DisplayFunctionSource(const SymbolContext &sc, SourceInfo &source_info,
+ CommandReturnObject &result) {
+ if (!source_info.IsValid()) {
+ source_info.function = sc.GetFunctionName();
+ source_info.line_entry = sc.GetFunctionStartLineEntry();
}
-protected:
- struct SourceInfo
- {
- ConstString function;
- LineEntry line_entry;
-
- SourceInfo (const ConstString &name, const LineEntry &line_entry) :
- function(name),
- line_entry(line_entry)
- {
- }
-
- SourceInfo () :
- function(),
- line_entry()
- {
+ if (sc.function) {
+ Target *target = m_exe_ctx.GetTargetPtr();
+
+ FileSpec start_file;
+ uint32_t start_line;
+ uint32_t end_line;
+ FileSpec end_file;
+
+ if (sc.block == nullptr) {
+ // Not an inlined function
+ sc.function->GetStartLineSourceInfo(start_file, start_line);
+ if (start_line == 0) {
+ result.AppendErrorWithFormat("Could not find line information for "
+ "start of function: \"%s\".\n",
+ source_info.function.GetCString());
+ result.SetStatus(eReturnStatusFailed);
+ return 0;
}
-
- bool
- IsValid () const
- {
- return (bool)function && line_entry.IsValid();
- }
-
- bool
- operator == (const SourceInfo &rhs) const
- {
- return function == rhs.function &&
- line_entry.original_file == rhs.line_entry.original_file &&
- line_entry.line == rhs.line_entry.line;
- }
-
- bool
- operator != (const SourceInfo &rhs) const
- {
- return function != rhs.function ||
- line_entry.original_file != rhs.line_entry.original_file ||
- line_entry.line != rhs.line_entry.line;
- }
-
- bool
- operator < (const SourceInfo &rhs) const
- {
- if (function.GetCString() < rhs.function.GetCString())
- return true;
- if (line_entry.file.GetDirectory().GetCString() < rhs.line_entry.file.GetDirectory().GetCString())
- return true;
- if (line_entry.file.GetFilename().GetCString() < rhs.line_entry.file.GetFilename().GetCString())
- return true;
- if (line_entry.line < rhs.line_entry.line)
- return true;
- return false;
+ sc.function->GetEndLineSourceInfo(end_file, end_line);
+ } else {
+ // We have an inlined function
+ start_file = source_info.line_entry.file;
+ start_line = source_info.line_entry.line;
+ end_line = start_line + m_options.num_lines;
+ }
+
+ // This is a little hacky, but the first line table entry for a function
+ // points to the "{" that
+ // starts the function block. It would be nice to actually get the
+ // function
+ // declaration in there too. So back up a bit, but not further than what
+ // you're going to display.
+ uint32_t extra_lines;
+ if (m_options.num_lines >= 10)
+ extra_lines = 5;
+ else
+ extra_lines = m_options.num_lines / 2;
+ uint32_t line_no;
+ if (start_line <= extra_lines)
+ line_no = 1;
+ else
+ line_no = start_line - extra_lines;
+
+ // For fun, if the function is shorter than the number of lines we're
+ // supposed to display,
+ // only display the function...
+ if (end_line != 0) {
+ if (m_options.num_lines > end_line - line_no)
+ m_options.num_lines = end_line - line_no + extra_lines;
+ }
+
+ m_breakpoint_locations.Clear();
+
+ if (m_options.show_bp_locs) {
+ const bool show_inlines = true;
+ m_breakpoint_locations.Reset(start_file, 0, show_inlines);
+ SearchFilterForUnconstrainedSearches target_search_filter(
+ m_exe_ctx.GetTargetSP());
+ target_search_filter.Search(m_breakpoint_locations);
+ }
+
+ result.AppendMessageWithFormat("File: %s\n",
+ start_file.GetPath().c_str());
+ // We don't care about the column here.
+ const uint32_t column = 0;
+ return target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
+ start_file, line_no, 0, m_options.num_lines, column, "",
+ &result.GetOutputStream(), GetBreakpointLocations());
+ } else {
+ result.AppendErrorWithFormat(
+ "Could not find function info for: \"%s\".\n",
+ m_options.symbol_name.c_str());
+ }
+ return 0;
+ }
+
+ // From Jim: The FindMatchingFunctions / FindMatchingFunctionSymbols functions
+ // "take a possibly empty vector of strings which are names of modules, and
+ // run the two search functions on the subset of the full module list that
+ // matches the strings in the input vector". If we wanted to put these
+ // somewhere,
+ // there should probably be a module-filter-list that can be passed to the
+ // various ModuleList::Find* calls, which would either be a vector of string
+ // names or a ModuleSpecList.
+ size_t FindMatchingFunctions(Target *target, const ConstString &name,
+ SymbolContextList &sc_list) {
+ // Displaying the source for a symbol:
+ bool include_inlines = true;
+ bool append = true;
+ bool include_symbols = false;
+ size_t num_matches = 0;
+
+ if (m_options.num_lines == 0)
+ m_options.num_lines = 10;
+
+ const size_t num_modules = m_options.modules.size();
+ if (num_modules > 0) {
+ ModuleList matching_modules;
+ for (size_t i = 0; i < num_modules; ++i) {
+ FileSpec module_file_spec(m_options.modules[i], false);
+ if (module_file_spec) {
+ ModuleSpec module_spec(module_file_spec);
+ matching_modules.Clear();
+ target->GetImages().FindModules(module_spec, matching_modules);
+ num_matches += matching_modules.FindFunctions(
+ name, eFunctionNameTypeAuto, include_symbols, include_inlines,
+ append, sc_list);
}
- };
-
- size_t
- DisplayFunctionSource (const SymbolContext &sc,
- SourceInfo &source_info,
- CommandReturnObject &result)
- {
- if (!source_info.IsValid())
- {
- source_info.function = sc.GetFunctionName();
- source_info.line_entry = sc.GetFunctionStartLineEntry();
+ }
+ } else {
+ num_matches = target->GetImages().FindFunctions(
+ name, eFunctionNameTypeAuto, include_symbols, include_inlines, append,
+ sc_list);
+ }
+ return num_matches;
+ }
+
+ size_t FindMatchingFunctionSymbols(Target *target, const ConstString &name,
+ SymbolContextList &sc_list) {
+ size_t num_matches = 0;
+ const size_t num_modules = m_options.modules.size();
+ if (num_modules > 0) {
+ ModuleList matching_modules;
+ for (size_t i = 0; i < num_modules; ++i) {
+ FileSpec module_file_spec(m_options.modules[i], false);
+ if (module_file_spec) {
+ ModuleSpec module_spec(module_file_spec);
+ matching_modules.Clear();
+ target->GetImages().FindModules(module_spec, matching_modules);
+ num_matches += matching_modules.FindFunctionSymbols(
+ name, eFunctionNameTypeAuto, sc_list);
}
-
- if (sc.function)
- {
- Target *target = m_exe_ctx.GetTargetPtr();
-
- FileSpec start_file;
- uint32_t start_line;
- uint32_t end_line;
- FileSpec end_file;
-
- if (sc.block == nullptr)
- {
- // Not an inlined function
- sc.function->GetStartLineSourceInfo (start_file, start_line);
- if (start_line == 0)
- {
- result.AppendErrorWithFormat("Could not find line information for start of function: \"%s\".\n", source_info.function.GetCString());
- result.SetStatus (eReturnStatusFailed);
- return 0;
- }
- sc.function->GetEndLineSourceInfo (end_file, end_line);
- }
- else
- {
- // We have an inlined function
- start_file = source_info.line_entry.file;
- start_line = source_info.line_entry.line;
- end_line = start_line + m_options.num_lines;
- }
+ }
+ } else {
+ num_matches = target->GetImages().FindFunctionSymbols(
+ name, eFunctionNameTypeAuto, sc_list);
+ }
+ return num_matches;
+ }
- // This is a little hacky, but the first line table entry for a function points to the "{" that
- // starts the function block. It would be nice to actually get the function
- // declaration in there too. So back up a bit, but not further than what you're going to display.
- uint32_t extra_lines;
- if (m_options.num_lines >= 10)
- extra_lines = 5;
- else
- extra_lines = m_options.num_lines/2;
- uint32_t line_no;
- if (start_line <= extra_lines)
- line_no = 1;
- else
- line_no = start_line - extra_lines;
-
- // For fun, if the function is shorter than the number of lines we're supposed to display,
- // only display the function...
- if (end_line != 0)
- {
- if (m_options.num_lines > end_line - line_no)
- m_options.num_lines = end_line - line_no + extra_lines;
- }
-
- m_breakpoint_locations.Clear();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
- if (m_options.show_bp_locs)
- {
- const bool show_inlines = true;
- m_breakpoint_locations.Reset (start_file, 0, show_inlines);
- SearchFilterForUnconstrainedSearches target_search_filter (m_exe_ctx.GetTargetSP());
- target_search_filter.Search (m_breakpoint_locations);
- }
-
- result.AppendMessageWithFormat("File: %s\n", start_file.GetPath().c_str());
- return target->GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file,
- line_no,
- 0,
- m_options.num_lines,
- "",
- &result.GetOutputStream(),
- GetBreakpointLocations ());
- }
- else
- {
- result.AppendErrorWithFormat("Could not find function info for: \"%s\".\n", m_options.symbol_name.c_str());
- }
- return 0;
+ if (argc != 0) {
+ result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n",
+ GetCommandName().str().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- // From Jim: The FindMatchingFunctions / FindMatchingFunctionSymbols functions
- // "take a possibly empty vector of strings which are names of modules, and
- // run the two search functions on the subset of the full module list that
- // matches the strings in the input vector". If we wanted to put these somewhere,
- // there should probably be a module-filter-list that can be passed to the
- // various ModuleList::Find* calls, which would either be a vector of string
- // names or a ModuleSpecList.
- size_t FindMatchingFunctions (Target *target, const ConstString &name, SymbolContextList& sc_list)
- {
- // Displaying the source for a symbol:
- bool include_inlines = true;
- bool append = true;
- bool include_symbols = false;
- size_t num_matches = 0;
-
- if (m_options.num_lines == 0)
- m_options.num_lines = 10;
-
- const size_t num_modules = m_options.modules.size();
- if (num_modules > 0)
- {
- ModuleList matching_modules;
- for (size_t i = 0; i < num_modules; ++i)
- {
- FileSpec module_file_spec(m_options.modules[i].c_str(), false);
- if (module_file_spec)
- {
- ModuleSpec module_spec (module_file_spec);
- matching_modules.Clear();
- target->GetImages().FindModules (module_spec, matching_modules);
- num_matches += matching_modules.FindFunctions (name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list);
- }
+ Target *target = m_exe_ctx.GetTargetPtr();
+
+ if (!m_options.symbol_name.empty()) {
+ SymbolContextList sc_list;
+ ConstString name(m_options.symbol_name.c_str());
+
+ // Displaying the source for a symbol. Search for function named name.
+ size_t num_matches = FindMatchingFunctions(target, name, sc_list);
+ if (!num_matches) {
+ // If we didn't find any functions with that name, try searching for
+ // symbols
+ // that line up exactly with function addresses.
+ SymbolContextList sc_list_symbols;
+ size_t num_symbol_matches =
+ FindMatchingFunctionSymbols(target, name, sc_list_symbols);
+ for (size_t i = 0; i < num_symbol_matches; i++) {
+ SymbolContext sc;
+ sc_list_symbols.GetContextAtIndex(i, sc);
+ if (sc.symbol && sc.symbol->ValueIsAddress()) {
+ const Address &base_address = sc.symbol->GetAddressRef();
+ Function *function = base_address.CalculateSymbolContextFunction();
+ if (function) {
+ sc_list.Append(SymbolContext(function));
+ num_matches++;
+ break;
}
+ }
}
- else
- {
- num_matches = target->GetImages().FindFunctions (name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list);
- }
- return num_matches;
- }
+ }
- size_t FindMatchingFunctionSymbols (Target *target, const ConstString &name, SymbolContextList& sc_list)
- {
- size_t num_matches = 0;
- const size_t num_modules = m_options.modules.size();
- if (num_modules > 0)
- {
- ModuleList matching_modules;
- for (size_t i = 0; i < num_modules; ++i)
- {
- FileSpec module_file_spec(m_options.modules[i].c_str(), false);
- if (module_file_spec)
- {
- ModuleSpec module_spec (module_file_spec);
- matching_modules.Clear();
- target->GetImages().FindModules (module_spec, matching_modules);
- num_matches += matching_modules.FindFunctionSymbols (name, eFunctionNameTypeAuto, sc_list);
- }
+ if (num_matches == 0) {
+ result.AppendErrorWithFormat("Could not find function named: \"%s\".\n",
+ m_options.symbol_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (num_matches > 1) {
+ std::set<SourceInfo> source_match_set;
+
+ bool displayed_something = false;
+ for (size_t i = 0; i < num_matches; i++) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(i, sc);
+ SourceInfo source_info(sc.GetFunctionName(),
+ sc.GetFunctionStartLineEntry());
+
+ if (source_info.IsValid()) {
+ if (source_match_set.find(source_info) == source_match_set.end()) {
+ source_match_set.insert(source_info);
+ if (DisplayFunctionSource(sc, source_info, result))
+ displayed_something = true;
}
+ }
}
+
+ if (displayed_something)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
else
- {
- num_matches = target->GetImages().FindFunctionSymbols (name, eFunctionNameTypeAuto, sc_list);
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ SourceInfo source_info;
+
+ if (DisplayFunctionSource(sc, source_info, result)) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.SetStatus(eReturnStatusFailed);
}
- return num_matches;
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- if (argc != 0)
- {
- result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", GetCommandName());
- result.SetStatus (eReturnStatusFailed);
- return false;
+ }
+ return result.Succeeded();
+ } else if (m_options.address != LLDB_INVALID_ADDRESS) {
+ Address so_addr;
+ StreamString error_strm;
+ SymbolContextList sc_list;
+
+ if (target->GetSectionLoadList().IsEmpty()) {
+ // The target isn't loaded yet, we need to lookup the file address
+ // in all modules
+ const ModuleList &module_list = target->GetImages();
+ const size_t num_modules = module_list.GetSize();
+ for (size_t i = 0; i < num_modules; ++i) {
+ ModuleSP module_sp(module_list.GetModuleAtIndex(i));
+ if (module_sp &&
+ module_sp->ResolveFileAddress(m_options.address, so_addr)) {
+ SymbolContext sc;
+ sc.Clear(true);
+ if (module_sp->ResolveSymbolContextForAddress(
+ so_addr, eSymbolContextEverything, sc) &
+ eSymbolContextLineEntry)
+ sc_list.Append(sc);
+ }
}
- Target *target = m_exe_ctx.GetTargetPtr();
-
- if (!m_options.symbol_name.empty())
- {
- SymbolContextList sc_list;
- ConstString name(m_options.symbol_name.c_str());
-
- // Displaying the source for a symbol. Search for function named name.
- size_t num_matches = FindMatchingFunctions (target, name, sc_list);
- if (!num_matches)
- {
- // If we didn't find any functions with that name, try searching for symbols
- // that line up exactly with function addresses.
- SymbolContextList sc_list_symbols;
- size_t num_symbol_matches = FindMatchingFunctionSymbols (target, name, sc_list_symbols);
- for (size_t i = 0; i < num_symbol_matches; i++)
- {
- SymbolContext sc;
- sc_list_symbols.GetContextAtIndex (i, sc);
- if (sc.symbol && sc.symbol->ValueIsAddress())
- {
- const Address &base_address = sc.symbol->GetAddressRef();
- Function *function = base_address.CalculateSymbolContextFunction();
- if (function)
- {
- sc_list.Append (SymbolContext(function));
- num_matches++;
- break;
- }
- }
- }
+ if (sc_list.GetSize() == 0) {
+ result.AppendErrorWithFormat(
+ "no modules have source information for file address 0x%" PRIx64
+ ".\n",
+ m_options.address);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ // The target has some things loaded, resolve this address to a
+ // compile unit + file + line and display
+ if (target->GetSectionLoadList().ResolveLoadAddress(m_options.address,
+ so_addr)) {
+ ModuleSP module_sp(so_addr.GetModule());
+ if (module_sp) {
+ SymbolContext sc;
+ sc.Clear(true);
+ if (module_sp->ResolveSymbolContextForAddress(
+ so_addr, eSymbolContextEverything, sc) &
+ eSymbolContextLineEntry) {
+ sc_list.Append(sc);
+ } else {
+ so_addr.Dump(&error_strm, nullptr,
+ Address::DumpStyleModuleWithFileAddress);
+ result.AppendErrorWithFormat("address resolves to %s, but there "
+ "is no line table information "
+ "available for this address.\n",
+ error_strm.GetData());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ }
+ }
- if (num_matches == 0)
- {
- result.AppendErrorWithFormat("Could not find function named: \"%s\".\n", m_options.symbol_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (sc_list.GetSize() == 0) {
+ result.AppendErrorWithFormat(
+ "no modules contain load address 0x%" PRIx64 ".\n",
+ m_options.address);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ uint32_t num_matches = sc_list.GetSize();
+ for (uint32_t i = 0; i < num_matches; ++i) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(i, sc);
+ if (sc.comp_unit) {
+ if (m_options.show_bp_locs) {
+ m_breakpoint_locations.Clear();
+ const bool show_inlines = true;
+ m_breakpoint_locations.Reset(*sc.comp_unit, 0, show_inlines);
+ SearchFilterForUnconstrainedSearches target_search_filter(
+ target->shared_from_this());
+ target_search_filter.Search(m_breakpoint_locations);
+ }
+
+ bool show_fullpaths = true;
+ bool show_module = true;
+ bool show_inlined_frames = true;
+ const bool show_function_arguments = true;
+ const bool show_function_name = true;
+ sc.DumpStopContext(&result.GetOutputStream(),
+ m_exe_ctx.GetBestExecutionContextScope(),
+ sc.line_entry.range.GetBaseAddress(),
+ show_fullpaths, show_module, show_inlined_frames,
+ show_function_arguments, show_function_name);
+ result.GetOutputStream().EOL();
+
+ if (m_options.num_lines == 0)
+ m_options.num_lines = 10;
- if (num_matches > 1)
- {
- std::set<SourceInfo> source_match_set;
-
- bool displayed_something = false;
- for (size_t i = 0; i < num_matches; i++)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (i, sc);
- SourceInfo source_info (sc.GetFunctionName(),
- sc.GetFunctionStartLineEntry());
-
- if (source_info.IsValid())
- {
- if (source_match_set.find(source_info) == source_match_set.end())
- {
- source_match_set.insert(source_info);
- if (DisplayFunctionSource (sc, source_info, result))
- displayed_something = true;
- }
- }
- }
-
- if (displayed_something)
- result.SetStatus (eReturnStatusSuccessFinishResult);
- else
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (0, sc);
- SourceInfo source_info;
-
- if (DisplayFunctionSource (sc, source_info, result))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.SetStatus (eReturnStatusFailed);
- }
- }
- return result.Succeeded();
+ size_t lines_to_back_up =
+ m_options.num_lines >= 10 ? 5 : m_options.num_lines / 2;
+
+ const uint32_t column =
+ (m_interpreter.GetDebugger().GetStopShowColumn() !=
+ eStopShowColumnNone)
+ ? sc.line_entry.column
+ : 0;
+ target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
+ sc.comp_unit, sc.line_entry.line, lines_to_back_up, column,
+ m_options.num_lines - lines_to_back_up, "->",
+ &result.GetOutputStream(), GetBreakpointLocations());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
}
- else if (m_options.address != LLDB_INVALID_ADDRESS)
- {
- Address so_addr;
- StreamString error_strm;
- SymbolContextList sc_list;
-
- if (target->GetSectionLoadList().IsEmpty())
- {
- // The target isn't loaded yet, we need to lookup the file address
- // in all modules
- const ModuleList &module_list = target->GetImages();
- const size_t num_modules = module_list.GetSize();
- for (size_t i = 0; i < num_modules; ++i)
- {
- ModuleSP module_sp (module_list.GetModuleAtIndex(i));
- if (module_sp && module_sp->ResolveFileAddress(m_options.address, so_addr))
- {
- SymbolContext sc;
- sc.Clear(true);
- if (module_sp->ResolveSymbolContextForAddress (so_addr, eSymbolContextEverything, sc) & eSymbolContextLineEntry)
- sc_list.Append(sc);
- }
- }
-
- if (sc_list.GetSize() == 0)
- {
- result.AppendErrorWithFormat("no modules have source information for file address 0x%" PRIx64 ".\n",
- m_options.address);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- // The target has some things loaded, resolve this address to a
- // compile unit + file + line and display
- if (target->GetSectionLoadList().ResolveLoadAddress (m_options.address, so_addr))
- {
- ModuleSP module_sp (so_addr.GetModule());
- if (module_sp)
- {
- SymbolContext sc;
- sc.Clear(true);
- if (module_sp->ResolveSymbolContextForAddress (so_addr, eSymbolContextEverything, sc) & eSymbolContextLineEntry)
- {
- sc_list.Append(sc);
- }
- else
- {
- so_addr.Dump(&error_strm, nullptr, Address::DumpStyleModuleWithFileAddress);
- result.AppendErrorWithFormat("address resolves to %s, but there is no line table information available for this address.\n",
- error_strm.GetData());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
-
- if (sc_list.GetSize() == 0)
- {
- result.AppendErrorWithFormat("no modules contain load address 0x%" PRIx64 ".\n", m_options.address);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- uint32_t num_matches = sc_list.GetSize();
- for (uint32_t i = 0; i < num_matches; ++i)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(i, sc);
- if (sc.comp_unit)
- {
- if (m_options.show_bp_locs)
- {
- m_breakpoint_locations.Clear();
- const bool show_inlines = true;
- m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines);
- SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this());
- target_search_filter.Search (m_breakpoint_locations);
- }
-
- bool show_fullpaths = true;
- bool show_module = true;
- bool show_inlined_frames = true;
- const bool show_function_arguments = true;
- const bool show_function_name = true;
- sc.DumpStopContext(&result.GetOutputStream(),
- m_exe_ctx.GetBestExecutionContextScope(),
- sc.line_entry.range.GetBaseAddress(),
- show_fullpaths,
- show_module,
- show_inlined_frames,
- show_function_arguments,
- show_function_name);
- result.GetOutputStream().EOL();
-
- if (m_options.num_lines == 0)
- m_options.num_lines = 10;
-
- size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2;
-
- target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
- sc.line_entry.line,
- lines_to_back_up,
- m_options.num_lines - lines_to_back_up,
- "->",
- &result.GetOutputStream(),
- GetBreakpointLocations ());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- }
+ }
+ } else if (m_options.file_name.empty()) {
+ // Last valid source manager context, or the current frame if no
+ // valid last context in source manager.
+ // One little trick here, if you type the exact same list command twice in
+ // a row, it is
+ // more likely because you typed it once, then typed it again
+ if (m_options.start_line == 0) {
+ if (target->GetSourceManager().DisplayMoreWithLineNumbers(
+ &result.GetOutputStream(), m_options.num_lines,
+ m_options.reverse, GetBreakpointLocations())) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
}
- else if (m_options.file_name.empty())
- {
- // Last valid source manager context, or the current frame if no
- // valid last context in source manager.
- // One little trick here, if you type the exact same list command twice in a row, it is
- // more likely because you typed it once, then typed it again
- if (m_options.start_line == 0)
- {
- if (target->GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream(),
- m_options.num_lines,
- m_options.reverse,
- GetBreakpointLocations ()))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- }
- else
- {
- if (m_options.num_lines == 0)
- m_options.num_lines = 10;
-
- if (m_options.show_bp_locs)
- {
- SourceManager::FileSP last_file_sp (target->GetSourceManager().GetLastFile ());
- if (last_file_sp)
- {
- const bool show_inlines = true;
- m_breakpoint_locations.Reset (last_file_sp->GetFileSpec(), 0, show_inlines);
- SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this());
- target_search_filter.Search (m_breakpoint_locations);
- }
- }
- else
- m_breakpoint_locations.Clear();
-
- if (target->GetSourceManager().DisplaySourceLinesWithLineNumbersUsingLastFile(
- m_options.start_line, // Line to display
- m_options.num_lines, // Lines after line to
- UINT32_MAX, // Don't mark "line"
- "", // Don't mark "line"
- &result.GetOutputStream(),
- GetBreakpointLocations ()))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- }
+ } else {
+ if (m_options.num_lines == 0)
+ m_options.num_lines = 10;
+
+ if (m_options.show_bp_locs) {
+ SourceManager::FileSP last_file_sp(
+ target->GetSourceManager().GetLastFile());
+ if (last_file_sp) {
+ const bool show_inlines = true;
+ m_breakpoint_locations.Reset(last_file_sp->GetFileSpec(), 0,
+ show_inlines);
+ SearchFilterForUnconstrainedSearches target_search_filter(
+ target->shared_from_this());
+ target_search_filter.Search(m_breakpoint_locations);
+ }
+ } else
+ m_breakpoint_locations.Clear();
+
+ const uint32_t column = 0;
+ if (target->GetSourceManager()
+ .DisplaySourceLinesWithLineNumbersUsingLastFile(
+ m_options.start_line, // Line to display
+ m_options.num_lines, // Lines after line to
+ UINT32_MAX, // Don't mark "line"
+ column,
+ "", // Don't mark "line"
+ &result.GetOutputStream(), GetBreakpointLocations())) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
}
- else
- {
- const char *filename = m_options.file_name.c_str();
-
- bool check_inlines = false;
- SymbolContextList sc_list;
- size_t num_matches = 0;
-
- if (!m_options.modules.empty())
- {
- ModuleList matching_modules;
- for (size_t i = 0, e = m_options.modules.size(); i < e; ++i)
- {
- FileSpec module_file_spec(m_options.modules[i].c_str(), false);
- if (module_file_spec)
- {
- ModuleSpec module_spec (module_file_spec);
- matching_modules.Clear();
- target->GetImages().FindModules (module_spec, matching_modules);
- num_matches += matching_modules.ResolveSymbolContextForFilePath (filename,
- 0,
- check_inlines,
- eSymbolContextModule | eSymbolContextCompUnit,
- sc_list);
- }
- }
- }
- else
- {
- num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename,
- 0,
- check_inlines,
- eSymbolContextModule | eSymbolContextCompUnit,
- sc_list);
- }
-
- if (num_matches == 0)
- {
- result.AppendErrorWithFormat("Could not find source file \"%s\".\n",
- m_options.file_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ }
+ } else {
+ const char *filename = m_options.file_name.c_str();
+
+ bool check_inlines = false;
+ SymbolContextList sc_list;
+ size_t num_matches = 0;
+
+ if (!m_options.modules.empty()) {
+ ModuleList matching_modules;
+ for (size_t i = 0, e = m_options.modules.size(); i < e; ++i) {
+ FileSpec module_file_spec(m_options.modules[i], false);
+ if (module_file_spec) {
+ ModuleSpec module_spec(module_file_spec);
+ matching_modules.Clear();
+ target->GetImages().FindModules(module_spec, matching_modules);
+ num_matches += matching_modules.ResolveSymbolContextForFilePath(
+ filename, 0, check_inlines,
+ eSymbolContextModule | eSymbolContextCompUnit, sc_list);
+ }
+ }
+ } else {
+ num_matches = target->GetImages().ResolveSymbolContextForFilePath(
+ filename, 0, check_inlines,
+ eSymbolContextModule | eSymbolContextCompUnit, sc_list);
+ }
+
+ if (num_matches == 0) {
+ result.AppendErrorWithFormat("Could not find source file \"%s\".\n",
+ m_options.file_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (num_matches > 1) {
+ bool got_multiple = false;
+ FileSpec *test_cu_spec = nullptr;
+
+ for (unsigned i = 0; i < num_matches; i++) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(i, sc);
+ if (sc.comp_unit) {
+ if (test_cu_spec) {
+ if (test_cu_spec != static_cast<FileSpec *>(sc.comp_unit))
+ got_multiple = true;
+ break;
+ } else
+ test_cu_spec = sc.comp_unit;
+ }
+ }
+ if (got_multiple) {
+ result.AppendErrorWithFormat(
+ "Multiple source files found matching: \"%s.\"\n",
+ m_options.file_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(0, sc)) {
+ if (sc.comp_unit) {
+ if (m_options.show_bp_locs) {
+ const bool show_inlines = true;
+ m_breakpoint_locations.Reset(*sc.comp_unit, 0, show_inlines);
+ SearchFilterForUnconstrainedSearches target_search_filter(
+ target->shared_from_this());
+ target_search_filter.Search(m_breakpoint_locations);
+ } else
+ m_breakpoint_locations.Clear();
- if (num_matches > 1)
- {
- bool got_multiple = false;
- FileSpec *test_cu_spec = nullptr;
-
- for (unsigned i = 0; i < num_matches; i++)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(i, sc);
- if (sc.comp_unit)
- {
- if (test_cu_spec)
- {
- if (test_cu_spec != static_cast<FileSpec *> (sc.comp_unit))
- got_multiple = true;
- break;
- }
- else
- test_cu_spec = sc.comp_unit;
- }
- }
- if (got_multiple)
- {
- result.AppendErrorWithFormat("Multiple source files found matching: \"%s.\"\n",
- m_options.file_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
-
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(0, sc))
- {
- if (sc.comp_unit)
- {
- if (m_options.show_bp_locs)
- {
- const bool show_inlines = true;
- m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines);
- SearchFilterForUnconstrainedSearches target_search_filter (target->shared_from_this());
- target_search_filter.Search (m_breakpoint_locations);
- }
- else
- m_breakpoint_locations.Clear();
-
- if (m_options.num_lines == 0)
- m_options.num_lines = 10;
-
- target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
- m_options.start_line,
- 0,
- m_options.num_lines,
- "",
- &result.GetOutputStream(),
- GetBreakpointLocations ());
-
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n",
- m_options.file_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
+ if (m_options.num_lines == 0)
+ m_options.num_lines = 10;
+ const uint32_t column = 0;
+ target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
+ sc.comp_unit, m_options.start_line, 0, m_options.num_lines,
+ column, "", &result.GetOutputStream(), GetBreakpointLocations());
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n",
+ m_options.file_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- return result.Succeeded();
- }
-
- const SymbolContextList *
- GetBreakpointLocations ()
- {
- if (m_breakpoint_locations.GetFileLineMatches().GetSize() > 0)
- return &m_breakpoint_locations.GetFileLineMatches();
- return nullptr;
+ }
}
-
- CommandOptions m_options;
- FileLineResolver m_breakpoint_locations;
- std::string m_reverse_name;
-};
-
-OptionDefinition
-CommandObjectSourceList::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "The number of source lines to display."},
-{ LLDB_OPT_SET_1 |
- LLDB_OPT_SET_2 , false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."},
-{ LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints."},
-{ LLDB_OPT_SET_1 , false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
-{ LLDB_OPT_SET_1 , false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "The line number at which to start the display source."},
-{ LLDB_OPT_SET_2 , false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."},
-{ LLDB_OPT_SET_3 , false, "address",'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line."},
-{ LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source."},
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ return result.Succeeded();
+ }
+
+ const SymbolContextList *GetBreakpointLocations() {
+ if (m_breakpoint_locations.GetFileLineMatches().GetSize() > 0)
+ return &m_breakpoint_locations.GetFileLineMatches();
+ return nullptr;
+ }
+
+ CommandOptions m_options;
+ FileLineResolver m_breakpoint_locations;
+ std::string m_reverse_name;
};
#pragma mark CommandObjectMultiwordSource
@@ -1478,14 +1314,17 @@ CommandObjectSourceList::CommandOptions::g_option_table[] =
// CommandObjectMultiwordSource
//-------------------------------------------------------------------------
-CommandObjectMultiwordSource::CommandObjectMultiwordSource(CommandInterpreter &interpreter)
- : CommandObjectMultiword(
- interpreter, "source",
- "Commands for examining source code described by debug information for the current target process.",
- "source <subcommand> [<subcommand-options>]")
-{
- LoadSubCommand ("info", CommandObjectSP (new CommandObjectSourceInfo (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectSourceList (interpreter)));
+CommandObjectMultiwordSource::CommandObjectMultiwordSource(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "source", "Commands for examining "
+ "source code described by "
+ "debug information for the "
+ "current target process.",
+ "source <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("info",
+ CommandObjectSP(new CommandObjectSourceInfo(interpreter)));
+ LoadSubCommand("list",
+ CommandObjectSP(new CommandObjectSourceList(interpreter)));
}
CommandObjectMultiwordSource::~CommandObjectMultiwordSource() = default;
diff --git a/source/Commands/CommandObjectSource.h b/source/Commands/CommandObjectSource.h
index 7ed08cdc9591..e81ac1961d26 100644
--- a/source/Commands/CommandObjectSource.h
+++ b/source/Commands/CommandObjectSource.h
@@ -1,4 +1,5 @@
-//===-- CommandObjectSource.h.h -----------------------------------*- C++ -*-===//
+//===-- CommandObjectSource.h.h -----------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,9 +15,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Core/STLUtils.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
-#include "lldb/Core/STLUtils.h"
namespace lldb_private {
@@ -24,13 +25,11 @@ namespace lldb_private {
// CommandObjectMultiwordSource
//-------------------------------------------------------------------------
-class CommandObjectMultiwordSource : public CommandObjectMultiword
-{
+class CommandObjectMultiwordSource : public CommandObjectMultiword {
public:
+ CommandObjectMultiwordSource(CommandInterpreter &interpreter);
- CommandObjectMultiwordSource (CommandInterpreter &interpreter);
-
- ~CommandObjectMultiwordSource() override;
+ ~CommandObjectMultiwordSource() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectSyntax.cpp b/source/Commands/CommandObjectSyntax.cpp
index c238bccfb5dd..2b83b1b8786b 100644
--- a/source/Commands/CommandObjectSyntax.cpp
+++ b/source/Commands/CommandObjectSyntax.cpp
@@ -14,10 +14,10 @@
#include "CommandObjectSyntax.h"
#include "CommandObjectHelp.h"
#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
using namespace lldb;
using namespace lldb_private;
@@ -26,97 +26,78 @@ using namespace lldb_private;
// CommandObjectSyntax
//-------------------------------------------------------------------------
-CommandObjectSyntax::CommandObjectSyntax (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "syntax",
- "Shows the correct syntax for a given debugger command.",
- "syntax <command>")
-{
- CommandArgumentEntry arg;
- CommandArgumentData command_arg;
+CommandObjectSyntax::CommandObjectSyntax(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "syntax",
+ "Shows the correct syntax for a given debugger command.",
+ "syntax <command>") {
+ CommandArgumentEntry arg;
+ CommandArgumentData command_arg;
- // Define the first (and only) variant of this arg.
- command_arg.arg_type = eArgTypeCommandName;
- command_arg.arg_repetition = eArgRepeatPlain;
+ // Define the first (and only) variant of this arg.
+ command_arg.arg_type = eArgTypeCommandName;
+ command_arg.arg_repetition = eArgRepeatPlain;
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (command_arg);
+ // There is only one variant this argument could be; put it into the argument
+ // entry.
+ arg.push_back(command_arg);
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
}
CommandObjectSyntax::~CommandObjectSyntax() = default;
-bool
-CommandObjectSyntax::DoExecute (Args& command, CommandReturnObject &result)
-{
- CommandObject::CommandMap::iterator pos;
- CommandObject *cmd_obj;
- const size_t argc = command.GetArgumentCount();
-
- if (argc > 0)
- {
- cmd_obj = m_interpreter.GetCommandObject (command.GetArgumentAtIndex(0));
- bool all_okay = true;
- for (size_t i = 1; i < argc; ++i)
- {
- std::string sub_command = command.GetArgumentAtIndex (i);
- if (!cmd_obj->IsMultiwordObject())
- {
- all_okay = false;
- break;
- }
- else
- {
- cmd_obj = cmd_obj->GetSubcommandObject(sub_command.c_str());
- if (!cmd_obj)
- {
- all_okay = false;
- break;
- }
- }
- }
-
- if (all_okay && (cmd_obj != nullptr))
- {
- Stream &output_strm = result.GetOutputStream();
- if (cmd_obj->GetOptions() != nullptr)
- {
- output_strm.Printf ("\nSyntax: %s\n", cmd_obj->GetSyntax());
- output_strm.Printf ("(Try 'help %s' for more information on command options syntax.)\n",
- cmd_obj->GetCommandName());
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- output_strm.Printf ("\nSyntax: %s\n", cmd_obj->GetSyntax());
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- }
- else
- {
- std::string cmd_string;
- command.GetCommandString (cmd_string);
-
- StreamString error_msg_stream;
- const bool generate_apropos = true;
- const bool generate_type_lookup = false;
- CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
- cmd_string.c_str(),
- nullptr,
- nullptr,
- generate_apropos,
- generate_type_lookup);
- result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("Must call 'syntax' with a valid command.");
- result.SetStatus (eReturnStatusFailed);
- }
-
- return result.Succeeded();
+bool CommandObjectSyntax::DoExecute(Args &command,
+ CommandReturnObject &result) {
+ CommandObject::CommandMap::iterator pos;
+ CommandObject *cmd_obj;
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc == 0) {
+ result.AppendError("Must call 'syntax' with a valid command.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ cmd_obj = m_interpreter.GetCommandObject(command[0].ref);
+ bool all_okay = llvm::all_of(
+ command.entries().drop_front(), [&cmd_obj](const Args::ArgEntry &e) {
+ if (!cmd_obj || !cmd_obj->IsMultiwordObject())
+ return false;
+
+ if (!(cmd_obj = cmd_obj->GetSubcommandObject(e.ref)))
+ return false;
+
+ return true;
+ });
+
+ if (!all_okay) {
+ std::string cmd_string;
+ command.GetCommandString(cmd_string);
+
+ StreamString error_msg_stream;
+ const bool generate_apropos = true;
+ const bool generate_type_lookup = false;
+ CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(
+ &error_msg_stream, cmd_string, "", "", generate_apropos,
+ generate_type_lookup);
+ result.AppendErrorWithFormat("%s", error_msg_stream.GetData());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Stream &output_strm = result.GetOutputStream();
+ if (cmd_obj->GetOptions() != nullptr) {
+ output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax().str().c_str());
+ output_strm.Printf(
+ "(Try 'help %s' for more information on command options syntax.)\n",
+ cmd_obj->GetCommandName().str().c_str());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ output_strm.Printf("\nSyntax: %s\n", cmd_obj->GetSyntax().str().c_str());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+
+ return result.Succeeded();
}
diff --git a/source/Commands/CommandObjectSyntax.h b/source/Commands/CommandObjectSyntax.h
index 1a3e4e04f01a..b65e9b1b750b 100644
--- a/source/Commands/CommandObjectSyntax.h
+++ b/source/Commands/CommandObjectSyntax.h
@@ -22,18 +22,14 @@ namespace lldb_private {
// CommandObjectSyntax
//-------------------------------------------------------------------------
-class CommandObjectSyntax : public CommandObjectParsed
-{
+class CommandObjectSyntax : public CommandObjectParsed {
public:
+ CommandObjectSyntax(CommandInterpreter &interpreter);
- CommandObjectSyntax (CommandInterpreter &interpreter);
+ ~CommandObjectSyntax() override;
- ~CommandObjectSyntax() override;
-
protected:
- bool
- DoExecute(Args& command,
- CommandReturnObject &result) override;
+ bool DoExecute(Args &command, CommandReturnObject &result) override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index 9e535ba8ebd8..d2e53aa4a14f 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -9,13 +9,7 @@
#include "CommandObjectTarget.h"
-// C Includes
-// C++ Includes
-#include <cerrno>
-
-// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Core/Module.h"
@@ -27,19 +21,20 @@
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/Symbols.h"
+#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionGroupArchitecture.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupFile.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
-#include "lldb/Interpreter/OptionGroupVariable.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
+#include "lldb/Interpreter/OptionGroupString.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionGroupUUID.h"
-#include "lldb/Interpreter/OptionGroupString.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
+#include "lldb/Interpreter/OptionGroupVariable.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/LineTable.h"
@@ -55,92 +50,105 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
+// C Includes
+// C++ Includes
+#include <cerrno>
+
using namespace lldb;
using namespace lldb_private;
-static void
-DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
-{
- const ArchSpec &target_arch = target->GetArchitecture();
-
- Module *exe_module = target->GetExecutableModulePointer();
- char exe_path[PATH_MAX];
- bool exe_valid = false;
- if (exe_module)
- exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
-
- if (!exe_valid)
- ::strcpy (exe_path, "<none>");
-
- strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
-
- uint32_t properties = 0;
- if (target_arch.IsValid())
- {
- strm.Printf ("%sarch=", properties++ > 0 ? ", " : " ( ");
- target_arch.DumpTriple (strm);
- properties++;
- }
- PlatformSP platform_sp (target->GetPlatform());
- if (platform_sp)
- strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName().GetCString());
-
- ProcessSP process_sp (target->GetProcessSP());
- bool show_process_status = false;
- if (process_sp)
- {
- lldb::pid_t pid = process_sp->GetID();
- StateType state = process_sp->GetState();
- if (show_stopped_process_status)
- show_process_status = StateIsStoppedState(state, true);
- const char *state_cstr = StateAsCString (state);
- if (pid != LLDB_INVALID_PROCESS_ID)
- strm.Printf ("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
- strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
- }
- if (properties > 0)
- strm.PutCString (" )\n");
- else
- strm.EOL();
- if (show_process_status)
- {
- const bool only_threads_with_stop_reason = true;
- const uint32_t start_frame = 0;
- const uint32_t num_frames = 1;
- const uint32_t num_frames_with_source = 1;
- process_sp->GetStatus (strm);
- process_sp->GetThreadStatus (strm,
- only_threads_with_stop_reason,
- start_frame,
- num_frames,
- num_frames_with_source);
+static void DumpTargetInfo(uint32_t target_idx, Target *target,
+ const char *prefix_cstr,
+ bool show_stopped_process_status, Stream &strm) {
+ const ArchSpec &target_arch = target->GetArchitecture();
+
+ Module *exe_module = target->GetExecutableModulePointer();
+ char exe_path[PATH_MAX];
+ bool exe_valid = false;
+ if (exe_module)
+ exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
+
+ if (!exe_valid)
+ ::strcpy(exe_path, "<none>");
+
+ strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
+ exe_path);
+
+ uint32_t properties = 0;
+ if (target_arch.IsValid()) {
+ strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
+ target_arch.DumpTriple(strm);
+ properties++;
+ }
+ PlatformSP platform_sp(target->GetPlatform());
+ if (platform_sp)
+ strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
+ platform_sp->GetName().GetCString());
+
+ ProcessSP process_sp(target->GetProcessSP());
+ bool show_process_status = false;
+ if (process_sp) {
+ lldb::pid_t pid = process_sp->GetID();
+ StateType state = process_sp->GetState();
+ if (show_stopped_process_status)
+ show_process_status = StateIsStoppedState(state, true);
+ const char *state_cstr = StateAsCString(state);
+ if (pid != LLDB_INVALID_PROCESS_ID)
+ strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
+ strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
+ }
+ if (properties > 0)
+ strm.PutCString(" )\n");
+ else
+ strm.EOL();
+ if (show_process_status) {
+ const bool only_threads_with_stop_reason = true;
+ const uint32_t start_frame = 0;
+ const uint32_t num_frames = 1;
+ const uint32_t num_frames_with_source = 1;
+ const bool stop_format = false;
+ process_sp->GetStatus(strm);
+ process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
+ start_frame, num_frames,
+ num_frames_with_source, stop_format);
+ }
+}
+static uint32_t DumpTargetList(TargetList &target_list,
+ bool show_stopped_process_status, Stream &strm) {
+ const uint32_t num_targets = target_list.GetNumTargets();
+ if (num_targets) {
+ TargetSP selected_target_sp(target_list.GetSelectedTarget());
+ strm.PutCString("Current targets:\n");
+ for (uint32_t i = 0; i < num_targets; ++i) {
+ TargetSP target_sp(target_list.GetTargetAtIndex(i));
+ if (target_sp) {
+ bool is_selected = target_sp.get() == selected_target_sp.get();
+ DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
+ show_stopped_process_status, strm);
+ }
}
+ }
+ return num_targets;
}
-static uint32_t
-DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
-{
- const uint32_t num_targets = target_list.GetNumTargets();
- if (num_targets)
- {
- TargetSP selected_target_sp (target_list.GetSelectedTarget());
- strm.PutCString ("Current targets:\n");
- for (uint32_t i = 0; i < num_targets; ++i)
- {
- TargetSP target_sp (target_list.GetTargetAtIndex (i));
- if (target_sp)
- {
- bool is_selected = target_sp.get() == selected_target_sp.get();
- DumpTargetInfo (i,
- target_sp.get(),
- is_selected ? "* " : " ",
- show_stopped_process_status,
- strm);
- }
- }
- }
- return num_targets;
+// TODO: Remove this once llvm can pretty-print time points
+static void DumpTimePoint(llvm::sys::TimePoint<> tp, Stream &s, uint32_t width) {
+#ifndef LLDB_DISABLE_POSIX
+ char time_buf[32];
+ time_t time = llvm::sys::toTimeT(tp);
+ char *time_cstr = ::ctime_r(&time, time_buf);
+ if (time_cstr) {
+ char *newline = ::strpbrk(time_cstr, "\n\r");
+ if (newline)
+ *newline = '\0';
+ if (width > 0)
+ s.Printf("%-*s", width, time_cstr);
+ else
+ s.PutCString(time_cstr);
+ } else if (width > 0)
+ s.Printf("%-*s", width, "");
+#endif
}
#pragma mark CommandObjectTargetCreate
@@ -149,312 +157,283 @@ DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Strea
// "target create"
//-------------------------------------------------------------------------
-class CommandObjectTargetCreate : public CommandObjectParsed
-{
+class CommandObjectTargetCreate : public CommandObjectParsed {
public:
- CommandObjectTargetCreate(CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "target create",
- "Create a target using the argument as the main executable.",
- nullptr),
- m_option_group (interpreter),
- m_arch_option (),
- m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename, "Fullpath to a core file to use for this target."),
- m_platform_path (LLDB_OPT_SET_1, false, "platform-path", 'P', 0, eArgTypePath, "Path to the remote file to use for this target."),
- m_symbol_file (LLDB_OPT_SET_1, false, "symfile", 's', 0, eArgTypeFilename, "Fullpath to a stand alone debug symbols file for when debug symbols are not in the executable."),
- m_remote_file (LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename, "Fullpath to the file on the remote host if debugging remotely."),
- m_add_dependents (LLDB_OPT_SET_1, false, "no-dependents", 'd', "Don't load dependent files when creating the target, just add the specified executable.", true, true)
- {
- CommandArgumentEntry arg;
- CommandArgumentData file_arg;
-
- // Define the first (and only) variant of this arg.
- file_arg.arg_type = eArgTypeFilename;
- file_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (file_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
-
- m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
+ CommandObjectTargetCreate(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "target create",
+ "Create a target using the argument as the main executable.",
+ nullptr),
+ m_option_group(), m_arch_option(),
+ m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
+ "Fullpath to a core file to use for this target."),
+ m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
+ eArgTypePath,
+ "Path to the remote file to use for this target."),
+ m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
+ eArgTypeFilename, "Fullpath to a stand alone debug "
+ "symbols file for when debug symbols "
+ "are not in the executable."),
+ m_remote_file(
+ LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
+ "Fullpath to the file on the remote host if debugging remotely."),
+ m_add_dependents(LLDB_OPT_SET_1, false, "no-dependents", 'd',
+ "Don't load dependent files when creating the target, "
+ "just add the specified executable.",
+ true, true) {
+ CommandArgumentEntry arg;
+ CommandArgumentData file_arg;
+
+ // Define the first (and only) variant of this arg.
+ file_arg.arg_type = eArgTypeFilename;
+ file_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(file_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+
+ m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectTargetCreate() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index));
+ completion_str.erase(cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
- ~CommandObjectTargetCreate() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
+ FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
+
+ if (core_file) {
+ if (!core_file.Exists()) {
+ result.AppendErrorWithFormat("core file '%s' doesn't exist",
+ core_file.GetPath().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ if (!core_file.Readable()) {
+ result.AppendErrorWithFormat("core file '%s' is not readable",
+ core_file.GetPath().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue());
- FileSpec remote_file (m_remote_file.GetOptionValue().GetCurrentValue());
-
- if (core_file)
- {
- if (!core_file.Exists())
- {
- result.AppendErrorWithFormat("core file '%s' doesn't exist", core_file.GetPath().c_str());
- result.SetStatus (eReturnStatusFailed);
+ if (argc == 1 || core_file || remote_file) {
+ FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
+ if (symfile) {
+ if (symfile.Exists()) {
+ if (!symfile.Readable()) {
+ result.AppendErrorWithFormat("symbol file '%s' is not readable",
+ symfile.GetPath().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ char symfile_path[PATH_MAX];
+ symfile.GetPath(symfile_path, sizeof(symfile_path));
+ result.AppendErrorWithFormat("invalid symbol file path '%s'",
+ symfile_path);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ const char *file_path = command.GetArgumentAtIndex(0);
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, "(lldb) target create '%s'",
+ file_path);
+ FileSpec file_spec;
+
+ if (file_path)
+ file_spec.SetFile(file_path, true);
+
+ bool must_set_platform_path = false;
+
+ Debugger &debugger = m_interpreter.GetDebugger();
+
+ TargetSP target_sp;
+ llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
+ const bool get_dependent_files =
+ m_add_dependents.GetOptionValue().GetCurrentValue();
+ Error error(debugger.GetTargetList().CreateTarget(
+ debugger, file_path, arch_cstr, get_dependent_files, nullptr,
+ target_sp));
+
+ if (target_sp) {
+ // Only get the platform after we create the target because we might
+ // have
+ // switched platforms depending on what the arguments were to
+ // CreateTarget()
+ // we can't rely on the selected platform.
+
+ PlatformSP platform_sp = target_sp->GetPlatform();
+
+ if (remote_file) {
+ if (platform_sp) {
+ // I have a remote file.. two possible cases
+ if (file_spec && file_spec.Exists()) {
+ // if the remote file does not exist, push it there
+ if (!platform_sp->GetFileExists(remote_file)) {
+ Error err = platform_sp->PutFile(file_spec, remote_file);
+ if (err.Fail()) {
+ result.AppendError(err.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ } else {
+ // there is no local file and we need one
+ // in order to make the remote ---> local transfer we need a
+ // platform
+ // TODO: if the user has passed in a --platform argument, use it
+ // to fetch the right platform
+ if (!platform_sp) {
+ result.AppendError(
+ "unable to perform remote debugging without a platform");
+ result.SetStatus(eReturnStatusFailed);
return false;
-
- }
- if (!core_file.Readable())
- {
- result.AppendErrorWithFormat("core file '%s' is not readable", core_file.GetPath().c_str());
- result.SetStatus (eReturnStatusFailed);
+ }
+ if (file_path) {
+ // copy the remote file to the local file
+ Error err = platform_sp->GetFile(remote_file, file_spec);
+ if (err.Fail()) {
+ result.AppendError(err.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ // make up a local file
+ result.AppendError("remote --> local transfer without local "
+ "path is not implemented yet");
+ result.SetStatus(eReturnStatusFailed);
return false;
+ }
}
+ } else {
+ result.AppendError("no platform found for target");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
- if (argc == 1 || core_file || remote_file)
- {
- FileSpec symfile (m_symbol_file.GetOptionValue().GetCurrentValue());
+ if (symfile || remote_file) {
+ ModuleSP module_sp(target_sp->GetExecutableModule());
+ if (module_sp) {
if (symfile)
- {
- if (symfile.Exists())
- {
- if (!symfile.Readable())
- {
- result.AppendErrorWithFormat("symbol file '%s' is not readable", symfile.GetPath().c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- char symfile_path[PATH_MAX];
- symfile.GetPath(symfile_path, sizeof(symfile_path));
- result.AppendErrorWithFormat("invalid symbol file path '%s'", symfile_path);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ module_sp->SetSymbolFileFileSpec(symfile);
+ if (remote_file) {
+ std::string remote_path = remote_file.GetPath();
+ target_sp->SetArg0(remote_path.c_str());
+ module_sp->SetPlatformFileSpec(remote_file);
}
+ }
+ }
- const char *file_path = command.GetArgumentAtIndex(0);
- Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
- FileSpec file_spec;
-
- if (file_path)
- file_spec.SetFile (file_path, true);
-
- bool must_set_platform_path = false;
-
- Debugger &debugger = m_interpreter.GetDebugger();
-
- TargetSP target_sp;
- const char *arch_cstr = m_arch_option.GetArchitectureName();
- const bool get_dependent_files = m_add_dependents.GetOptionValue().GetCurrentValue();
- Error error(debugger.GetTargetList().CreateTarget(debugger,
- file_path,
- arch_cstr,
- get_dependent_files,
- nullptr,
- target_sp));
-
- if (target_sp)
- {
- // Only get the platform after we create the target because we might have
- // switched platforms depending on what the arguments were to CreateTarget()
- // we can't rely on the selected platform.
-
- PlatformSP platform_sp = target_sp->GetPlatform();
-
- if (remote_file)
- {
- if (platform_sp)
- {
- // I have a remote file.. two possible cases
- if (file_spec && file_spec.Exists())
- {
- // if the remote file does not exist, push it there
- if (!platform_sp->GetFileExists (remote_file))
- {
- Error err = platform_sp->PutFile(file_spec, remote_file);
- if (err.Fail())
- {
- result.AppendError(err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
- else
- {
- // there is no local file and we need one
- // in order to make the remote ---> local transfer we need a platform
- // TODO: if the user has passed in a --platform argument, use it to fetch the right platform
- if (!platform_sp)
- {
- result.AppendError("unable to perform remote debugging without a platform");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (file_path)
- {
- // copy the remote file to the local file
- Error err = platform_sp->GetFile(remote_file, file_spec);
- if (err.Fail())
- {
- result.AppendError(err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- // make up a local file
- result.AppendError("remote --> local transfer without local path is not implemented yet");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
- else
- {
- result.AppendError("no platform found for target");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
-
- if (symfile || remote_file)
- {
- ModuleSP module_sp (target_sp->GetExecutableModule());
- if (module_sp)
- {
- if (symfile)
- module_sp->SetSymbolFileFileSpec(symfile);
- if (remote_file)
- {
- std::string remote_path = remote_file.GetPath();
- target_sp->SetArg0(remote_path.c_str());
- module_sp->SetPlatformFileSpec(remote_file);
- }
- }
- }
-
- debugger.GetTargetList().SetSelectedTarget(target_sp.get());
- if (must_set_platform_path)
- {
- ModuleSpec main_module_spec(file_spec);
- ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
- if (module_sp)
- module_sp->SetPlatformFileSpec(remote_file);
- }
- if (core_file)
- {
- char core_path[PATH_MAX];
- core_file.GetPath(core_path, sizeof(core_path));
- if (core_file.Exists())
- {
- if (!core_file.Readable())
- {
- result.AppendMessageWithFormat ("Core file '%s' is not readable.\n", core_path);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- FileSpec core_file_dir;
- core_file_dir.GetDirectory() = core_file.GetDirectory();
- target_sp->GetExecutableSearchPaths ().Append (core_file_dir);
-
- ProcessSP process_sp(target_sp->CreateProcess(m_interpreter.GetDebugger().GetListener(), nullptr, &core_file));
-
- if (process_sp)
- {
- // Seems weird that we Launch a core file, but that is
- // what we do!
- error = process_sp->LoadCore();
-
- if (error.Fail())
- {
- result.AppendError(error.AsCString("can't find plug-in for core file"));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName());
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
+ debugger.GetTargetList().SetSelectedTarget(target_sp.get());
+ if (must_set_platform_path) {
+ ModuleSpec main_module_spec(file_spec);
+ ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(remote_file);
+ }
+ if (core_file) {
+ char core_path[PATH_MAX];
+ core_file.GetPath(core_path, sizeof(core_path));
+ if (core_file.Exists()) {
+ if (!core_file.Readable()) {
+ result.AppendMessageWithFormat(
+ "Core file '%s' is not readable.\n", core_path);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else
- {
- result.AppendError(error.AsCString());
- result.SetStatus (eReturnStatusFailed);
+ FileSpec core_file_dir;
+ core_file_dir.GetDirectory() = core_file.GetDirectory();
+ target_sp->GetExecutableSearchPaths().Append(core_file_dir);
+
+ ProcessSP process_sp(target_sp->CreateProcess(
+ m_interpreter.GetDebugger().GetListener(), llvm::StringRef(),
+ &core_file));
+
+ if (process_sp) {
+ // Seems weird that we Launch a core file, but that is
+ // what we do!
+ error = process_sp->LoadCore();
+
+ if (error.Fail()) {
+ result.AppendError(
+ error.AsCString("can't find plug-in for core file"));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ result.AppendMessageWithFormat(
+ "Core file '%s' (%s) was loaded.\n", core_path,
+ target_sp->GetArchitecture().GetArchitectureName());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+ } else {
+ result.AppendErrorWithFormat(
+ "Unable to find process plug-in for core file '%s'\n",
+ core_path);
+ result.SetStatus(eReturnStatusFailed);
}
+ } else {
+ result.AppendErrorWithFormat("Core file '%s' does not exist\n",
+ core_path);
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendMessageWithFormat(
+ "Current executable set to '%s' (%s).\n", file_path,
+ target_sp->GetArchitecture().GetArchitectureName());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
- else
- {
- result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core option.\n", m_cmd_name.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ } else {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendErrorWithFormat("'%s' takes exactly one executable path "
+ "argument, or use the --core option.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
private:
- OptionGroupOptions m_option_group;
- OptionGroupArchitecture m_arch_option;
- OptionGroupFile m_core_file;
- OptionGroupFile m_platform_path;
- OptionGroupFile m_symbol_file;
- OptionGroupFile m_remote_file;
- OptionGroupBoolean m_add_dependents;
+ OptionGroupOptions m_option_group;
+ OptionGroupArchitecture m_arch_option;
+ OptionGroupFile m_core_file;
+ OptionGroupFile m_platform_path;
+ OptionGroupFile m_symbol_file;
+ OptionGroupFile m_remote_file;
+ OptionGroupBoolean m_add_dependents;
};
#pragma mark CommandObjectTargetList
@@ -463,41 +442,33 @@ private:
// "target list"
//----------------------------------------------------------------------
-class CommandObjectTargetList : public CommandObjectParsed
-{
+class CommandObjectTargetList : public CommandObjectParsed {
public:
- CommandObjectTargetList (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "target list",
- "List all current targets in the current debug session.",
- nullptr)
- {
- }
+ CommandObjectTargetList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "target list",
+ "List all current targets in the current debug session.", nullptr) {
+ }
- ~CommandObjectTargetList() override = default;
+ ~CommandObjectTargetList() override = default;
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- if (args.GetArgumentCount() == 0)
- {
- Stream &strm = result.GetOutputStream();
-
- bool show_stopped_process_status = false;
- if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
- {
- strm.PutCString ("No targets.\n");
- }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError ("the 'target list' command takes no arguments\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ if (args.GetArgumentCount() == 0) {
+ Stream &strm = result.GetOutputStream();
+
+ bool show_stopped_process_status = false;
+ if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
+ show_stopped_process_status, strm) == 0) {
+ strm.PutCString("No targets.\n");
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError("the 'target list' command takes no arguments\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetSelect
@@ -506,78 +477,63 @@ protected:
// "target select"
//----------------------------------------------------------------------
-class CommandObjectTargetSelect : public CommandObjectParsed
-{
+class CommandObjectTargetSelect : public CommandObjectParsed {
public:
- CommandObjectTargetSelect (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "target select",
- "Select a target as the current target by target index.",
- nullptr)
- {
- }
+ CommandObjectTargetSelect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "target select",
+ "Select a target as the current target by target index.", nullptr) {
+ }
- ~CommandObjectTargetSelect() override = default;
+ ~CommandObjectTargetSelect() override = default;
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- if (args.GetArgumentCount() == 1)
- {
- bool success = false;
- const char *target_idx_arg = args.GetArgumentAtIndex(0);
- uint32_t target_idx = StringConvert::ToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
- if (success)
- {
- TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
- const uint32_t num_targets = target_list.GetNumTargets();
- if (target_idx < num_targets)
- {
- TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
- if (target_sp)
- {
- Stream &strm = result.GetOutputStream();
- target_list.SetSelectedTarget (target_sp.get());
- bool show_stopped_process_status = false;
- DumpTargetList (target_list, show_stopped_process_status, strm);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- if (num_targets > 0)
- {
- result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
- target_idx,
- num_targets - 1);
- }
- else
- {
- result.AppendErrorWithFormat ("index %u is out of range since there are no active targets\n",
- target_idx);
- }
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("'target select' takes a single argument: a target index\n");
- result.SetStatus (eReturnStatusFailed);
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ if (args.GetArgumentCount() == 1) {
+ bool success = false;
+ const char *target_idx_arg = args.GetArgumentAtIndex(0);
+ uint32_t target_idx =
+ StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
+ if (success) {
+ TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
+ const uint32_t num_targets = target_list.GetNumTargets();
+ if (target_idx < num_targets) {
+ TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
+ if (target_sp) {
+ Stream &strm = result.GetOutputStream();
+ target_list.SetSelectedTarget(target_sp.get());
+ bool show_stopped_process_status = false;
+ DumpTargetList(target_list, show_stopped_process_status, strm);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("target #%u is NULL in target list\n",
+ target_idx);
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ if (num_targets > 0) {
+ result.AppendErrorWithFormat(
+ "index %u is out of range, valid target indexes are 0 - %u\n",
+ target_idx, num_targets - 1);
+ } else {
+ result.AppendErrorWithFormat(
+ "index %u is out of range since there are no active targets\n",
+ target_idx);
+ }
+ result.SetStatus(eReturnStatusFailed);
}
- return result.Succeeded();
+ } else {
+ result.AppendErrorWithFormat("invalid index string value '%s'\n",
+ target_idx_arg);
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError(
+ "'target select' takes a single argument: a target index\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetSelect
@@ -586,130 +542,111 @@ protected:
// "target delete"
//----------------------------------------------------------------------
-class CommandObjectTargetDelete : public CommandObjectParsed
-{
+class CommandObjectTargetDelete : public CommandObjectParsed {
public:
- CommandObjectTargetDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "target delete",
+ CommandObjectTargetDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target delete",
"Delete one or more targets by target index.",
nullptr),
- m_option_group(interpreter),
- m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.", false, true),
+ m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
+ "Delete all targets.", false, true),
m_cleanup_option(
- LLDB_OPT_SET_1,
- false,
- "clean", 'c',
- "Perform extra cleanup to minimize memory consumption after deleting the target. "
- "By default, LLDB will keep in memory any modules previously loaded by the target as well "
- "as all of its debug info. Specifying --clean will unload all of these shared modules and "
+ LLDB_OPT_SET_1, false, "clean", 'c',
+ "Perform extra cleanup to minimize memory consumption after "
+ "deleting the target. "
+ "By default, LLDB will keep in memory any modules previously "
+ "loaded by the target as well "
+ "as all of its debug info. Specifying --clean will unload all of "
+ "these shared modules and "
"cause them to be reparsed again the next time the target is run",
- false, true)
- {
- m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
+ false, true) {
+ m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
- ~CommandObjectTargetDelete() override = default;
+ ~CommandObjectTargetDelete() override = default;
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
+ Options *GetOptions() override { return &m_option_group; }
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- const size_t argc = args.GetArgumentCount();
- std::vector<TargetSP> delete_target_list;
- TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
- TargetSP target_sp;
-
- if (m_all_option.GetOptionValue())
- {
- for (int i = 0; i < target_list.GetNumTargets(); ++i)
- delete_target_list.push_back(target_list.GetTargetAtIndex(i));
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ const size_t argc = args.GetArgumentCount();
+ std::vector<TargetSP> delete_target_list;
+ TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
+ TargetSP target_sp;
+
+ if (m_all_option.GetOptionValue()) {
+ for (int i = 0; i < target_list.GetNumTargets(); ++i)
+ delete_target_list.push_back(target_list.GetTargetAtIndex(i));
+ } else if (argc > 0) {
+ const uint32_t num_targets = target_list.GetNumTargets();
+ // Bail out if don't have any targets.
+ if (num_targets == 0) {
+ result.AppendError("no targets to delete");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ for (auto &entry : args.entries()) {
+ uint32_t target_idx;
+ if (entry.ref.getAsInteger(0, target_idx)) {
+ result.AppendErrorWithFormat("invalid target index '%s'\n",
+ entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else if (argc > 0)
- {
- const uint32_t num_targets = target_list.GetNumTargets();
- // Bail out if don't have any targets.
- if (num_targets == 0) {
- result.AppendError("no targets to delete");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- for (uint32_t arg_idx = 0; arg_idx < argc; ++arg_idx)
- {
- const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
- bool success = false;
- uint32_t target_idx = StringConvert::ToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
- if (!success)
- {
- result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (target_idx < num_targets)
- {
- target_sp = target_list.GetTargetAtIndex (target_idx);
- if (target_sp)
- {
- delete_target_list.push_back (target_sp);
- continue;
- }
- }
- if (num_targets > 1)
- result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n",
- target_idx,
- num_targets - 1);
- else
- result.AppendErrorWithFormat("target index %u is out of range, the only valid index is 0\n",
- target_idx);
-
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (target_idx < num_targets) {
+ target_sp = target_list.GetTargetAtIndex(target_idx);
+ if (target_sp) {
+ delete_target_list.push_back(target_sp);
+ continue;
+ }
}
+ if (num_targets > 1)
+ result.AppendErrorWithFormat("target index %u is out of range, valid "
+ "target indexes are 0 - %u\n",
+ target_idx, num_targets - 1);
else
- {
- target_sp = target_list.GetSelectedTarget();
- if (!target_sp)
- {
- result.AppendErrorWithFormat("no target is currently selected\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- delete_target_list.push_back (target_sp);
- }
+ result.AppendErrorWithFormat(
+ "target index %u is out of range, the only valid index is 0\n",
+ target_idx);
- const size_t num_targets_to_delete = delete_target_list.size();
- for (size_t idx = 0; idx < num_targets_to_delete; ++idx)
- {
- target_sp = delete_target_list[idx];
- target_list.DeleteTarget(target_sp);
- target_sp->Destroy();
- }
- // If "--clean" was specified, prune any orphaned shared modules from
- // the global shared module list
- if (m_cleanup_option.GetOptionValue ())
- {
- const bool mandatory = true;
- ModuleList::RemoveOrphanSharedModules(mandatory);
- }
- result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete);
- result.SetStatus(eReturnStatusSuccessFinishResult);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ target_sp = target_list.GetSelectedTarget();
+ if (!target_sp) {
+ result.AppendErrorWithFormat("no target is currently selected\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ delete_target_list.push_back(target_sp);
+ }
- return true;
+ const size_t num_targets_to_delete = delete_target_list.size();
+ for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
+ target_sp = delete_target_list[idx];
+ target_list.DeleteTarget(target_sp);
+ target_sp->Destroy();
+ }
+ // If "--clean" was specified, prune any orphaned shared modules from
+ // the global shared module list
+ if (m_cleanup_option.GetOptionValue()) {
+ const bool mandatory = true;
+ ModuleList::RemoveOrphanSharedModules(mandatory);
}
+ result.GetOutputStream().Printf("%u targets deleted.\n",
+ (uint32_t)num_targets_to_delete);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
- OptionGroupOptions m_option_group;
- OptionGroupBoolean m_all_option;
- OptionGroupBoolean m_cleanup_option;
+ return true;
+ }
+
+ OptionGroupOptions m_option_group;
+ OptionGroupBoolean m_all_option;
+ OptionGroupBoolean m_cleanup_option;
};
#pragma mark CommandObjectTargetVariable
@@ -718,1308 +655,1141 @@ protected:
// "target variable"
//----------------------------------------------------------------------
-class CommandObjectTargetVariable : public CommandObjectParsed
-{
- static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
- static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
+class CommandObjectTargetVariable : public CommandObjectParsed {
+ static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
+ static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
public:
- CommandObjectTargetVariable(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "target variable",
- "Read global variables for the current target, before or while running a process.",
- nullptr, eCommandRequiresTarget),
- m_option_group(interpreter),
- m_option_variable(false), // Don't include frame options
- m_option_format(eFormatDefault),
- m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE, 0, eArgTypeFilename,
- "A basename or fullpath to a file that contains global variables. This option can be "
- "specified multiple times."),
- m_option_shared_libraries(LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0, eArgTypeFilename,
- "A basename or fullpath to a shared library to use in the search for global "
- "variables. This option can be specified multiple times."),
- m_varobj_options()
- {
- CommandArgumentEntry arg;
- CommandArgumentData var_name_arg;
-
- // Define the first (and only) variant of this arg.
- var_name_arg.arg_type = eArgTypeVarName;
- var_name_arg.arg_repetition = eArgRepeatPlus;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (var_name_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
-
- m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
- m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
+ CommandObjectTargetVariable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target variable",
+ "Read global variables for the current target, "
+ "before or while running a process.",
+ nullptr, eCommandRequiresTarget),
+ m_option_group(),
+ m_option_variable(false), // Don't include frame options
+ m_option_format(eFormatDefault),
+ m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
+ 0, eArgTypeFilename,
+ "A basename or fullpath to a file that contains "
+ "global variables. This option can be "
+ "specified multiple times."),
+ m_option_shared_libraries(
+ LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
+ eArgTypeFilename,
+ "A basename or fullpath to a shared library to use in the search "
+ "for global "
+ "variables. This option can be specified multiple times."),
+ m_varobj_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData var_name_arg;
+
+ // Define the first (and only) variant of this arg.
+ var_name_arg.arg_type = eArgTypeVarName;
+ var_name_arg.arg_repetition = eArgRepeatPlus;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(var_name_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+
+ m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_option_format,
+ OptionGroupFormat::OPTION_GROUP_FORMAT |
+ OptionGroupFormat::OPTION_GROUP_GDB_FMT,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectTargetVariable() override = default;
+
+ void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
+ const char *root_name) {
+ DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
+
+ if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
+ valobj_sp->IsRuntimeSupportValue())
+ return;
+
+ switch (var_sp->GetScope()) {
+ case eValueTypeVariableGlobal:
+ if (m_option_variable.show_scope)
+ s.PutCString("GLOBAL: ");
+ break;
+
+ case eValueTypeVariableStatic:
+ if (m_option_variable.show_scope)
+ s.PutCString("STATIC: ");
+ break;
+
+ case eValueTypeVariableArgument:
+ if (m_option_variable.show_scope)
+ s.PutCString(" ARG: ");
+ break;
+
+ case eValueTypeVariableLocal:
+ if (m_option_variable.show_scope)
+ s.PutCString(" LOCAL: ");
+ break;
+
+ case eValueTypeVariableThreadLocal:
+ if (m_option_variable.show_scope)
+ s.PutCString("THREAD: ");
+ break;
+
+ default:
+ break;
}
- ~CommandObjectTargetVariable() override = default;
-
- void
- DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
- {
- DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
+ if (m_option_variable.show_decl) {
+ bool show_fullpaths = false;
+ bool show_module = true;
+ if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
+ s.PutCString(": ");
+ }
- if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
- valobj_sp->IsRuntimeSupportValue())
- return;
-
- switch (var_sp->GetScope())
- {
- case eValueTypeVariableGlobal:
- if (m_option_variable.show_scope)
- s.PutCString("GLOBAL: ");
- break;
+ const Format format = m_option_format.GetFormat();
+ if (format != eFormatDefault)
+ options.SetFormat(format);
- case eValueTypeVariableStatic:
- if (m_option_variable.show_scope)
- s.PutCString("STATIC: ");
- break;
+ options.SetRootValueObjectName(root_name);
- case eValueTypeVariableArgument:
- if (m_option_variable.show_scope)
- s.PutCString(" ARG: ");
- break;
+ valobj_sp->Dump(s, options);
+ }
- case eValueTypeVariableLocal:
- if (m_option_variable.show_scope)
- s.PutCString(" LOCAL: ");
- break;
+ static size_t GetVariableCallback(void *baton, const char *name,
+ VariableList &variable_list) {
+ Target *target = static_cast<Target *>(baton);
+ if (target) {
+ return target->GetImages().FindGlobalVariables(ConstString(name), true,
+ UINT32_MAX, variable_list);
+ }
+ return 0;
+ }
- case eValueTypeVariableThreadLocal:
- if (m_option_variable.show_scope)
- s.PutCString("THREAD: ");
- break;
+ Options *GetOptions() override { return &m_option_group; }
- default:
- break;
+protected:
+ void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
+ const SymbolContext &sc,
+ const VariableList &variable_list, Stream &s) {
+ size_t count = variable_list.GetSize();
+ if (count > 0) {
+ if (sc.module_sp) {
+ if (sc.comp_unit) {
+ s.Printf("Global variables for %s in %s:\n",
+ sc.comp_unit->GetPath().c_str(),
+ sc.module_sp->GetFileSpec().GetPath().c_str());
+ } else {
+ s.Printf("Global variables for %s\n",
+ sc.module_sp->GetFileSpec().GetPath().c_str());
}
-
- if (m_option_variable.show_decl)
- {
- bool show_fullpaths = false;
- bool show_module = true;
- if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
- s.PutCString (": ");
+ } else if (sc.comp_unit) {
+ s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
+ }
+
+ for (uint32_t i = 0; i < count; ++i) {
+ VariableSP var_sp(variable_list.GetVariableAtIndex(i));
+ if (var_sp) {
+ ValueObjectSP valobj_sp(ValueObjectVariable::Create(
+ exe_ctx.GetBestExecutionContextScope(), var_sp));
+
+ if (valobj_sp)
+ DumpValueObject(s, var_sp, valobj_sp,
+ var_sp->GetName().GetCString());
}
-
- const Format format = m_option_format.GetFormat();
- if (format != eFormatDefault)
- options.SetFormat(format);
-
- options.SetRootValueObjectName(root_name);
-
- valobj_sp->Dump(s,options);
+ }
}
-
- static size_t GetVariableCallback (void *baton,
- const char *name,
- VariableList &variable_list)
- {
- Target *target = static_cast<Target *>(baton);
- if (target)
- {
- return target->GetImages().FindGlobalVariables (ConstString(name),
- true,
- UINT32_MAX,
- variable_list);
+ }
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Target *target = m_exe_ctx.GetTargetPtr();
+ const size_t argc = args.GetArgumentCount();
+ Stream &s = result.GetOutputStream();
+
+ if (argc > 0) {
+
+ // TODO: Convert to entry-based iteration. Requires converting
+ // DumpValueObject.
+ for (size_t idx = 0; idx < argc; ++idx) {
+ VariableList variable_list;
+ ValueObjectList valobj_list;
+
+ const char *arg = args.GetArgumentAtIndex(idx);
+ size_t matches = 0;
+ bool use_var_name = false;
+ if (m_option_variable.use_regex) {
+ RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
+ if (!regex.IsValid()) {
+ result.GetErrorStream().Printf(
+ "error: invalid regular expression: '%s'\n", arg);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ use_var_name = true;
+ matches = target->GetImages().FindGlobalVariables(
+ regex, true, UINT32_MAX, variable_list);
+ } else {
+ Error error(Variable::GetValuesForVariableExpressionPath(
+ arg, m_exe_ctx.GetBestExecutionContextScope(),
+ GetVariableCallback, target, variable_list, valobj_list));
+ matches = variable_list.GetSize();
}
- return 0;
- }
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
-
-protected:
- void
- DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, Stream &s)
- {
- size_t count = variable_list.GetSize();
- if (count > 0)
- {
- if (sc.module_sp)
- {
- if (sc.comp_unit)
- {
- s.Printf ("Global variables for %s in %s:\n",
- sc.comp_unit->GetPath().c_str(),
- sc.module_sp->GetFileSpec().GetPath().c_str());
- }
- else
- {
- s.Printf ("Global variables for %s\n",
- sc.module_sp->GetFileSpec().GetPath().c_str());
- }
- }
- else if (sc.comp_unit)
- {
- s.Printf ("Global variables for %s\n",
- sc.comp_unit->GetPath().c_str());
- }
-
- for (uint32_t i = 0; i < count; ++i)
- {
- VariableSP var_sp (variable_list.GetVariableAtIndex(i));
- if (var_sp)
- {
- ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));
-
- if (valobj_sp)
- DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
- }
+ if (matches == 0) {
+ result.GetErrorStream().Printf(
+ "error: can't find global variable '%s'\n", arg);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
+ VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
+ if (var_sp) {
+ ValueObjectSP valobj_sp(
+ valobj_list.GetValueObjectAtIndex(global_idx));
+ if (!valobj_sp)
+ valobj_sp = ValueObjectVariable::Create(
+ m_exe_ctx.GetBestExecutionContextScope(), var_sp);
+
+ if (valobj_sp)
+ DumpValueObject(s, var_sp, valobj_sp,
+ use_var_name ? var_sp->GetName().GetCString()
+ : arg);
}
+ }
}
- }
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Target *target = m_exe_ctx.GetTargetPtr();
- const size_t argc = args.GetArgumentCount();
- Stream &s = result.GetOutputStream();
-
- if (argc > 0)
- {
-
- for (size_t idx = 0; idx < argc; ++idx)
- {
- VariableList variable_list;
- ValueObjectList valobj_list;
-
- const char *arg = args.GetArgumentAtIndex(idx);
- size_t matches = 0;
- bool use_var_name = false;
- if (m_option_variable.use_regex)
- {
- RegularExpression regex(arg);
- if (!regex.IsValid ())
- {
- result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- use_var_name = true;
- matches = target->GetImages().FindGlobalVariables (regex,
- true,
- UINT32_MAX,
- variable_list);
- }
- else
- {
- Error error (Variable::GetValuesForVariableExpressionPath (arg,
- m_exe_ctx.GetBestExecutionContextScope(),
- GetVariableCallback,
- target,
- variable_list,
- valobj_list));
- matches = variable_list.GetSize();
- }
-
- if (matches == 0)
- {
- result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
- {
- VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
- if (var_sp)
- {
- ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
- if (!valobj_sp)
- valobj_sp = ValueObjectVariable::Create (m_exe_ctx.GetBestExecutionContextScope(), var_sp);
-
- if (valobj_sp)
- DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
- }
- }
- }
+ }
+ } else {
+ const FileSpecList &compile_units =
+ m_option_compile_units.GetOptionValue().GetCurrentValue();
+ const FileSpecList &shlibs =
+ m_option_shared_libraries.GetOptionValue().GetCurrentValue();
+ SymbolContextList sc_list;
+ const size_t num_compile_units = compile_units.GetSize();
+ const size_t num_shlibs = shlibs.GetSize();
+ if (num_compile_units == 0 && num_shlibs == 0) {
+ bool success = false;
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
+ CompileUnit *comp_unit = nullptr;
+ if (frame) {
+ SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
+ if (sc.comp_unit) {
+ const bool can_create = true;
+ VariableListSP comp_unit_varlist_sp(
+ sc.comp_unit->GetVariableList(can_create));
+ if (comp_unit_varlist_sp) {
+ size_t count = comp_unit_varlist_sp->GetSize();
+ if (count > 0) {
+ DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
+ success = true;
+ }
}
+ }
}
- else
- {
- const FileSpecList &compile_units = m_option_compile_units.GetOptionValue().GetCurrentValue();
- const FileSpecList &shlibs = m_option_shared_libraries.GetOptionValue().GetCurrentValue();
- SymbolContextList sc_list;
- const size_t num_compile_units = compile_units.GetSize();
- const size_t num_shlibs = shlibs.GetSize();
- if (num_compile_units == 0 && num_shlibs == 0)
- {
- bool success = false;
- StackFrame *frame = m_exe_ctx.GetFramePtr();
- CompileUnit *comp_unit = nullptr;
- if (frame)
- {
- SymbolContext sc = frame->GetSymbolContext (eSymbolContextCompUnit);
- if (sc.comp_unit)
- {
- const bool can_create = true;
- VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create));
- if (comp_unit_varlist_sp)
- {
- size_t count = comp_unit_varlist_sp->GetSize();
- if (count > 0)
- {
- DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
- success = true;
- }
- }
- }
- }
- if (!success)
- {
- if (frame)
- {
- if (comp_unit)
- result.AppendErrorWithFormat ("no global variables in current compile unit: %s\n",
- comp_unit->GetPath().c_str());
- else
- result.AppendErrorWithFormat ("no debug information for frame %u\n", frame->GetFrameIndex());
- }
- else
- result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
- result.SetStatus (eReturnStatusFailed);
- }
- }
+ if (!success) {
+ if (frame) {
+ if (comp_unit)
+ result.AppendErrorWithFormat(
+ "no global variables in current compile unit: %s\n",
+ comp_unit->GetPath().c_str());
else
- {
- SymbolContextList sc_list;
- const bool append = true;
- // We have one or more compile unit or shlib
- if (num_shlibs > 0)
- {
- for (size_t shlib_idx=0; shlib_idx<num_shlibs; ++shlib_idx)
- {
- const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
- ModuleSpec module_spec (module_file);
-
- ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
- if (module_sp)
- {
- if (num_compile_units > 0)
- {
- for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx)
- module_sp->FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
- }
- else
- {
- SymbolContext sc;
- sc.module_sp = module_sp;
- sc_list.Append(sc);
- }
- }
- else
- {
- // Didn't find matching shlib/module in target...
- result.AppendErrorWithFormat ("target doesn't contain the specified shared library: %s\n",
- module_file.GetPath().c_str());
- }
- }
- }
- else
- {
- // No shared libraries, we just want to find globals for the compile units files that were specified
- for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx)
- target->GetImages().FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
- }
-
- const uint32_t num_scs = sc_list.GetSize();
- if (num_scs > 0)
- {
- SymbolContext sc;
- for (uint32_t sc_idx=0; sc_idx<num_scs; ++sc_idx)
- {
- if (sc_list.GetContextAtIndex(sc_idx, sc))
- {
- if (sc.comp_unit)
- {
- const bool can_create = true;
- VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create));
- if (comp_unit_varlist_sp)
- DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
- }
- else if (sc.module_sp)
- {
- // Get all global variables for this module
- lldb_private::RegularExpression all_globals_regex("."); // Any global with at least one character
- VariableList variable_list;
- sc.module_sp->FindGlobalVariables(all_globals_regex, append, UINT32_MAX, variable_list);
- DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
- }
- }
- }
- }
+ result.AppendErrorWithFormat(
+ "no debug information for frame %u\n",
+ frame->GetFrameIndex());
+ } else
+ result.AppendError("'target variable' takes one or more global "
+ "variable names as arguments\n");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ SymbolContextList sc_list;
+ const bool append = true;
+ // We have one or more compile unit or shlib
+ if (num_shlibs > 0) {
+ for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
+ const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
+ ModuleSpec module_spec(module_file);
+
+ ModuleSP module_sp(
+ target->GetImages().FindFirstModule(module_spec));
+ if (module_sp) {
+ if (num_compile_units > 0) {
+ for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ module_sp->FindCompileUnits(
+ compile_units.GetFileSpecAtIndex(cu_idx), append,
+ sc_list);
+ } else {
+ SymbolContext sc;
+ sc.module_sp = module_sp;
+ sc_list.Append(sc);
+ }
+ } else {
+ // Didn't find matching shlib/module in target...
+ result.AppendErrorWithFormat(
+ "target doesn't contain the specified shared library: %s\n",
+ module_file.GetPath().c_str());
}
+ }
+ } else {
+ // No shared libraries, we just want to find globals for the compile
+ // units files that were specified
+ for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+ target->GetImages().FindCompileUnits(
+ compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
}
- if (m_interpreter.TruncationWarningNecessary())
- {
- result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
- m_cmd_name.c_str());
- m_interpreter.TruncationWarningGiven();
+ const uint32_t num_scs = sc_list.GetSize();
+ if (num_scs > 0) {
+ SymbolContext sc;
+ for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
+ if (sc_list.GetContextAtIndex(sc_idx, sc)) {
+ if (sc.comp_unit) {
+ const bool can_create = true;
+ VariableListSP comp_unit_varlist_sp(
+ sc.comp_unit->GetVariableList(can_create));
+ if (comp_unit_varlist_sp)
+ DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
+ s);
+ } else if (sc.module_sp) {
+ // Get all global variables for this module
+ lldb_private::RegularExpression all_globals_regex(
+ llvm::StringRef(
+ ".")); // Any global with at least one character
+ VariableList variable_list;
+ sc.module_sp->FindGlobalVariables(all_globals_regex, append,
+ UINT32_MAX, variable_list);
+ DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
+ }
+ }
+ }
}
+ }
+ }
- return result.Succeeded();
+ if (m_interpreter.TruncationWarningNecessary()) {
+ result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
+ m_cmd_name.c_str());
+ m_interpreter.TruncationWarningGiven();
}
- OptionGroupOptions m_option_group;
- OptionGroupVariable m_option_variable;
- OptionGroupFormat m_option_format;
- OptionGroupFileList m_option_compile_units;
- OptionGroupFileList m_option_shared_libraries;
- OptionGroupValueObjectDisplay m_varobj_options;
+ return result.Succeeded();
+ }
+
+ OptionGroupOptions m_option_group;
+ OptionGroupVariable m_option_variable;
+ OptionGroupFormat m_option_format;
+ OptionGroupFileList m_option_compile_units;
+ OptionGroupFileList m_option_shared_libraries;
+ OptionGroupValueObjectDisplay m_varobj_options;
};
#pragma mark CommandObjectTargetModulesSearchPathsAdd
-class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed
-{
+class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
public:
- CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "target modules search-paths add",
- "Add new image search paths substitution pairs to the current target.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandArgumentData old_prefix_arg;
- CommandArgumentData new_prefix_arg;
-
- // Define the first variant of this arg pair.
- old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
- old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
-
- // Define the first variant of this arg pair.
- new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
- new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
-
- // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
- // must always occur together, they are treated as two variants of one argument rather than two independent
- // arguments. Push them both into the first argument position for m_arguments...
-
- arg.push_back (old_prefix_arg);
- arg.push_back (new_prefix_arg);
-
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectTargetModulesSearchPathsAdd() override = default;
+ CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target modules search-paths add",
+ "Add new image search paths substitution pairs to "
+ "the current target.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData old_prefix_arg;
+ CommandArgumentData new_prefix_arg;
+
+ // Define the first variant of this arg pair.
+ old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
+ old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
+
+ // Define the first variant of this arg pair.
+ new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
+ new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
+
+ // There are two required arguments that must always occur together, i.e. an
+ // argument "pair". Because they
+ // must always occur together, they are treated as two variants of one
+ // argument rather than two independent
+ // arguments. Push them both into the first argument position for
+ // m_arguments...
+
+ arg.push_back(old_prefix_arg);
+ arg.push_back(new_prefix_arg);
+
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectTargetModulesSearchPathsAdd() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target)
- {
- const size_t argc = command.GetArgumentCount();
- if (argc & 1)
- {
- result.AppendError ("add requires an even number of arguments\n");
- result.SetStatus (eReturnStatusFailed);
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target) {
+ const size_t argc = command.GetArgumentCount();
+ if (argc & 1) {
+ result.AppendError("add requires an even number of arguments\n");
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ for (size_t i = 0; i < argc; i += 2) {
+ const char *from = command.GetArgumentAtIndex(i);
+ const char *to = command.GetArgumentAtIndex(i + 1);
+
+ if (from[0] && to[0]) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (log) {
+ log->Printf("target modules search path adding ImageSearchPath "
+ "pair: '%s' -> '%s'",
+ from, to);
}
+ bool last_pair = ((argc - i) == 2);
+ target->GetImageSearchPathList().Append(
+ ConstString(from), ConstString(to),
+ last_pair); // Notify if this is the last pair
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ if (from[0])
+ result.AppendError("<path-prefix> can't be empty\n");
else
- {
- for (size_t i = 0; i < argc; i+=2)
- {
- const char *from = command.GetArgumentAtIndex(i);
- const char *to = command.GetArgumentAtIndex(i+1);
-
- if (from[0] && to[0])
- {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- {
- log->Printf ("target modules search path adding ImageSearchPath pair: '%s' -> '%s'",
- from, to);
- }
- bool last_pair = ((argc - i) == 2);
- target->GetImageSearchPathList().Append (ConstString(from),
- ConstString(to),
- last_pair); // Notify if this is the last pair
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- if (from[0])
- result.AppendError ("<path-prefix> can't be empty\n");
- else
- result.AppendError ("<new-path-prefix> can't be empty\n");
- result.SetStatus (eReturnStatusFailed);
- }
- }
- }
- }
- else
- {
- result.AppendError ("invalid target\n");
- result.SetStatus (eReturnStatusFailed);
+ result.AppendError("<new-path-prefix> can't be empty\n");
+ result.SetStatus(eReturnStatusFailed);
+ }
}
- return result.Succeeded();
+ }
+ } else {
+ result.AppendError("invalid target\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetModulesSearchPathsClear
-class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed
-{
+class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
public:
- CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target modules search-paths clear",
- "Clear all current image search path substitution pairs from the current target.",
- "target modules search-paths clear")
- {
- }
+ CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target modules search-paths clear",
+ "Clear all current image search path substitution "
+ "pairs from the current target.",
+ "target modules search-paths clear") {}
- ~CommandObjectTargetModulesSearchPathsClear() override = default;
+ ~CommandObjectTargetModulesSearchPathsClear() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target)
- {
- bool notify = true;
- target->GetImageSearchPathList().Clear(notify);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError ("invalid target\n");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target) {
+ bool notify = true;
+ target->GetImageSearchPathList().Clear(notify);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("invalid target\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetModulesSearchPathsInsert
-class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed
-{
+class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
public:
- CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "target modules search-paths insert",
- "Insert a new image search path substitution pair into the current target at the specified index.",
- nullptr)
- {
- CommandArgumentEntry arg1;
- CommandArgumentEntry arg2;
- CommandArgumentData index_arg;
- CommandArgumentData old_prefix_arg;
- CommandArgumentData new_prefix_arg;
-
- // Define the first and only variant of this arg.
- index_arg.arg_type = eArgTypeIndex;
- index_arg.arg_repetition = eArgRepeatPlain;
-
- // Put the one and only variant into the first arg for m_arguments:
- arg1.push_back (index_arg);
-
- // Define the first variant of this arg pair.
- old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
- old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
-
- // Define the first variant of this arg pair.
- new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
- new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
-
- // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
- // must always occur together, they are treated as two variants of one argument rather than two independent
- // arguments. Push them both into the same argument position for m_arguments...
-
- arg2.push_back (old_prefix_arg);
- arg2.push_back (new_prefix_arg);
-
- // Add arguments to m_arguments.
- m_arguments.push_back (arg1);
- m_arguments.push_back (arg2);
- }
-
- ~CommandObjectTargetModulesSearchPathsInsert() override = default;
+ CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target modules search-paths insert",
+ "Insert a new image search path substitution pair "
+ "into the current target at the specified index.",
+ nullptr) {
+ CommandArgumentEntry arg1;
+ CommandArgumentEntry arg2;
+ CommandArgumentData index_arg;
+ CommandArgumentData old_prefix_arg;
+ CommandArgumentData new_prefix_arg;
+
+ // Define the first and only variant of this arg.
+ index_arg.arg_type = eArgTypeIndex;
+ index_arg.arg_repetition = eArgRepeatPlain;
+
+ // Put the one and only variant into the first arg for m_arguments:
+ arg1.push_back(index_arg);
+
+ // Define the first variant of this arg pair.
+ old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
+ old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
+
+ // Define the first variant of this arg pair.
+ new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
+ new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
+
+ // There are two required arguments that must always occur together, i.e. an
+ // argument "pair". Because they
+ // must always occur together, they are treated as two variants of one
+ // argument rather than two independent
+ // arguments. Push them both into the same argument position for
+ // m_arguments...
+
+ arg2.push_back(old_prefix_arg);
+ arg2.push_back(new_prefix_arg);
+
+ // Add arguments to m_arguments.
+ m_arguments.push_back(arg1);
+ m_arguments.push_back(arg2);
+ }
+
+ ~CommandObjectTargetModulesSearchPathsInsert() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target)
- {
- size_t argc = command.GetArgumentCount();
- // check for at least 3 arguments and an odd number of parameters
- if (argc >= 3 && argc & 1)
- {
- bool success = false;
-
- uint32_t insert_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
-
- if (!success)
- {
- result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
- result.SetStatus (eReturnStatusFailed);
- return result.Succeeded();
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target) {
+ size_t argc = command.GetArgumentCount();
+ // check for at least 3 arguments and an odd number of parameters
+ if (argc >= 3 && argc & 1) {
+ bool success = false;
+
+ uint32_t insert_idx = StringConvert::ToUInt32(
+ command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
+
+ if (!success) {
+ result.AppendErrorWithFormat(
+ "<index> parameter is not an integer: '%s'.\n",
+ command.GetArgumentAtIndex(0));
+ result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
+ }
- // shift off the index
- command.Shift();
- argc = command.GetArgumentCount();
-
- for (uint32_t i = 0; i < argc; i += 2, ++insert_idx)
- {
- const char *from = command.GetArgumentAtIndex(i);
- const char *to = command.GetArgumentAtIndex(i+1);
-
- if (from[0] && to[0])
- {
- bool last_pair = ((argc - i) == 2);
- target->GetImageSearchPathList().Insert (ConstString(from),
- ConstString(to),
- insert_idx,
- last_pair);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- if (from[0])
- result.AppendError ("<path-prefix> can't be empty\n");
- else
- result.AppendError ("<new-path-prefix> can't be empty\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
+ // shift off the index
+ command.Shift();
+ argc = command.GetArgumentCount();
+
+ for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
+ const char *from = command.GetArgumentAtIndex(i);
+ const char *to = command.GetArgumentAtIndex(i + 1);
+
+ if (from[0] && to[0]) {
+ bool last_pair = ((argc - i) == 2);
+ target->GetImageSearchPathList().Insert(
+ ConstString(from), ConstString(to), insert_idx, last_pair);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ if (from[0])
+ result.AppendError("<path-prefix> can't be empty\n");
else
- {
- result.AppendError ("insert requires at least three arguments\n");
- result.SetStatus (eReturnStatusFailed);
- return result.Succeeded();
- }
-
- }
- else
- {
- result.AppendError ("invalid target\n");
- result.SetStatus (eReturnStatusFailed);
+ result.AppendError("<new-path-prefix> can't be empty\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
+ } else {
+ result.AppendError("insert requires at least three arguments\n");
+ result.SetStatus(eReturnStatusFailed);
return result.Succeeded();
+ }
+
+ } else {
+ result.AppendError("invalid target\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetModulesSearchPathsList
-class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed
-{
+class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
public:
- CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target modules search-paths list",
- "List all current image search path substitution pairs in the current target.",
- "target modules search-paths list")
- {
- }
+ CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target modules search-paths list",
+ "List all current image search path substitution "
+ "pairs in the current target.",
+ "target modules search-paths list") {}
- ~CommandObjectTargetModulesSearchPathsList() override = default;
+ ~CommandObjectTargetModulesSearchPathsList() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target)
- {
- if (command.GetArgumentCount() != 0)
- {
- result.AppendError ("list takes no arguments\n");
- result.SetStatus (eReturnStatusFailed);
- return result.Succeeded();
- }
-
- target->GetImageSearchPathList().Dump(&result.GetOutputStream());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError ("invalid target\n");
- result.SetStatus (eReturnStatusFailed);
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target) {
+ if (command.GetArgumentCount() != 0) {
+ result.AppendError("list takes no arguments\n");
+ result.SetStatus(eReturnStatusFailed);
return result.Succeeded();
+ }
+
+ target->GetImageSearchPathList().Dump(&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError("invalid target\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetModulesSearchPathsQuery
-class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed
-{
+class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
public:
- CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "target modules search-paths query",
- "Transform a path using the first applicable image search path.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandArgumentData path_arg;
-
- // Define the first (and only) variant of this arg.
- path_arg.arg_type = eArgTypeDirectoryName;
- path_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (path_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "target modules search-paths query",
+ "Transform a path using the first applicable image search path.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData path_arg;
- ~CommandObjectTargetModulesSearchPathsQuery() override = default;
+ // Define the first (and only) variant of this arg.
+ path_arg.arg_type = eArgTypeDirectoryName;
+ path_arg.arg_repetition = eArgRepeatPlain;
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target)
- {
- if (command.GetArgumentCount() != 1)
- {
- result.AppendError ("query requires one argument\n");
- result.SetStatus (eReturnStatusFailed);
- return result.Succeeded();
- }
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(path_arg);
- ConstString orig(command.GetArgumentAtIndex(0));
- ConstString transformed;
- if (target->GetImageSearchPathList().RemapPath(orig, transformed))
- result.GetOutputStream().Printf("%s\n", transformed.GetCString());
- else
- result.GetOutputStream().Printf("%s\n", orig.GetCString());
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError ("invalid target\n");
- result.SetStatus (eReturnStatusFailed);
- }
+ ~CommandObjectTargetModulesSearchPathsQuery() override = default;
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target) {
+ if (command.GetArgumentCount() != 1) {
+ result.AppendError("query requires one argument\n");
+ result.SetStatus(eReturnStatusFailed);
return result.Succeeded();
+ }
+
+ ConstString orig(command.GetArgumentAtIndex(0));
+ ConstString transformed;
+ if (target->GetImageSearchPathList().RemapPath(orig, transformed))
+ result.GetOutputStream().Printf("%s\n", transformed.GetCString());
+ else
+ result.GetOutputStream().Printf("%s\n", orig.GetCString());
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError("invalid target\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
//----------------------------------------------------------------------
// Static Helper functions
//----------------------------------------------------------------------
-static void
-DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
-{
- if (module)
- {
- StreamString arch_strm;
-
- if (full_triple)
- module->GetArchitecture().DumpTriple(arch_strm);
- else
- arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
- std::string arch_str = arch_strm.GetString();
+static void DumpModuleArchitecture(Stream &strm, Module *module,
+ bool full_triple, uint32_t width) {
+ if (module) {
+ StreamString arch_strm;
- if (width)
- strm.Printf("%-*s", width, arch_str.c_str());
- else
- strm.PutCString(arch_str.c_str());
- }
-}
+ if (full_triple)
+ module->GetArchitecture().DumpTriple(arch_strm);
+ else
+ arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
+ std::string arch_str = arch_strm.GetString();
-static void
-DumpModuleUUID (Stream &strm, Module *module)
-{
- if (module && module->GetUUID().IsValid())
- module->GetUUID().Dump (&strm);
+ if (width)
+ strm.Printf("%-*s", width, arch_str.c_str());
else
- strm.PutCString(" ");
+ strm.PutCString(arch_str);
+ }
}
-static uint32_t
-DumpCompileUnitLineTable (CommandInterpreter &interpreter,
- Stream &strm,
- Module *module,
- const FileSpec &file_spec,
- bool load_addresses)
-{
- uint32_t num_matches = 0;
- if (module)
- {
- SymbolContextList sc_list;
- num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
- 0,
- false,
- eSymbolContextCompUnit,
- sc_list);
-
- for (uint32_t i = 0; i < num_matches; ++i)
- {
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(i, sc))
- {
- if (i > 0)
- strm << "\n\n";
-
- strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
- << module->GetFileSpec().GetFilename() << "\n";
- LineTable *line_table = sc.comp_unit->GetLineTable();
- if (line_table)
- line_table->GetDescription (&strm,
- interpreter.GetExecutionContext().GetTargetPtr(),
- lldb::eDescriptionLevelBrief);
- else
- strm << "No line table";
- }
- }
- }
- return num_matches;
+static void DumpModuleUUID(Stream &strm, Module *module) {
+ if (module && module->GetUUID().IsValid())
+ module->GetUUID().Dump(&strm);
+ else
+ strm.PutCString(" ");
}
-static void
-DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
-{
- if (file_spec_ptr)
- {
- if (width > 0)
- {
- std::string fullpath = file_spec_ptr->GetPath();
- strm.Printf("%-*s", width, fullpath.c_str());
- return;
- }
+static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
+ Stream &strm, Module *module,
+ const FileSpec &file_spec,
+ bool load_addresses) {
+ uint32_t num_matches = 0;
+ if (module) {
+ SymbolContextList sc_list;
+ num_matches = module->ResolveSymbolContextsForFileSpec(
+ file_spec, 0, false, eSymbolContextCompUnit, sc_list);
+
+ for (uint32_t i = 0; i < num_matches; ++i) {
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(i, sc)) {
+ if (i > 0)
+ strm << "\n\n";
+
+ strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
+ << " in `" << module->GetFileSpec().GetFilename() << "\n";
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+ if (line_table)
+ line_table->GetDescription(
+ &strm, interpreter.GetExecutionContext().GetTargetPtr(),
+ lldb::eDescriptionLevelBrief);
else
- {
- file_spec_ptr->Dump(&strm);
- return;
- }
+ strm << "No line table";
+ }
}
- // Keep the width spacing correct if things go wrong...
- if (width > 0)
- strm.Printf("%-*s", width, "");
+ }
+ return num_matches;
}
-static void
-DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
-{
- if (file_spec_ptr)
- {
- if (width > 0)
- strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
- else
- file_spec_ptr->GetDirectory().Dump(&strm);
- return;
+static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
+ uint32_t width) {
+ if (file_spec_ptr) {
+ if (width > 0) {
+ std::string fullpath = file_spec_ptr->GetPath();
+ strm.Printf("%-*s", width, fullpath.c_str());
+ return;
+ } else {
+ file_spec_ptr->Dump(&strm);
+ return;
}
- // Keep the width spacing correct if things go wrong...
- if (width > 0)
- strm.Printf("%-*s", width, "");
+ }
+ // Keep the width spacing correct if things go wrong...
+ if (width > 0)
+ strm.Printf("%-*s", width, "");
}
-static void
-DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
-{
- if (file_spec_ptr)
- {
- if (width > 0)
- strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
- else
- file_spec_ptr->GetFilename().Dump(&strm);
- return;
- }
- // Keep the width spacing correct if things go wrong...
+static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
+ uint32_t width) {
+ if (file_spec_ptr) {
if (width > 0)
- strm.Printf("%-*s", width, "");
+ strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
+ else
+ file_spec_ptr->GetDirectory().Dump(&strm);
+ return;
+ }
+ // Keep the width spacing correct if things go wrong...
+ if (width > 0)
+ strm.Printf("%-*s", width, "");
}
-static size_t
-DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list)
-{
- size_t num_dumped = 0;
- std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
- const size_t num_modules = module_list.GetSize();
- if (num_modules > 0)
- {
- strm.Printf("Dumping headers for %" PRIu64 " module(s).\n", static_cast<uint64_t>(num_modules));
- strm.IndentMore();
- for (size_t image_idx = 0; image_idx < num_modules; ++image_idx)
- {
- Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
- if (module)
- {
- if (num_dumped++ > 0)
- {
- strm.EOL();
- strm.EOL();
- }
- ObjectFile *objfile = module->GetObjectFile();
- objfile->Dump(&strm);
- }
- }
- strm.IndentLess();
- }
- return num_dumped;
+static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
+ uint32_t width) {
+ if (file_spec_ptr) {
+ if (width > 0)
+ strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
+ else
+ file_spec_ptr->GetFilename().Dump(&strm);
+ return;
+ }
+ // Keep the width spacing correct if things go wrong...
+ if (width > 0)
+ strm.Printf("%-*s", width, "");
}
-static void
-DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
-{
- if (module)
- {
- SymbolVendor *sym_vendor = module->GetSymbolVendor ();
- if (sym_vendor)
- {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order);
+static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
+ size_t num_dumped = 0;
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
+ const size_t num_modules = module_list.GetSize();
+ if (num_modules > 0) {
+ strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
+ static_cast<uint64_t>(num_modules));
+ strm.IndentMore();
+ for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
+ if (module) {
+ if (num_dumped++ > 0) {
+ strm.EOL();
+ strm.EOL();
}
+ ObjectFile *objfile = module->GetObjectFile();
+ objfile->Dump(&strm);
+ }
}
+ strm.IndentLess();
+ }
+ return num_dumped;
}
-static void
-DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
-{
- if (module)
- {
- SectionList *section_list = module->GetSectionList();
- if (section_list)
- {
- strm.Printf ("Sections for '%s' (%s):\n",
- module->GetSpecificationDescription().c_str(),
- module->GetArchitecture().GetArchitectureName());
- strm.IndentMore();
- section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX);
- strm.IndentLess();
- }
+static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
+ Module *module, SortOrder sort_order) {
+ if (module) {
+ SymbolVendor *sym_vendor = module->GetSymbolVendor();
+ if (sym_vendor) {
+ Symtab *symtab = sym_vendor->GetSymtab();
+ if (symtab)
+ symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
+ sort_order);
}
+ }
}
-static bool
-DumpModuleSymbolVendor (Stream &strm, Module *module)
-{
- if (module)
- {
- SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
- if (symbol_vendor)
- {
- symbol_vendor->Dump(&strm);
- return true;
- }
+static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
+ Module *module) {
+ if (module) {
+ SectionList *section_list = module->GetSectionList();
+ if (section_list) {
+ strm.Printf("Sections for '%s' (%s):\n",
+ module->GetSpecificationDescription().c_str(),
+ module->GetArchitecture().GetArchitectureName());
+ strm.IndentMore();
+ section_list->Dump(&strm,
+ interpreter.GetExecutionContext().GetTargetPtr(), true,
+ UINT32_MAX);
+ strm.IndentLess();
}
- return false;
+ }
}
-static void
-DumpAddress (ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm)
-{
- strm.IndentMore();
- strm.Indent (" Address: ");
- so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
- strm.PutCString (" (");
- so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
- strm.PutCString (")\n");
- strm.Indent (" Summary: ");
- const uint32_t save_indent = strm.GetIndentLevel ();
- strm.SetIndentLevel (save_indent + 13);
- so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
- strm.SetIndentLevel (save_indent);
- // Print out detailed address information when verbose is enabled
- if (verbose)
- {
- strm.EOL();
- so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
+static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
+ if (module) {
+ SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
+ if (symbol_vendor) {
+ symbol_vendor->Dump(&strm);
+ return true;
}
- strm.IndentLess();
+ }
+ return false;
}
-static bool
-LookupAddressInModule (CommandInterpreter &interpreter,
- Stream &strm,
- Module *module,
- uint32_t resolve_mask,
- lldb::addr_t raw_addr,
- lldb::addr_t offset,
- bool verbose)
-{
- if (module)
- {
- lldb::addr_t addr = raw_addr - offset;
- Address so_addr;
- SymbolContext sc;
- Target *target = interpreter.GetExecutionContext().GetTargetPtr();
- if (target && !target->GetSectionLoadList().IsEmpty())
- {
- if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
- return false;
- else if (so_addr.GetModule().get() != module)
- return false;
- }
- else
- {
- if (!module->ResolveFileAddress (addr, so_addr))
- return false;
- }
+static void DumpAddress(ExecutionContextScope *exe_scope,
+ const Address &so_addr, bool verbose, Stream &strm) {
+ strm.IndentMore();
+ strm.Indent(" Address: ");
+ so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
+ strm.PutCString(" (");
+ so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
+ strm.PutCString(")\n");
+ strm.Indent(" Summary: ");
+ const uint32_t save_indent = strm.GetIndentLevel();
+ strm.SetIndentLevel(save_indent + 13);
+ so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
+ strm.SetIndentLevel(save_indent);
+ // Print out detailed address information when verbose is enabled
+ if (verbose) {
+ strm.EOL();
+ so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
+ }
+ strm.IndentLess();
+}
- ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
- DumpAddress (exe_scope, so_addr, verbose, strm);
-// strm.IndentMore();
-// strm.Indent (" Address: ");
-// so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
-// strm.PutCString (" (");
-// so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
-// strm.PutCString (")\n");
-// strm.Indent (" Summary: ");
-// const uint32_t save_indent = strm.GetIndentLevel ();
-// strm.SetIndentLevel (save_indent + 13);
-// so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
-// strm.SetIndentLevel (save_indent);
-// // Print out detailed address information when verbose is enabled
-// if (verbose)
-// {
-// strm.EOL();
-// so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
-// }
-// strm.IndentLess();
- return true;
+static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
+ Module *module, uint32_t resolve_mask,
+ lldb::addr_t raw_addr, lldb::addr_t offset,
+ bool verbose) {
+ if (module) {
+ lldb::addr_t addr = raw_addr - offset;
+ Address so_addr;
+ SymbolContext sc;
+ Target *target = interpreter.GetExecutionContext().GetTargetPtr();
+ if (target && !target->GetSectionLoadList().IsEmpty()) {
+ if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
+ return false;
+ else if (so_addr.GetModule().get() != module)
+ return false;
+ } else {
+ if (!module->ResolveFileAddress(addr, so_addr))
+ return false;
}
- return false;
+ ExecutionContextScope *exe_scope =
+ interpreter.GetExecutionContext().GetBestExecutionContextScope();
+ DumpAddress(exe_scope, so_addr, verbose, strm);
+ // strm.IndentMore();
+ // strm.Indent (" Address: ");
+ // so_addr.Dump (&strm, exe_scope,
+ // Address::DumpStyleModuleWithFileAddress);
+ // strm.PutCString (" (");
+ // so_addr.Dump (&strm, exe_scope,
+ // Address::DumpStyleSectionNameOffset);
+ // strm.PutCString (")\n");
+ // strm.Indent (" Summary: ");
+ // const uint32_t save_indent = strm.GetIndentLevel ();
+ // strm.SetIndentLevel (save_indent + 13);
+ // so_addr.Dump (&strm, exe_scope,
+ // Address::DumpStyleResolvedDescription);
+ // strm.SetIndentLevel (save_indent);
+ // // Print out detailed address information when verbose is enabled
+ // if (verbose)
+ // {
+ // strm.EOL();
+ // so_addr.Dump (&strm, exe_scope,
+ // Address::DumpStyleDetailedSymbolContext);
+ // }
+ // strm.IndentLess();
+ return true;
+ }
+
+ return false;
}
-static uint32_t
-LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
-{
- if (module)
- {
- SymbolContext sc;
-
- SymbolVendor *sym_vendor = module->GetSymbolVendor ();
- if (sym_vendor)
- {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- {
- std::vector<uint32_t> match_indexes;
- ConstString symbol_name (name);
- uint32_t num_matches = 0;
- if (name_is_regex)
- {
- RegularExpression name_regexp(name);
- num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
- eSymbolTypeAny,
- match_indexes);
- }
- else
- {
- num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
- }
+static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
+ Stream &strm, Module *module,
+ const char *name, bool name_is_regex,
+ bool verbose) {
+ if (module) {
+ SymbolContext sc;
+
+ SymbolVendor *sym_vendor = module->GetSymbolVendor();
+ if (sym_vendor) {
+ Symtab *symtab = sym_vendor->GetSymtab();
+ if (symtab) {
+ std::vector<uint32_t> match_indexes;
+ ConstString symbol_name(name);
+ uint32_t num_matches = 0;
+ if (name_is_regex) {
+ RegularExpression name_regexp(symbol_name.GetStringRef());
+ num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
+ name_regexp, eSymbolTypeAny, match_indexes);
+ } else {
+ num_matches =
+ symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
+ }
- if (num_matches > 0)
- {
- strm.Indent ();
- strm.Printf("%u symbols match %s'%s' in ", num_matches,
- name_is_regex ? "the regular expression " : "", name);
- DumpFullpath (strm, &module->GetFileSpec(), 0);
- strm.PutCString(":\n");
- strm.IndentMore ();
- for (uint32_t i = 0; i < num_matches; ++i)
- {
- Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
- if (symbol && symbol->ValueIsAddress())
- {
- DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(),
- symbol->GetAddressRef(),
- verbose,
- strm);
- }
- }
- strm.IndentLess ();
- return num_matches;
- }
+ if (num_matches > 0) {
+ strm.Indent();
+ strm.Printf("%u symbols match %s'%s' in ", num_matches,
+ name_is_regex ? "the regular expression " : "", name);
+ DumpFullpath(strm, &module->GetFileSpec(), 0);
+ strm.PutCString(":\n");
+ strm.IndentMore();
+ for (uint32_t i = 0; i < num_matches; ++i) {
+ Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
+ if (symbol && symbol->ValueIsAddress()) {
+ DumpAddress(interpreter.GetExecutionContext()
+ .GetBestExecutionContextScope(),
+ symbol->GetAddressRef(), verbose, strm);
}
+ }
+ strm.IndentLess();
+ return num_matches;
}
+ }
}
- return 0;
+ }
+ return 0;
}
-static void
-DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose)
-{
- strm.IndentMore ();
+static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
+ Stream &strm, SymbolContextList &sc_list,
+ bool verbose) {
+ strm.IndentMore();
- const uint32_t num_matches = sc_list.GetSize();
+ const uint32_t num_matches = sc_list.GetSize();
- for (uint32_t i = 0; i < num_matches; ++i)
- {
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(i, sc))
- {
- AddressRange range;
+ for (uint32_t i = 0; i < num_matches; ++i) {
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(i, sc)) {
+ AddressRange range;
- sc.GetAddressRange(eSymbolContextEverything,
- 0,
- true,
- range);
+ sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
- DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm);
- }
+ DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
}
- strm.IndentLess ();
+ }
+ strm.IndentLess();
}
-static size_t
-LookupFunctionInModule (CommandInterpreter &interpreter,
- Stream &strm,
- Module *module,
- const char *name,
- bool name_is_regex,
- bool include_inlines,
- bool include_symbols,
- bool verbose)
-{
- if (module && name && name[0])
- {
- SymbolContextList sc_list;
- const bool append = true;
- size_t num_matches = 0;
- if (name_is_regex)
- {
- RegularExpression function_name_regex (name);
- num_matches = module->FindFunctions (function_name_regex,
- include_symbols,
- include_inlines,
- append,
- sc_list);
- }
- else
- {
- ConstString function_name (name);
- num_matches = module->FindFunctions(function_name,
- nullptr,
- eFunctionNameTypeAuto,
- include_symbols,
- include_inlines,
- append,
- sc_list);
- }
-
- if (num_matches)
- {
- strm.Indent ();
- strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : "");
- DumpFullpath (strm, &module->GetFileSpec(), 0);
- strm.PutCString(":\n");
- DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
- }
- return num_matches;
+static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
+ Stream &strm, Module *module,
+ const char *name, bool name_is_regex,
+ bool include_inlines, bool include_symbols,
+ bool verbose) {
+ if (module && name && name[0]) {
+ SymbolContextList sc_list;
+ const bool append = true;
+ size_t num_matches = 0;
+ if (name_is_regex) {
+ RegularExpression function_name_regex((llvm::StringRef(name)));
+ num_matches = module->FindFunctions(function_name_regex, include_symbols,
+ include_inlines, append, sc_list);
+ } else {
+ ConstString function_name(name);
+ num_matches = module->FindFunctions(
+ function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
+ include_inlines, append, sc_list);
}
- return 0;
-}
-static size_t
-LookupTypeInModule (CommandInterpreter &interpreter,
- Stream &strm,
- Module *module,
- const char *name_cstr,
- bool name_is_regex)
-{
- if (module && name_cstr && name_cstr[0])
- {
- TypeList type_list;
- const uint32_t max_num_matches = UINT32_MAX;
- size_t num_matches = 0;
- bool name_is_fully_qualified = false;
- SymbolContext sc;
-
- ConstString name(name_cstr);
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, searched_symbol_files, type_list);
-
- if (num_matches)
- {
- strm.Indent ();
- strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, num_matches > 1 ? "es" : "");
- DumpFullpath (strm, &module->GetFileSpec(), 0);
- strm.PutCString(":\n");
- for (TypeSP type_sp : type_list.Types())
- {
- if (type_sp)
- {
- // Resolve the clang type so that any forward references
- // to types that haven't yet been parsed will get parsed.
- type_sp->GetFullCompilerType ();
- type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
- // Print all typedef chains
- TypeSP typedef_type_sp (type_sp);
- TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
- while (typedefed_type_sp)
- {
- strm.EOL();
- strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString());
- typedefed_type_sp->GetFullCompilerType ();
- typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
- typedef_type_sp = typedefed_type_sp;
- typedefed_type_sp = typedef_type_sp->GetTypedefType();
- }
- }
- strm.EOL();
- }
- }
- return num_matches;
+ if (num_matches) {
+ strm.Indent();
+ strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
+ num_matches > 1 ? "es" : "");
+ DumpFullpath(strm, &module->GetFileSpec(), 0);
+ strm.PutCString(":\n");
+ DumpSymbolContextList(
+ interpreter.GetExecutionContext().GetBestExecutionContextScope(),
+ strm, sc_list, verbose);
}
- return 0;
+ return num_matches;
+ }
+ return 0;
}
-static size_t
-LookupTypeHere (CommandInterpreter &interpreter,
- Stream &strm,
- const SymbolContext &sym_ctx,
- const char *name_cstr,
- bool name_is_regex)
-{
- if (!sym_ctx.module_sp)
- return 0;
-
+static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
+ Module *module, const char *name_cstr,
+ bool name_is_regex) {
+ if (module && name_cstr && name_cstr[0]) {
TypeList type_list;
const uint32_t max_num_matches = UINT32_MAX;
- size_t num_matches = 1;
+ size_t num_matches = 0;
bool name_is_fully_qualified = false;
+ SymbolContext sc;
ConstString name(name_cstr);
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, searched_symbol_files, type_list);
-
- if (num_matches)
- {
- strm.Indent ();
- strm.PutCString("Best match found in ");
- DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0);
- strm.PutCString(":\n");
-
- TypeSP type_sp (type_list.GetTypeAtIndex(0));
- if (type_sp)
- {
- // Resolve the clang type so that any forward references
- // to types that haven't yet been parsed will get parsed.
- type_sp->GetFullCompilerType ();
- type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
- // Print all typedef chains
- TypeSP typedef_type_sp (type_sp);
- TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
- while (typedefed_type_sp)
- {
- strm.EOL();
- strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString());
- typedefed_type_sp->GetFullCompilerType ();
- typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
- typedef_type_sp = typedefed_type_sp;
- typedefed_type_sp = typedef_type_sp->GetTypedefType();
- }
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ num_matches =
+ module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches,
+ searched_symbol_files, type_list);
+
+ if (num_matches) {
+ strm.Indent();
+ strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
+ num_matches > 1 ? "es" : "");
+ DumpFullpath(strm, &module->GetFileSpec(), 0);
+ strm.PutCString(":\n");
+ for (TypeSP type_sp : type_list.Types()) {
+ if (type_sp) {
+ // Resolve the clang type so that any forward references
+ // to types that haven't yet been parsed will get parsed.
+ type_sp->GetFullCompilerType();
+ type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
+ // Print all typedef chains
+ TypeSP typedef_type_sp(type_sp);
+ TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
+ while (typedefed_type_sp) {
+ strm.EOL();
+ strm.Printf(" typedef '%s': ",
+ typedef_type_sp->GetName().GetCString());
+ typedefed_type_sp->GetFullCompilerType();
+ typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
+ true);
+ typedef_type_sp = typedefed_type_sp;
+ typedefed_type_sp = typedef_type_sp->GetTypedefType();
+ }
}
strm.EOL();
+ }
}
return num_matches;
+ }
+ return 0;
}
-static uint32_t
-LookupFileAndLineInModule (CommandInterpreter &interpreter,
- Stream &strm,
- Module *module,
- const FileSpec &file_spec,
- uint32_t line,
- bool check_inlines,
- bool verbose)
-{
- if (module && file_spec)
- {
- SymbolContextList sc_list;
- const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
- eSymbolContextEverything, sc_list);
- if (num_matches > 0)
- {
- strm.Indent ();
- strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
- strm << file_spec;
- if (line > 0)
- strm.Printf (":%u", line);
- strm << " in ";
- DumpFullpath (strm, &module->GetFileSpec(), 0);
- strm.PutCString(":\n");
- DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
- return num_matches;
- }
- }
+static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
+ const SymbolContext &sym_ctx,
+ const char *name_cstr, bool name_is_regex) {
+ if (!sym_ctx.module_sp)
return 0;
+
+ TypeList type_list;
+ const uint32_t max_num_matches = UINT32_MAX;
+ size_t num_matches = 1;
+ bool name_is_fully_qualified = false;
+
+ ConstString name(name_cstr);
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ num_matches = sym_ctx.module_sp->FindTypes(
+ sym_ctx, name, name_is_fully_qualified, max_num_matches,
+ searched_symbol_files, type_list);
+
+ if (num_matches) {
+ strm.Indent();
+ strm.PutCString("Best match found in ");
+ DumpFullpath(strm, &sym_ctx.module_sp->GetFileSpec(), 0);
+ strm.PutCString(":\n");
+
+ TypeSP type_sp(type_list.GetTypeAtIndex(0));
+ if (type_sp) {
+ // Resolve the clang type so that any forward references
+ // to types that haven't yet been parsed will get parsed.
+ type_sp->GetFullCompilerType();
+ type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
+ // Print all typedef chains
+ TypeSP typedef_type_sp(type_sp);
+ TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
+ while (typedefed_type_sp) {
+ strm.EOL();
+ strm.Printf(" typedef '%s': ",
+ typedef_type_sp->GetName().GetCString());
+ typedefed_type_sp->GetFullCompilerType();
+ typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
+ typedef_type_sp = typedefed_type_sp;
+ typedefed_type_sp = typedef_type_sp->GetTypedefType();
+ }
+ }
+ strm.EOL();
+ }
+ return num_matches;
}
-static size_t
-FindModulesByName (Target *target,
- const char *module_name,
- ModuleList &module_list,
- bool check_global_list)
-{
- FileSpec module_file_spec(module_name, false);
- ModuleSpec module_spec (module_file_spec);
-
- const size_t initial_size = module_list.GetSize ();
-
- if (check_global_list)
- {
- // Check the global list
- std::lock_guard<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex());
- const size_t num_modules = Module::GetNumberAllocatedModules();
- ModuleSP module_sp;
- for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
- {
- Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
-
- if (module)
- {
- if (module->MatchesModuleSpec (module_spec))
- {
- module_sp = module->shared_from_this();
- module_list.AppendIfNeeded(module_sp);
- }
- }
- }
+static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
+ Stream &strm, Module *module,
+ const FileSpec &file_spec,
+ uint32_t line, bool check_inlines,
+ bool verbose) {
+ if (module && file_spec) {
+ SymbolContextList sc_list;
+ const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
+ file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
+ if (num_matches > 0) {
+ strm.Indent();
+ strm.Printf("%u match%s found in ", num_matches,
+ num_matches > 1 ? "es" : "");
+ strm << file_spec;
+ if (line > 0)
+ strm.Printf(":%u", line);
+ strm << " in ";
+ DumpFullpath(strm, &module->GetFileSpec(), 0);
+ strm.PutCString(":\n");
+ DumpSymbolContextList(
+ interpreter.GetExecutionContext().GetBestExecutionContextScope(),
+ strm, sc_list, verbose);
+ return num_matches;
}
- else
- {
- if (target)
- {
- const size_t num_matches = target->GetImages().FindModules (module_spec, module_list);
-
- // Not found in our module list for our target, check the main
- // shared module list in case it is a extra file used somewhere
- // else
- if (num_matches == 0)
- {
- module_spec.GetArchitecture() = target->GetArchitecture();
- ModuleList::FindSharedModules (module_spec, module_list);
- }
- }
- else
- {
- ModuleList::FindSharedModules (module_spec,module_list);
+ }
+ return 0;
+}
+
+static size_t FindModulesByName(Target *target, const char *module_name,
+ ModuleList &module_list,
+ bool check_global_list) {
+ FileSpec module_file_spec(module_name, false);
+ ModuleSpec module_spec(module_file_spec);
+
+ const size_t initial_size = module_list.GetSize();
+
+ if (check_global_list) {
+ // Check the global list
+ std::lock_guard<std::recursive_mutex> guard(
+ Module::GetAllocationModuleCollectionMutex());
+ const size_t num_modules = Module::GetNumberAllocatedModules();
+ ModuleSP module_sp;
+ for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
+
+ if (module) {
+ if (module->MatchesModuleSpec(module_spec)) {
+ module_sp = module->shared_from_this();
+ module_list.AppendIfNeeded(module_sp);
}
+ }
+ }
+ } else {
+ if (target) {
+ const size_t num_matches =
+ target->GetImages().FindModules(module_spec, module_list);
+
+ // Not found in our module list for our target, check the main
+ // shared module list in case it is a extra file used somewhere
+ // else
+ if (num_matches == 0) {
+ module_spec.GetArchitecture() = target->GetArchitecture();
+ ModuleList::FindSharedModules(module_spec, module_list);
+ }
+ } else {
+ ModuleList::FindSharedModules(module_spec, module_list);
}
+ }
- return module_list.GetSize () - initial_size;
+ return module_list.GetSize() - initial_size;
}
#pragma mark CommandObjectTargetModulesModuleAutoComplete
@@ -2029,55 +1799,47 @@ FindModulesByName (Target *target,
// paths
//----------------------------------------------------------------------
-class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed
-{
+class CommandObjectTargetModulesModuleAutoComplete
+ : public CommandObjectParsed {
public:
- CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
- const char *name,
- const char *help,
- const char *syntax) :
- CommandObjectParsed (interpreter, name, help, syntax)
- {
- CommandArgumentEntry arg;
- CommandArgumentData file_arg;
-
- // Define the first (and only) variant of this arg.
- file_arg.arg_type = eArgTypeFilename;
- file_arg.arg_repetition = eArgRepeatStar;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (file_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectTargetModulesModuleAutoComplete() override = default;
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- // Arguments are the standard module completer.
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eModuleCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
- }
+ CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
+ const char *name,
+ const char *help,
+ const char *syntax)
+ : CommandObjectParsed(interpreter, name, help, syntax) {
+ CommandArgumentEntry arg;
+ CommandArgumentData file_arg;
+
+ // Define the first (and only) variant of this arg.
+ file_arg.arg_type = eArgTypeFilename;
+ file_arg.arg_repetition = eArgRepeatStar;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(file_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectTargetModulesModuleAutoComplete() override = default;
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ // Arguments are the standard module completer.
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index));
+ completion_str.erase(cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
};
#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
@@ -2087,308 +1849,257 @@ public:
// file paths
//----------------------------------------------------------------------
-class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed
-{
+class CommandObjectTargetModulesSourceFileAutoComplete
+ : public CommandObjectParsed {
public:
- CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
- const char *name,
- const char *help,
- const char *syntax,
- uint32_t flags) :
- CommandObjectParsed (interpreter, name, help, syntax, flags)
- {
- CommandArgumentEntry arg;
- CommandArgumentData source_file_arg;
-
- // Define the first (and only) variant of this arg.
- source_file_arg.arg_type = eArgTypeSourceFile;
- source_file_arg.arg_repetition = eArgRepeatPlus;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (source_file_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
-
- ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- // Arguments are the standard source file completer.
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eSourceFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
- }
+ CommandObjectTargetModulesSourceFileAutoComplete(
+ CommandInterpreter &interpreter, const char *name, const char *help,
+ const char *syntax, uint32_t flags)
+ : CommandObjectParsed(interpreter, name, help, syntax, flags) {
+ CommandArgumentEntry arg;
+ CommandArgumentData source_file_arg;
+
+ // Define the first (and only) variant of this arg.
+ source_file_arg.arg_type = eArgTypeSourceFile;
+ source_file_arg.arg_repetition = eArgRepeatPlus;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(source_file_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ // Arguments are the standard source file completer.
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index));
+ completion_str.erase(cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
};
#pragma mark CommandObjectTargetModulesDumpObjfile
-class CommandObjectTargetModulesDumpObjfile : public CommandObjectTargetModulesModuleAutoComplete
-{
+class CommandObjectTargetModulesDumpObjfile
+ : public CommandObjectTargetModulesModuleAutoComplete {
public:
- CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
- : CommandObjectTargetModulesModuleAutoComplete(interpreter, "target modules dump objfile",
- "Dump the object file headers from one or more target modules.",
- nullptr)
- {
- }
+ CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
+ : CommandObjectTargetModulesModuleAutoComplete(
+ interpreter, "target modules dump objfile",
+ "Dump the object file headers from one or more target modules.",
+ nullptr) {}
- ~CommandObjectTargetModulesDumpObjfile() override = default;
+ ~CommandObjectTargetModulesDumpObjfile() override = default;
protected:
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError("invalid target, create a debug target using the 'target create' command");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
- size_t num_dumped = 0;
- if (command.GetArgumentCount() == 0)
- {
- // Dump all headers for all modules images
- num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(), target->GetImages());
- if (num_dumped == 0)
- {
- result.AppendError("the target has no associated executable images");
- result.SetStatus(eReturnStatusFailed);
- }
- }
- else
- {
- // Find the modules that match the basename or full path.
- ModuleList module_list;
- const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
- {
- size_t num_matched = FindModulesByName(target, arg_cstr, module_list, true);
- if (num_matched == 0)
- {
- result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
- }
- }
- // Dump all the modules we found.
- num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
+ size_t num_dumped = 0;
+ if (command.GetArgumentCount() == 0) {
+ // Dump all headers for all modules images
+ num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
+ target->GetImages());
+ if (num_dumped == 0) {
+ result.AppendError("the target has no associated executable images");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ // Find the modules that match the basename or full path.
+ ModuleList module_list;
+ const char *arg_cstr;
+ for (int arg_idx = 0;
+ (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
+ ++arg_idx) {
+ size_t num_matched =
+ FindModulesByName(target, arg_cstr, module_list, true);
+ if (num_matched == 0) {
+ result.AppendWarningWithFormat(
+ "Unable to find an image that matches '%s'.\n", arg_cstr);
}
+ }
+ // Dump all the modules we found.
+ num_dumped =
+ DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
+ }
- if (num_dumped > 0)
- {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError("no matching executable images found");
- result.SetStatus(eReturnStatusFailed);
- }
- return result.Succeeded();
+ if (num_dumped > 0) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError("no matching executable images found");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetModulesDumpSymtab
-class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
-{
+static OptionEnumValueElement g_sort_option_enumeration[4] = {
+ {eSortOrderNone, "none",
+ "No sorting, use the original symbol table order."},
+ {eSortOrderByAddress, "address", "Sort output by symbol address."},
+ {eSortOrderByName, "name", "Sort output by symbol name."},
+ {0, nullptr, nullptr}};
+
+static OptionDefinition g_target_modules_dump_symtab_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table." }
+ // clang-format on
+};
+
+class CommandObjectTargetModulesDumpSymtab
+ : public CommandObjectTargetModulesModuleAutoComplete {
public:
- CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
- CommandObjectTargetModulesModuleAutoComplete(interpreter,
- "target modules dump symtab",
- "Dump the symbol table from one or more target modules.",
- nullptr),
- m_options(interpreter)
- {
+ CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
+ : CommandObjectTargetModulesModuleAutoComplete(
+ interpreter, "target modules dump symtab",
+ "Dump the symbol table from one or more target modules.", nullptr),
+ m_options() {}
+
+ ~CommandObjectTargetModulesDumpSymtab() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 's':
+ m_sort_order = (SortOrder)Args::StringToOptionEnum(
+ option_arg, GetDefinitions()[option_idx].enum_values,
+ eSortOrderNone, error);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
}
- ~CommandObjectTargetModulesDumpSymtab() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_sort_order = eSortOrderNone;
}
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter),
- m_sort_order (eSortOrderNone)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 's':
- m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
- g_option_table[option_idx].enum_values,
- eSortOrderNone,
- error);
- break;
-
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_sort_order = eSortOrderNone;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
+ }
- SortOrder m_sort_order;
- };
+ SortOrder m_sort_order;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- uint32_t num_dumped = 0;
-
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
-
- if (command.GetArgumentCount() == 0)
- {
- // Dump all sections for all modules images
- std::lock_guard<std::recursive_mutex> guard(target->GetImages().GetMutex());
- const size_t num_modules = target->GetImages().GetSize();
- if (num_modules > 0)
- {
- result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64 " modules.\n", (uint64_t)num_modules);
- for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
- {
- if (num_dumped > 0)
- {
- result.GetOutputStream().EOL();
- result.GetOutputStream().EOL();
- }
- num_dumped++;
- DumpModuleSymtab (m_interpreter,
- result.GetOutputStream(),
- target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
- m_options.m_sort_order);
- }
- }
- else
- {
- result.AppendError ("the target has no associated executable images");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ uint32_t num_dumped = 0;
+
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+
+ if (command.GetArgumentCount() == 0) {
+ // Dump all sections for all modules images
+ std::lock_guard<std::recursive_mutex> guard(
+ target->GetImages().GetMutex());
+ const size_t num_modules = target->GetImages().GetSize();
+ if (num_modules > 0) {
+ result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
+ " modules.\n",
+ (uint64_t)num_modules);
+ for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ if (num_dumped > 0) {
+ result.GetOutputStream().EOL();
+ result.GetOutputStream().EOL();
}
- else
- {
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
- {
- ModuleList module_list;
- const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
- if (num_matches > 0)
- {
- for (size_t i = 0; i < num_matches; ++i)
- {
- Module *module = module_list.GetModulePointerAtIndex(i);
- if (module)
- {
- if (num_dumped > 0)
- {
- result.GetOutputStream().EOL();
- result.GetOutputStream().EOL();
- }
- num_dumped++;
- DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
- }
- }
- }
- else
- result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
+ num_dumped++;
+ DumpModuleSymtab(
+ m_interpreter, result.GetOutputStream(),
+ target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
+ m_options.m_sort_order);
+ }
+ } else {
+ result.AppendError("the target has no associated executable images");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr;
+ for (int arg_idx = 0;
+ (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
+ ++arg_idx) {
+ ModuleList module_list;
+ const size_t num_matches =
+ FindModulesByName(target, arg_cstr, module_list, true);
+ if (num_matches > 0) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ Module *module = module_list.GetModulePointerAtIndex(i);
+ if (module) {
+ if (num_dumped > 0) {
+ result.GetOutputStream().EOL();
+ result.GetOutputStream().EOL();
}
+ num_dumped++;
+ DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
+ module, m_options.m_sort_order);
+ }
}
-
- if (num_dumped > 0)
- result.SetStatus (eReturnStatusSuccessFinishResult);
- else
- {
- result.AppendError ("no matching executable images found");
- result.SetStatus (eReturnStatusFailed);
- }
+ } else
+ result.AppendWarningWithFormat(
+ "Unable to find an image that matches '%s'.\n", arg_cstr);
}
- return result.Succeeded();
- }
-
- CommandOptions m_options;
-};
+ }
-static OptionEnumValueElement
-g_sort_option_enumeration[4] =
-{
- { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
- { eSortOrderByAddress, "address", "Sort output by symbol address."},
- { eSortOrderByName, "name", "Sort output by symbol name."},
- { 0, nullptr, nullptr }
-};
+ if (num_dumped > 0)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else {
+ result.AppendError("no matching executable images found");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
#pragma mark CommandObjectTargetModulesDumpSections
@@ -2397,99 +2108,89 @@ CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
// Image section dumping command
//----------------------------------------------------------------------
-class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
-{
+class CommandObjectTargetModulesDumpSections
+ : public CommandObjectTargetModulesModuleAutoComplete {
public:
- CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
- CommandObjectTargetModulesModuleAutoComplete(interpreter,
- "target modules dump sections",
- "Dump the sections from one or more target modules.",
- //"target modules dump sections [<file1> ...]")
- nullptr)
- {
- }
+ CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
+ : CommandObjectTargetModulesModuleAutoComplete(
+ interpreter, "target modules dump sections",
+ "Dump the sections from one or more target modules.",
+ //"target modules dump sections [<file1> ...]")
+ nullptr) {}
- ~CommandObjectTargetModulesDumpSections() override = default;
+ ~CommandObjectTargetModulesDumpSections() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ uint32_t num_dumped = 0;
+
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+
+ if (command.GetArgumentCount() == 0) {
+ // Dump all sections for all modules images
+ const size_t num_modules = target->GetImages().GetSize();
+ if (num_modules > 0) {
+ result.GetOutputStream().Printf("Dumping sections for %" PRIu64
+ " modules.\n",
+ (uint64_t)num_modules);
+ for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ num_dumped++;
+ DumpModuleSections(
+ m_interpreter, result.GetOutputStream(),
+ target->GetImages().GetModulePointerAtIndex(image_idx));
+ }
+ } else {
+ result.AppendError("the target has no associated executable images");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else
- {
- uint32_t num_dumped = 0;
-
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
-
- if (command.GetArgumentCount() == 0)
- {
- // Dump all sections for all modules images
- const size_t num_modules = target->GetImages().GetSize();
- if (num_modules > 0)
- {
- result.GetOutputStream().Printf("Dumping sections for %" PRIu64 " modules.\n", (uint64_t)num_modules);
- for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
- {
- num_dumped++;
- DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
- }
- }
- else
- {
- result.AppendError ("the target has no associated executable images");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
- {
- ModuleList module_list;
- const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
- if (num_matches > 0)
- {
- for (size_t i = 0; i < num_matches; ++i)
- {
- Module *module = module_list.GetModulePointerAtIndex(i);
- if (module)
- {
- num_dumped++;
- DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
- }
- }
- }
- else
- {
- // Check the global list
- std::lock_guard<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex());
-
- result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
- }
- }
- }
-
- if (num_dumped > 0)
- result.SetStatus (eReturnStatusSuccessFinishResult);
- else
- {
- result.AppendError ("no matching executable images found");
- result.SetStatus (eReturnStatusFailed);
+ } else {
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr;
+ for (int arg_idx = 0;
+ (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
+ ++arg_idx) {
+ ModuleList module_list;
+ const size_t num_matches =
+ FindModulesByName(target, arg_cstr, module_list, true);
+ if (num_matches > 0) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ Module *module = module_list.GetModulePointerAtIndex(i);
+ if (module) {
+ num_dumped++;
+ DumpModuleSections(m_interpreter, result.GetOutputStream(),
+ module);
+ }
}
+ } else {
+ // Check the global list
+ std::lock_guard<std::recursive_mutex> guard(
+ Module::GetAllocationModuleCollectionMutex());
+
+ result.AppendWarningWithFormat(
+ "Unable to find an image that matches '%s'.\n", arg_cstr);
+ }
}
- return result.Succeeded();
+ }
+
+ if (num_dumped > 0)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else {
+ result.AppendError("no matching executable images found");
+ result.SetStatus(eReturnStatusFailed);
+ }
}
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetModulesDumpSymfile
@@ -2498,96 +2199,85 @@ protected:
// Image debug symbol dumping command
//----------------------------------------------------------------------
-class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
-{
+class CommandObjectTargetModulesDumpSymfile
+ : public CommandObjectTargetModulesModuleAutoComplete {
public:
- CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
- CommandObjectTargetModulesModuleAutoComplete(interpreter,
- "target modules dump symfile",
- "Dump the debug symbol file for one or more target modules.",
- //"target modules dump symfile [<file1> ...]")
- nullptr)
- {
- }
+ CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
+ : CommandObjectTargetModulesModuleAutoComplete(
+ interpreter, "target modules dump symfile",
+ "Dump the debug symbol file for one or more target modules.",
+ //"target modules dump symfile [<file1> ...]")
+ nullptr) {}
- ~CommandObjectTargetModulesDumpSymfile() override = default;
+ ~CommandObjectTargetModulesDumpSymfile() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ uint32_t num_dumped = 0;
+
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+
+ if (command.GetArgumentCount() == 0) {
+ // Dump all sections for all modules images
+ const ModuleList &target_modules = target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+ const size_t num_modules = target_modules.GetSize();
+ if (num_modules > 0) {
+ result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
+ " modules.\n",
+ (uint64_t)num_modules);
+ for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ if (DumpModuleSymbolVendor(
+ result.GetOutputStream(),
+ target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
+ num_dumped++;
+ }
+ } else {
+ result.AppendError("the target has no associated executable images");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else
- {
- uint32_t num_dumped = 0;
-
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
-
- if (command.GetArgumentCount() == 0)
- {
- // Dump all sections for all modules images
- const ModuleList &target_modules = target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- const size_t num_modules = target_modules.GetSize();
- if (num_modules > 0)
- {
- result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64 " modules.\n", (uint64_t)num_modules);
- for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
- {
- if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
- num_dumped++;
- }
- }
- else
- {
- result.AppendError ("the target has no associated executable images");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
- {
- ModuleList module_list;
- const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
- if (num_matches > 0)
- {
- for (size_t i = 0; i < num_matches; ++i)
- {
- Module *module = module_list.GetModulePointerAtIndex(i);
- if (module)
- {
- if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
- num_dumped++;
- }
- }
- }
- else
- result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
- }
- }
-
- if (num_dumped > 0)
- result.SetStatus (eReturnStatusSuccessFinishResult);
- else
- {
- result.AppendError ("no matching executable images found");
- result.SetStatus (eReturnStatusFailed);
+ } else {
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr;
+ for (int arg_idx = 0;
+ (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
+ ++arg_idx) {
+ ModuleList module_list;
+ const size_t num_matches =
+ FindModulesByName(target, arg_cstr, module_list, true);
+ if (num_matches > 0) {
+ for (size_t i = 0; i < num_matches; ++i) {
+ Module *module = module_list.GetModulePointerAtIndex(i);
+ if (module) {
+ if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
+ num_dumped++;
+ }
}
+ } else
+ result.AppendWarningWithFormat(
+ "Unable to find an image that matches '%s'.\n", arg_cstr);
}
- return result.Succeeded();
+ }
+
+ if (num_dumped > 0)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else {
+ result.AppendError("no matching executable images found");
+ result.SetStatus(eReturnStatusFailed);
+ }
}
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetModulesDumpLineTable
@@ -2596,77 +2286,68 @@ protected:
// Image debug line table dumping command
//----------------------------------------------------------------------
-class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
-{
+class CommandObjectTargetModulesDumpLineTable
+ : public CommandObjectTargetModulesSourceFileAutoComplete {
public:
- CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
- CommandObjectTargetModulesSourceFileAutoComplete(interpreter,
- "target modules dump line-table",
- "Dump the line table for one or more compilation units.",
- nullptr,
- eCommandRequiresTarget)
- {
- }
+ CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
+ : CommandObjectTargetModulesSourceFileAutoComplete(
+ interpreter, "target modules dump line-table",
+ "Dump the line table for one or more compilation units.", nullptr,
+ eCommandRequiresTarget) {}
- ~CommandObjectTargetModulesDumpLineTable() override = default;
+ ~CommandObjectTargetModulesDumpLineTable() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_exe_ctx.GetTargetPtr();
- uint32_t total_num_dumped = 0;
-
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
-
- if (command.GetArgumentCount() == 0)
- {
- result.AppendError ("file option must be specified.");
- result.SetStatus (eReturnStatusFailed);
- return result.Succeeded();
- }
- else
- {
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx)
- {
- FileSpec file_spec(arg_cstr, false);
-
- const ModuleList &target_modules = target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- const size_t num_modules = target_modules.GetSize();
- if (num_modules > 0)
- {
- uint32_t num_dumped = 0;
- for (uint32_t i = 0; i<num_modules; ++i)
- {
- if (DumpCompileUnitLineTable (m_interpreter,
- result.GetOutputStream(),
- target_modules.GetModulePointerAtIndexUnlocked(i),
- file_spec,
- m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive()))
- num_dumped++;
- }
- if (num_dumped == 0)
- result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
- else
- total_num_dumped += num_dumped;
- }
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_exe_ctx.GetTargetPtr();
+ uint32_t total_num_dumped = 0;
+
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+
+ if (command.GetArgumentCount() == 0) {
+ result.AppendError("file option must be specified.");
+ result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
+ } else {
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr;
+ for (int arg_idx = 0;
+ (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
+ ++arg_idx) {
+ FileSpec file_spec(arg_cstr, false);
+
+ const ModuleList &target_modules = target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+ const size_t num_modules = target_modules.GetSize();
+ if (num_modules > 0) {
+ uint32_t num_dumped = 0;
+ for (uint32_t i = 0; i < num_modules; ++i) {
+ if (DumpCompileUnitLineTable(
+ m_interpreter, result.GetOutputStream(),
+ target_modules.GetModulePointerAtIndexUnlocked(i),
+ file_spec, m_exe_ctx.GetProcessPtr() &&
+ m_exe_ctx.GetProcessRef().IsAlive()))
+ num_dumped++;
+ }
+ if (num_dumped == 0)
+ result.AppendWarningWithFormat(
+ "No source filenames matched '%s'.\n", arg_cstr);
+ else
+ total_num_dumped += num_dumped;
}
+ }
+ }
- if (total_num_dumped > 0)
- result.SetStatus (eReturnStatusSuccessFinishResult);
- else
- {
- result.AppendError ("no source filenames matched any command arguments");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ if (total_num_dumped > 0)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else {
+ result.AppendError("no source filenames matched any command arguments");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetModulesDump
@@ -2675,901 +2356,799 @@ protected:
// Dump multi-word command for target modules
//----------------------------------------------------------------------
-class CommandObjectTargetModulesDump : public CommandObjectMultiword
-{
+class CommandObjectTargetModulesDump : public CommandObjectMultiword {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
- : CommandObjectMultiword(
- interpreter, "target modules dump", "Commands for dumping information about one or more target modules.",
- "target modules dump [headers|symtab|sections|symfile|line-table] [<file1> <file2> ...]")
- {
- LoadSubCommand("objfile", CommandObjectSP(new CommandObjectTargetModulesDumpObjfile(interpreter)));
- LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
- LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
- LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
- LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
- }
-
- ~CommandObjectTargetModulesDump() override = default;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "target modules dump",
+ "Commands for dumping information about one or "
+ "more target modules.",
+ "target modules dump "
+ "[headers|symtab|sections|symfile|line-table] "
+ "[<file1> <file2> ...]") {
+ LoadSubCommand("objfile",
+ CommandObjectSP(
+ new CommandObjectTargetModulesDumpObjfile(interpreter)));
+ LoadSubCommand(
+ "symtab",
+ CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
+ LoadSubCommand("sections",
+ CommandObjectSP(new CommandObjectTargetModulesDumpSections(
+ interpreter)));
+ LoadSubCommand("symfile",
+ CommandObjectSP(
+ new CommandObjectTargetModulesDumpSymfile(interpreter)));
+ LoadSubCommand("line-table",
+ CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
+ interpreter)));
+ }
+
+ ~CommandObjectTargetModulesDump() override = default;
};
-class CommandObjectTargetModulesAdd : public CommandObjectParsed
-{
+class CommandObjectTargetModulesAdd : public CommandObjectParsed {
public:
- CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target modules add",
- "Add a new module to the current target's modules.",
- "target modules add [<module>]"),
- m_option_group (interpreter),
- m_symbol_file (LLDB_OPT_SET_1, false, "symfile", 's', 0, eArgTypeFilename, "Fullpath to a stand alone debug symbols file for when debug symbols are not in the executable.")
- {
- m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
-
- ~CommandObjectTargetModulesAdd() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
- }
+ CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target modules add",
+ "Add a new module to the current target's modules.",
+ "target modules add [<module>]"),
+ m_option_group(),
+ m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
+ eArgTypeFilename, "Fullpath to a stand alone debug "
+ "symbols file for when debug symbols "
+ "are not in the executable.") {
+ m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectTargetModulesAdd() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index));
+ completion_str.erase(cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
protected:
- OptionGroupOptions m_option_group;
- OptionGroupUUID m_uuid_option_group;
- OptionGroupFile m_symbol_file;
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- bool flush = false;
-
- const size_t argc = args.GetArgumentCount();
- if (argc == 0)
- {
- if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
- {
- // We are given a UUID only, go locate the file
- ModuleSpec module_spec;
- module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
- if (m_symbol_file.GetOptionValue().OptionWasSet())
- module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
- if (Symbols::DownloadObjectAndSymbolFile (module_spec))
- {
- ModuleSP module_sp (target->GetSharedModule (module_spec));
- if (module_sp)
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
- }
- else
- {
- StreamString strm;
- module_spec.GetUUID().Dump (&strm);
- if (module_spec.GetFileSpec())
- {
- if (module_spec.GetSymbolFileSpec())
- {
- result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s",
- strm.GetString().c_str(),
- module_spec.GetFileSpec().GetPath().c_str(),
- module_spec.GetSymbolFileSpec().GetPath().c_str());
- }
- else
- {
- result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s",
- strm.GetString().c_str(),
- module_spec.GetFileSpec().GetPath().c_str());
- }
- }
- else
- {
- result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s",
- strm.GetString().c_str());
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- StreamString strm;
- module_spec.GetUUID().Dump (&strm);
- result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- result.AppendError ("one or more executable image paths must be specified");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ OptionGroupOptions m_option_group;
+ OptionGroupUUID m_uuid_option_group;
+ OptionGroupFile m_symbol_file;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ bool flush = false;
+
+ const size_t argc = args.GetArgumentCount();
+ if (argc == 0) {
+ if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
+ // We are given a UUID only, go locate the file
+ ModuleSpec module_spec;
+ module_spec.GetUUID() =
+ m_uuid_option_group.GetOptionValue().GetCurrentValue();
+ if (m_symbol_file.GetOptionValue().OptionWasSet())
+ module_spec.GetSymbolFileSpec() =
+ m_symbol_file.GetOptionValue().GetCurrentValue();
+ if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
+ ModuleSP module_sp(target->GetSharedModule(module_spec));
+ if (module_sp) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ } else {
+ StreamString strm;
+ module_spec.GetUUID().Dump(&strm);
+ if (module_spec.GetFileSpec()) {
+ if (module_spec.GetSymbolFileSpec()) {
+ result.AppendErrorWithFormat(
+ "Unable to create the executable or symbol file with "
+ "UUID %s with path %s and symbol file %s",
+ strm.GetData(),
+ module_spec.GetFileSpec().GetPath().c_str(),
+ module_spec.GetSymbolFileSpec().GetPath().c_str());
+ } else {
+ result.AppendErrorWithFormat(
+ "Unable to create the executable or symbol file with "
+ "UUID %s with path %s",
+ strm.GetData(),
+ module_spec.GetFileSpec().GetPath().c_str());
}
+ } else {
+ result.AppendErrorWithFormat("Unable to create the executable "
+ "or symbol file with UUID %s",
+ strm.GetData());
+ }
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else
- {
- for (size_t i = 0; i < argc; ++i)
- {
- const char *path = args.GetArgumentAtIndex(i);
- if (path)
- {
- FileSpec file_spec(path, true);
- if (file_spec.Exists())
- {
- ModuleSpec module_spec (file_spec);
- if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
- module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
- if (m_symbol_file.GetOptionValue().OptionWasSet())
- module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
- if (!module_spec.GetArchitecture().IsValid())
- module_spec.GetArchitecture() = target->GetArchitecture();
- Error error;
- ModuleSP module_sp (target->GetSharedModule (module_spec, &error));
- if (!module_sp)
- {
- const char *error_cstr = error.AsCString();
- if (error_cstr)
- result.AppendError (error_cstr);
- else
- result.AppendErrorWithFormat ("unsupported module: %s", path);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- flush = true;
- }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- char resolved_path[PATH_MAX];
- result.SetStatus (eReturnStatusFailed);
- if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
- {
- if (strcmp (resolved_path, path) != 0)
- {
- result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
- break;
- }
- }
- result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
- break;
- }
- }
- }
+ } else {
+ StreamString strm;
+ module_spec.GetUUID().Dump(&strm);
+ result.AppendErrorWithFormat(
+ "Unable to locate the executable or symbol file with UUID %s",
+ strm.GetData());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ result.AppendError(
+ "one or more executable image paths must be specified");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ for (auto &entry : args.entries()) {
+ if (entry.ref.empty())
+ continue;
+
+ FileSpec file_spec(entry.ref, true);
+ if (file_spec.Exists()) {
+ ModuleSpec module_spec(file_spec);
+ if (m_uuid_option_group.GetOptionValue().OptionWasSet())
+ module_spec.GetUUID() =
+ m_uuid_option_group.GetOptionValue().GetCurrentValue();
+ if (m_symbol_file.GetOptionValue().OptionWasSet())
+ module_spec.GetSymbolFileSpec() =
+ m_symbol_file.GetOptionValue().GetCurrentValue();
+ if (!module_spec.GetArchitecture().IsValid())
+ module_spec.GetArchitecture() = target->GetArchitecture();
+ Error error;
+ ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
+ if (!module_sp) {
+ const char *error_cstr = error.AsCString();
+ if (error_cstr)
+ result.AppendError(error_cstr);
+ else
+ result.AppendErrorWithFormat("unsupported module: %s",
+ entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ flush = true;
}
-
- if (flush)
- {
- ProcessSP process = target->GetProcessSP();
- if (process)
- process->Flush();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ std::string resolved_path = file_spec.GetPath();
+ result.SetStatus(eReturnStatusFailed);
+ if (resolved_path != entry.ref) {
+ result.AppendErrorWithFormat(
+ "invalid module path '%s' with resolved path '%s'\n",
+ entry.ref.str().c_str(), resolved_path.c_str());
+ break;
}
+ result.AppendErrorWithFormat("invalid module path '%s'\n",
+ entry.c_str());
+ break;
+ }
}
+ }
- return result.Succeeded();
+ if (flush) {
+ ProcessSP process = target->GetProcessSP();
+ if (process)
+ process->Flush();
+ }
}
+
+ return result.Succeeded();
+ }
};
-class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
-{
+class CommandObjectTargetModulesLoad
+ : public CommandObjectTargetModulesModuleAutoComplete {
public:
- CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
- CommandObjectTargetModulesModuleAutoComplete (interpreter,
- "target modules load",
- "Set the load addresses for one or more sections in a target module.",
- "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
- m_option_group (interpreter),
- m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""),
- m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset, "Set the load address for all sections to be the virtual address in the file plus the offset.", 0)
- {
- m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
-
- ~CommandObjectTargetModulesLoad() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
+ CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
+ : CommandObjectTargetModulesModuleAutoComplete(
+ interpreter, "target modules load", "Set the load addresses for "
+ "one or more sections in a "
+ "target module.",
+ "target modules load [--file <module> --uuid <uuid>] <sect-name> "
+ "<address> [<sect-name> <address> ....]"),
+ m_option_group(),
+ m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
+ "Fullpath or basename for module to load.", ""),
+ m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
+ "Set the load address for all sections to be the "
+ "virtual address in the file plus the offset.",
+ 0) {
+ m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectTargetModulesLoad() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
protected:
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ const size_t argc = args.GetArgumentCount();
+ ModuleSpec module_spec;
+ bool search_using_module_spec = false;
+ if (m_file_option.GetOptionValue().OptionWasSet()) {
+ search_using_module_spec = true;
+ const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
+ const bool use_global_module_list = true;
+ ModuleList module_list;
+ const size_t num_matches = FindModulesByName(
+ target, arg_cstr, module_list, use_global_module_list);
+ if (num_matches == 1) {
+ module_spec.GetFileSpec() =
+ module_list.GetModuleAtIndex(0)->GetFileSpec();
+ } else if (num_matches > 1) {
+ search_using_module_spec = false;
+ result.AppendErrorWithFormat(
+ "more than 1 module matched by name '%s'\n", arg_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ search_using_module_spec = false;
+ result.AppendErrorWithFormat("no object file for module '%s'\n",
+ arg_cstr);
+ result.SetStatus(eReturnStatusFailed);
}
- else
- {
- const size_t argc = args.GetArgumentCount();
- ModuleSpec module_spec;
- bool search_using_module_spec = false;
- if (m_file_option.GetOptionValue().OptionWasSet())
- {
- search_using_module_spec = true;
- const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
- const bool use_global_module_list = true;
- ModuleList module_list;
- const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
- if (num_matches == 1)
- {
- module_spec.GetFileSpec() = module_list.GetModuleAtIndex(0)->GetFileSpec();
- }
- else if (num_matches > 1 )
- {
- search_using_module_spec = false;
- result.AppendErrorWithFormat ("more than 1 module matched by name '%s'\n", arg_cstr);
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- search_using_module_spec = false;
- result.AppendErrorWithFormat ("no object file for module '%s'\n", arg_cstr);
- result.SetStatus (eReturnStatusFailed);
- }
- }
-
- if (m_uuid_option_group.GetOptionValue().OptionWasSet())
- {
- search_using_module_spec = true;
- module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
- }
-
- if (search_using_module_spec)
- {
- ModuleList matching_modules;
- const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules);
-
- char path[PATH_MAX];
- if (num_matches == 1)
- {
- Module *module = matching_modules.GetModulePointerAtIndex(0);
- if (module)
- {
- ObjectFile *objfile = module->GetObjectFile();
- if (objfile)
- {
- SectionList *section_list = module->GetSectionList();
- if (section_list)
- {
- bool changed = false;
- if (argc == 0)
- {
- if (m_slide_option.GetOptionValue().OptionWasSet())
- {
- const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
- const bool slide_is_offset = true;
- module->SetLoadAddress (*target, slide, slide_is_offset, changed);
- }
- else
- {
- result.AppendError ("one or more section name + load address pair must be specified");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- if (m_slide_option.GetOptionValue().OptionWasSet())
- {
- result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- for (size_t i = 0; i < argc; i += 2)
- {
- const char *sect_name = args.GetArgumentAtIndex(i);
- const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
- if (sect_name && load_addr_cstr)
- {
- ConstString const_sect_name(sect_name);
- bool success = false;
- addr_t load_addr = StringConvert::ToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
- if (success)
- {
- SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
- if (section_sp)
- {
- if (section_sp->IsThreadSpecific())
- {
- result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name);
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- else
- {
- if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
- changed = true;
- result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- }
- else
- {
- if (sect_name)
- result.AppendError ("section names must be followed by a load address.\n");
- else
- result.AppendError ("one or more section name + load address pair must be specified.\n");
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- }
- }
-
- if (changed)
- {
- target->ModulesDidLoad (matching_modules);
- Process *process = m_exe_ctx.GetProcessPtr();
- if (process)
- process->Flush();
- }
- }
- else
- {
- module->GetFileSpec().GetPath (path, sizeof(path));
- result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- module->GetFileSpec().GetPath (path, sizeof(path));
- result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
- if (module_spec_file)
- {
- module_spec_file->GetPath (path, sizeof(path));
- result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
+ }
+
+ if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
+ search_using_module_spec = true;
+ module_spec.GetUUID() =
+ m_uuid_option_group.GetOptionValue().GetCurrentValue();
+ }
+
+ if (search_using_module_spec) {
+ ModuleList matching_modules;
+ const size_t num_matches =
+ target->GetImages().FindModules(module_spec, matching_modules);
+
+ char path[PATH_MAX];
+ if (num_matches == 1) {
+ Module *module = matching_modules.GetModulePointerAtIndex(0);
+ if (module) {
+ ObjectFile *objfile = module->GetObjectFile();
+ if (objfile) {
+ SectionList *section_list = module->GetSectionList();
+ if (section_list) {
+ bool changed = false;
+ if (argc == 0) {
+ if (m_slide_option.GetOptionValue().OptionWasSet()) {
+ const addr_t slide =
+ m_slide_option.GetOptionValue().GetCurrentValue();
+ const bool slide_is_offset = true;
+ module->SetLoadAddress(*target, slide, slide_is_offset,
+ changed);
+ } else {
+ result.AppendError("one or more section name + load "
+ "address pair must be specified");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ if (m_slide_option.GetOptionValue().OptionWasSet()) {
+ result.AppendError("The \"--slide <offset>\" option can't "
+ "be used in conjunction with setting "
+ "section load addresses.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ for (size_t i = 0; i < argc; i += 2) {
+ const char *sect_name = args.GetArgumentAtIndex(i);
+ const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
+ if (sect_name && load_addr_cstr) {
+ ConstString const_sect_name(sect_name);
+ bool success = false;
+ addr_t load_addr = StringConvert::ToUInt64(
+ load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
+ if (success) {
+ SectionSP section_sp(
+ section_list->FindSectionByName(const_sect_name));
+ if (section_sp) {
+ if (section_sp->IsThreadSpecific()) {
+ result.AppendErrorWithFormat(
+ "thread specific sections are not yet "
+ "supported (section '%s')\n",
+ sect_name);
+ result.SetStatus(eReturnStatusFailed);
+ break;
+ } else {
+ if (target->GetSectionLoadList()
+ .SetSectionLoadAddress(section_sp,
+ load_addr))
+ changed = true;
+ result.AppendMessageWithFormat(
+ "section '%s' loaded at 0x%" PRIx64 "\n",
+ sect_name, load_addr);
+ }
+ } else {
+ result.AppendErrorWithFormat("no section found that "
+ "matches the section "
+ "name '%s'\n",
+ sect_name);
+ result.SetStatus(eReturnStatusFailed);
+ break;
}
- else
- result.AppendError ("no module spec");
- result.SetStatus (eReturnStatusFailed);
+ } else {
+ result.AppendErrorWithFormat(
+ "invalid load address string '%s'\n",
+ load_addr_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ break;
+ }
+ } else {
+ if (sect_name)
+ result.AppendError("section names must be followed by "
+ "a load address.\n");
+ else
+ result.AppendError("one or more section name + load "
+ "address pair must be specified.\n");
+ result.SetStatus(eReturnStatusFailed);
+ break;
}
+ }
}
- else
- {
- std::string uuid_str;
-
- if (module_spec.GetFileSpec())
- module_spec.GetFileSpec().GetPath (path, sizeof(path));
- else
- path[0] = '\0';
-
- if (module_spec.GetUUIDPtr())
- uuid_str = module_spec.GetUUID().GetAsString();
- if (num_matches > 1)
- {
- result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
- path[0] ? " file=" : "",
- path,
- !uuid_str.empty() ? " uuid=" : "",
- uuid_str.c_str());
- for (size_t i = 0; i < num_matches; ++i)
- {
- if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
- result.AppendMessageWithFormat("%s\n", path);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n",
- path[0] ? " file=" : "",
- path,
- !uuid_str.empty() ? " uuid=" : "",
- uuid_str.c_str());
- }
- result.SetStatus (eReturnStatusFailed);
+
+ if (changed) {
+ target->ModulesDidLoad(matching_modules);
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process)
+ process->Flush();
}
+ } else {
+ module->GetFileSpec().GetPath(path, sizeof(path));
+ result.AppendErrorWithFormat(
+ "no sections in object file '%s'\n", path);
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ module->GetFileSpec().GetPath(path, sizeof(path));
+ result.AppendErrorWithFormat("no object file for module '%s'\n",
+ path);
+ result.SetStatus(eReturnStatusFailed);
}
- else
- {
- result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ } else {
+ FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
+ if (module_spec_file) {
+ module_spec_file->GetPath(path, sizeof(path));
+ result.AppendErrorWithFormat("invalid module '%s'.\n", path);
+ } else
+ result.AppendError("no module spec");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ std::string uuid_str;
+
+ if (module_spec.GetFileSpec())
+ module_spec.GetFileSpec().GetPath(path, sizeof(path));
+ else
+ path[0] = '\0';
+
+ if (module_spec.GetUUIDPtr())
+ uuid_str = module_spec.GetUUID().GetAsString();
+ if (num_matches > 1) {
+ result.AppendErrorWithFormat(
+ "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
+ path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
+ for (size_t i = 0; i < num_matches; ++i) {
+ if (matching_modules.GetModulePointerAtIndex(i)
+ ->GetFileSpec()
+ .GetPath(path, sizeof(path)))
+ result.AppendMessageWithFormat("%s\n", path);
}
+ } else {
+ result.AppendErrorWithFormat(
+ "no modules were found that match%s%s%s%s.\n",
+ path[0] ? " file=" : "", path,
+ !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
+ }
+ result.SetStatus(eReturnStatusFailed);
}
- return result.Succeeded();
+ } else {
+ result.AppendError("either the \"--file <module>\" or the \"--uuid "
+ "<uuid>\" option must be specified.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
+ return result.Succeeded();
+ }
- OptionGroupOptions m_option_group;
- OptionGroupUUID m_uuid_option_group;
- OptionGroupString m_file_option;
- OptionGroupUInt64 m_slide_option;
+ OptionGroupOptions m_option_group;
+ OptionGroupUUID m_uuid_option_group;
+ OptionGroupString m_file_option;
+ OptionGroupUInt64 m_slide_option;
};
//----------------------------------------------------------------------
// List images with associated information
//----------------------------------------------------------------------
-class CommandObjectTargetModulesList : public CommandObjectParsed
-{
-public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter),
- m_format_array(),
- m_use_global_module_list (false),
- m_module_addr (LLDB_INVALID_ADDRESS)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
-
- const int short_option = m_getopt_table[option_idx].val;
- if (short_option == 'g')
- {
- m_use_global_module_list = true;
- }
- else if (short_option == 'a')
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- m_module_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- }
- else
- {
- unsigned long width = 0;
- if (option_arg)
- width = strtoul(option_arg, nullptr, 0);
- m_format_array.push_back(std::make_pair(short_option, width));
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_format_array.clear();
- m_use_global_module_list = false;
- m_module_addr = LLDB_INVALID_ADDRESS;
- }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
- typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
- FormatWidthCollection m_format_array;
- bool m_use_global_module_list;
- lldb::addr_t m_module_addr;
- };
+static OptionDefinition g_target_modules_list_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
+ { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images." },
+ { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images." },
+ { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise." },
+ { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)." },
+ { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images." },
+ { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
+ { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
+ { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
+ { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
+ { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file." },
+ { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
+ { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache." },
+ { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer." },
+ { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target." }
+ // clang-format on
+};
- CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target modules list",
- "List current executable and dependent shared library images.",
- "target modules list [<cmd-options>]"),
- m_options (interpreter)
- {
+class CommandObjectTargetModulesList : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_format_array(), m_use_global_module_list(false),
+ m_module_addr(LLDB_INVALID_ADDRESS) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+
+ const int short_option = m_getopt_table[option_idx].val;
+ if (short_option == 'g') {
+ m_use_global_module_list = true;
+ } else if (short_option == 'a') {
+ m_module_addr = Args::StringToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
+ } else {
+ unsigned long width = 0;
+ option_arg.getAsInteger(0, width);
+ m_format_array.push_back(std::make_pair(short_option, width));
+ }
+ return error;
}
- ~CommandObjectTargetModulesList() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_format_array.clear();
+ m_use_global_module_list = false;
+ m_module_addr = LLDB_INVALID_ADDRESS;
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- const bool use_global_module_list = m_options.m_use_global_module_list;
- // Define a local module list here to ensure it lives longer than any "locker"
- // object which might lock its contents below (through the "module_list_ptr"
- // variable).
- ModuleList module_list;
- if (target == nullptr && !use_global_module_list)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- if (target)
- {
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
- }
- // Dump all sections for all modules images
- Stream &strm = result.GetOutputStream();
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_target_modules_list_options);
+ }
- if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
- {
- if (target)
- {
- Address module_address;
- if (module_address.SetLoadAddress(m_options.m_module_addr, target))
- {
- ModuleSP module_sp (module_address.GetModule());
- if (module_sp)
- {
- PrintModule (target, module_sp.get(), 0, strm);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr);
- result.SetStatus (eReturnStatusFailed);
- }
- }
- else
- {
- result.AppendError ("Can only look up modules by address with a valid target.");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
- }
+ // Instance variables to hold the values for command options.
+ typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
+ FormatWidthCollection m_format_array;
+ bool m_use_global_module_list;
+ lldb::addr_t m_module_addr;
+ };
- size_t num_modules = 0;
-
- // This locker will be locked on the mutex in module_list_ptr if it is non-nullptr.
- // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
- // the global module list directly.
- std::unique_lock<std::recursive_mutex> guard(Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
-
- const ModuleList *module_list_ptr = nullptr;
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- if (use_global_module_list)
- {
- guard.lock();
- num_modules = Module::GetNumberAllocatedModules();
- }
- else
- {
- module_list_ptr = &target->GetImages();
- }
- }
- else
- {
- for (size_t i = 0; i < argc; ++i)
- {
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr = command.GetArgumentAtIndex(i);
- const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
- if (num_matches == 0)
- {
- if (argc == 1)
- {
- result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
+ CommandObjectTargetModulesList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "target modules list",
+ "List current executable and dependent shared library images.",
+ "target modules list [<cmd-options>]"),
+ m_options() {}
- module_list_ptr = &module_list;
- }
+ ~CommandObjectTargetModulesList() override = default;
- std::unique_lock<std::recursive_mutex> lock;
- if (module_list_ptr != nullptr)
- {
- lock = std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
+ Options *GetOptions() override { return &m_options; }
- num_modules = module_list_ptr->GetSize();
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ const bool use_global_module_list = m_options.m_use_global_module_list;
+ // Define a local module list here to ensure it lives longer than any
+ // "locker"
+ // object which might lock its contents below (through the "module_list_ptr"
+ // variable).
+ ModuleList module_list;
+ if (target == nullptr && !use_global_module_list) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ if (target) {
+ uint32_t addr_byte_size =
+ target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+ }
+ // Dump all sections for all modules images
+ Stream &strm = result.GetOutputStream();
+
+ if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
+ if (target) {
+ Address module_address;
+ if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
+ ModuleSP module_sp(module_address.GetModule());
+ if (module_sp) {
+ PrintModule(target, module_sp.get(), 0, strm);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat(
+ "Couldn't find module matching address: 0x%" PRIx64 ".",
+ m_options.m_module_addr);
+ result.SetStatus(eReturnStatusFailed);
}
+ } else {
+ result.AppendErrorWithFormat(
+ "Couldn't find module containing address: 0x%" PRIx64 ".",
+ m_options.m_module_addr);
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendError(
+ "Can only look up modules by address with a valid target.");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+
+ size_t num_modules = 0;
+
+ // This locker will be locked on the mutex in module_list_ptr if it is
+ // non-nullptr.
+ // Otherwise it will lock the AllocationModuleCollectionMutex when
+ // accessing
+ // the global module list directly.
+ std::unique_lock<std::recursive_mutex> guard(
+ Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
+
+ const ModuleList *module_list_ptr = nullptr;
+ const size_t argc = command.GetArgumentCount();
+ if (argc == 0) {
+ if (use_global_module_list) {
+ guard.lock();
+ num_modules = Module::GetNumberAllocatedModules();
+ } else {
+ module_list_ptr = &target->GetImages();
+ }
+ } else {
+ // TODO: Convert to entry based iteration. Requires converting
+ // FindModulesByName.
+ for (size_t i = 0; i < argc; ++i) {
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr = command.GetArgumentAtIndex(i);
+ const size_t num_matches = FindModulesByName(
+ target, arg_cstr, module_list, use_global_module_list);
+ if (num_matches == 0) {
+ if (argc == 1) {
+ result.AppendErrorWithFormat("no modules found that match '%s'",
+ arg_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ }
- if (num_modules > 0)
- {
- for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
- {
- ModuleSP module_sp;
- Module *module;
- if (module_list_ptr)
- {
- module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
- module = module_sp.get();
- }
- else
- {
- module = Module::GetAllocatedModuleAtIndex(image_idx);
- module_sp = module->shared_from_this();
- }
+ module_list_ptr = &module_list;
+ }
+
+ std::unique_lock<std::recursive_mutex> lock;
+ if (module_list_ptr != nullptr) {
+ lock =
+ std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
+
+ num_modules = module_list_ptr->GetSize();
+ }
+
+ if (num_modules > 0) {
+ for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ ModuleSP module_sp;
+ Module *module;
+ if (module_list_ptr) {
+ module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
+ module = module_sp.get();
+ } else {
+ module = Module::GetAllocatedModuleAtIndex(image_idx);
+ module_sp = module->shared_from_this();
+ }
+
+ const size_t indent = strm.Printf("[%3u] ", image_idx);
+ PrintModule(target, module, indent, strm);
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ if (argc) {
+ if (use_global_module_list)
+ result.AppendError(
+ "the global module list has no matching modules");
+ else
+ result.AppendError("the target has no matching modules");
+ } else {
+ if (use_global_module_list)
+ result.AppendError("the global module list is empty");
+ else
+ result.AppendError(
+ "the target has no associated executable images");
+ }
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ return result.Succeeded();
+ }
- const size_t indent = strm.Printf("[%3u] ", image_idx);
- PrintModule (target, module, indent, strm);
+ void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
+ if (module == nullptr) {
+ strm.PutCString("Null module");
+ return;
+ }
+ bool dump_object_name = false;
+ if (m_options.m_format_array.empty()) {
+ m_options.m_format_array.push_back(std::make_pair('u', 0));
+ m_options.m_format_array.push_back(std::make_pair('h', 0));
+ m_options.m_format_array.push_back(std::make_pair('f', 0));
+ m_options.m_format_array.push_back(std::make_pair('S', 0));
+ }
+ const size_t num_entries = m_options.m_format_array.size();
+ bool print_space = false;
+ for (size_t i = 0; i < num_entries; ++i) {
+ if (print_space)
+ strm.PutChar(' ');
+ print_space = true;
+ const char format_char = m_options.m_format_array[i].first;
+ uint32_t width = m_options.m_format_array[i].second;
+ switch (format_char) {
+ case 'A':
+ DumpModuleArchitecture(strm, module, false, width);
+ break;
+
+ case 't':
+ DumpModuleArchitecture(strm, module, true, width);
+ break;
+
+ case 'f':
+ DumpFullpath(strm, &module->GetFileSpec(), width);
+ dump_object_name = true;
+ break;
+
+ case 'd':
+ DumpDirectory(strm, &module->GetFileSpec(), width);
+ break;
+
+ case 'b':
+ DumpBasename(strm, &module->GetFileSpec(), width);
+ dump_object_name = true;
+ break;
+
+ case 'h':
+ case 'o':
+ // Image header address
+ {
+ uint32_t addr_nibble_width =
+ target ? (target->GetArchitecture().GetAddressByteSize() * 2)
+ : 16;
+
+ ObjectFile *objfile = module->GetObjectFile();
+ if (objfile) {
+ Address header_addr(objfile->GetHeaderAddress());
+ if (header_addr.IsValid()) {
+ if (target && !target->GetSectionLoadList().IsEmpty()) {
+ lldb::addr_t header_load_addr =
+ header_addr.GetLoadAddress(target);
+ if (header_load_addr == LLDB_INVALID_ADDRESS) {
+ header_addr.Dump(&strm, target,
+ Address::DumpStyleModuleWithFileAddress,
+ Address::DumpStyleFileAddress);
+ } else {
+ if (format_char == 'o') {
+ // Show the offset of slide for the image
+ strm.Printf(
+ "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
+ header_load_addr - header_addr.GetFileAddress());
+ } else {
+ // Show the load address of the image
+ strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
+ addr_nibble_width, header_load_addr);
+ }
}
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- if (argc)
- {
- if (use_global_module_list)
- result.AppendError ("the global module list has no matching modules");
- else
- result.AppendError ("the target has no matching modules");
- }
- else
- {
- if (use_global_module_list)
- result.AppendError ("the global module list is empty");
- else
- result.AppendError ("the target has no associated executable images");
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
+ break;
+ }
+ // The address was valid, but the image isn't loaded, output the
+ // address in an appropriate format
+ header_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
+ break;
}
+ }
+ strm.Printf("%*s", addr_nibble_width + 2, "");
}
- return result.Succeeded();
- }
-
- void
- PrintModule (Target *target, Module *module, int indent, Stream &strm)
- {
- if (module == nullptr)
- {
- strm.PutCString("Null module");
- return;
+ break;
+
+ case 'r': {
+ size_t ref_count = 0;
+ ModuleSP module_sp(module->shared_from_this());
+ if (module_sp) {
+ // Take one away to make sure we don't count our local "module_sp"
+ ref_count = module_sp.use_count() - 1;
}
-
- bool dump_object_name = false;
- if (m_options.m_format_array.empty())
- {
- m_options.m_format_array.push_back(std::make_pair('u', 0));
- m_options.m_format_array.push_back(std::make_pair('h', 0));
- m_options.m_format_array.push_back(std::make_pair('f', 0));
- m_options.m_format_array.push_back(std::make_pair('S', 0));
+ if (width)
+ strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
+ else
+ strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
+ } break;
+
+ case 's':
+ case 'S': {
+ const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
+ if (symbol_vendor) {
+ const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
+ if (format_char == 'S') {
+ // Dump symbol file only if different from module file
+ if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
+ print_space = false;
+ break;
+ }
+ // Add a newline and indent past the index
+ strm.Printf("\n%*s", indent, "");
+ }
+ DumpFullpath(strm, &symfile_spec, width);
+ dump_object_name = true;
+ break;
}
- const size_t num_entries = m_options.m_format_array.size();
- bool print_space = false;
- for (size_t i = 0; i < num_entries; ++i)
- {
- if (print_space)
- strm.PutChar(' ');
- print_space = true;
- const char format_char = m_options.m_format_array[i].first;
- uint32_t width = m_options.m_format_array[i].second;
- switch (format_char)
- {
- case 'A':
- DumpModuleArchitecture (strm, module, false, width);
- break;
-
- case 't':
- DumpModuleArchitecture (strm, module, true, width);
- break;
-
- case 'f':
- DumpFullpath (strm, &module->GetFileSpec(), width);
- dump_object_name = true;
- break;
-
- case 'd':
- DumpDirectory (strm, &module->GetFileSpec(), width);
- break;
-
- case 'b':
- DumpBasename (strm, &module->GetFileSpec(), width);
- dump_object_name = true;
- break;
-
- case 'h':
- case 'o':
- // Image header address
- {
- uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
-
- ObjectFile *objfile = module->GetObjectFile ();
- if (objfile)
- {
- Address header_addr(objfile->GetHeaderAddress());
- if (header_addr.IsValid())
- {
- if (target && !target->GetSectionLoadList().IsEmpty())
- {
- lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
- if (header_load_addr == LLDB_INVALID_ADDRESS)
- {
- header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
- }
- else
- {
- if (format_char == 'o')
- {
- // Show the offset of slide for the image
- strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
- }
- else
- {
- // Show the load address of the image
- strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr);
- }
- }
- break;
- }
- // The address was valid, but the image isn't loaded, output the address in an appropriate format
- header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
- break;
- }
- }
- strm.Printf ("%*s", addr_nibble_width + 2, "");
- }
- break;
-
- case 'r':
- {
- size_t ref_count = 0;
- ModuleSP module_sp (module->shared_from_this());
- if (module_sp)
- {
- // Take one away to make sure we don't count our local "module_sp"
- ref_count = module_sp.use_count() - 1;
- }
- if (width)
- strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
- else
- strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
- }
- break;
-
- case 's':
- case 'S':
- {
- const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
- if (symbol_vendor)
- {
- const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
- if (format_char == 'S')
- {
- // Dump symbol file only if different from module file
- if (!symfile_spec || symfile_spec == module->GetFileSpec())
- {
- print_space = false;
- break;
- }
- // Add a newline and indent past the index
- strm.Printf ("\n%*s", indent, "");
- }
- DumpFullpath (strm, &symfile_spec, width);
- dump_object_name = true;
- break;
- }
- strm.Printf("%.*s", width, "<NONE>");
- }
- break;
+ strm.Printf("%.*s", width, "<NONE>");
+ } break;
- case 'm':
- module->GetModificationTime().Dump(&strm, width);
- break;
+ case 'm':
+ DumpTimePoint(module->GetModificationTime(), strm, width);
+ break;
- case 'p':
- strm.Printf("%p", static_cast<void*>(module));
- break;
+ case 'p':
+ strm.Printf("%p", static_cast<void *>(module));
+ break;
- case 'u':
- DumpModuleUUID(strm, module);
- break;
+ case 'u':
+ DumpModuleUUID(strm, module);
+ break;
- default:
- break;
- }
- }
- if (dump_object_name)
- {
- const char *object_name = module->GetObjectName().GetCString();
- if (object_name)
- strm.Printf ("(%s)", object_name);
- }
- strm.EOL();
+ default:
+ break;
+ }
}
+ if (dump_object_name) {
+ const char *object_name = module->GetObjectName().GetCString();
+ if (object_name)
+ strm.Printf("(%s)", object_name);
+ }
+ strm.EOL();
+ }
- CommandOptions m_options;
-};
-
-OptionDefinition
-CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
- { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images."},
- { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images."},
- { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."},
- { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."},
- { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images."},
- { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
- { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
- { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
- { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
- { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."},
- { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module."},
- { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."},
- { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer."},
- { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
#pragma mark CommandObjectTargetModulesShowUnwind
@@ -3578,750 +3157,674 @@ CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
// Lookup unwind information in images
//----------------------------------------------------------------------
-class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
-{
-public:
- enum
- {
- eLookupTypeInvalid = -1,
- eLookupTypeAddress = 0,
- eLookupTypeSymbol,
- eLookupTypeFunction,
- eLookupTypeFunctionOrSymbol,
- kNumLookupTypes
- };
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter),
- m_type(eLookupTypeInvalid),
- m_str(),
- m_addr(LLDB_INVALID_ADDRESS)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
-
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'a':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- m_str = option_arg;
- m_type = eLookupTypeAddress;
- m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- if (m_addr == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
- break;
- }
-
- case 'n':
- m_str = option_arg;
- m_type = eLookupTypeFunctionOrSymbol;
- break;
+static OptionDefinition g_target_modules_show_unwind_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
+ { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
+ // clang-format on
+};
- default:
- error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
- break;
- }
+class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
+public:
+ enum {
+ eLookupTypeInvalid = -1,
+ eLookupTypeAddress = 0,
+ eLookupTypeSymbol,
+ eLookupTypeFunction,
+ eLookupTypeFunctionOrSymbol,
+ kNumLookupTypes
+ };
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_type(eLookupTypeInvalid), m_str(),
+ m_addr(LLDB_INVALID_ADDRESS) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'a': {
+ m_str = option_arg;
+ m_type = eLookupTypeAddress;
+ m_addr = Args::StringToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
+ if (m_addr == LLDB_INVALID_ADDRESS)
+ error.SetErrorStringWithFormat("invalid address string '%s'",
+ option_arg.str().c_str());
+ break;
+ }
+
+ case 'n':
+ m_str = option_arg;
+ m_type = eLookupTypeFunctionOrSymbol;
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
+ break;
+ }
+
+ return error;
+ }
- return error;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_type = eLookupTypeInvalid;
+ m_str.clear();
+ m_addr = LLDB_INVALID_ADDRESS;
+ }
- void
- OptionParsingStarting () override
- {
- m_type = eLookupTypeInvalid;
- m_str.clear();
- m_addr = LLDB_INVALID_ADDRESS;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_target_modules_show_unwind_options);
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ // Instance variables to hold the values for command options.
- // Options table: Required for subclasses of Options.
+ int m_type; // Should be a eLookupTypeXXX enum after parsing options
+ std::string m_str; // Holds name lookup
+ lldb::addr_t m_addr; // Holds the address to lookup
+ };
- static OptionDefinition g_option_table[];
+ CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "target modules show-unwind",
+ "Show synthesized unwind instructions for a function.", nullptr,
+ eCommandRequiresTarget | eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options() {}
- // Instance variables to hold the values for command options.
+ ~CommandObjectTargetModulesShowUnwind() override = default;
- int m_type; // Should be a eLookupTypeXXX enum after parsing options
- std::string m_str; // Holds name lookup
- lldb::addr_t m_addr; // Holds the address to lookup
- };
+ Options *GetOptions() override { return &m_options; }
- CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "target modules show-unwind",
- "Show synthesized unwind instructions for a function.",
- nullptr,
- eCommandRequiresTarget |
- eCommandRequiresProcess |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_options (interpreter)
- {
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_exe_ctx.GetTargetPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
+ ABI *abi = nullptr;
+ if (process)
+ abi = process->GetABI().get();
+
+ if (process == nullptr) {
+ result.AppendError(
+ "You must have a process running to use this command.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- ~CommandObjectTargetModulesShowUnwind() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ ThreadList threads(process->GetThreadList());
+ if (threads.GetSize() == 0) {
+ result.AppendError("The process must be paused to use this command.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_exe_ctx.GetTargetPtr();
- Process *process = m_exe_ctx.GetProcessPtr();
- ABI *abi = nullptr;
- if (process)
- abi = process->GetABI().get();
-
- if (process == nullptr)
- {
- result.AppendError ("You must have a process running to use this command.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ ThreadSP thread(threads.GetThreadAtIndex(0));
+ if (!thread) {
+ result.AppendError("The process must be paused to use this command.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- ThreadList threads(process->GetThreadList());
- if (threads.GetSize() == 0)
- {
- result.AppendError ("The process must be paused to use this command.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ SymbolContextList sc_list;
- ThreadSP thread(threads.GetThreadAtIndex(0));
- if (!thread)
- {
- result.AppendError ("The process must be paused to use this command.");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
+ ConstString function_name(m_options.m_str.c_str());
+ target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
+ true, false, true, sc_list);
+ } else if (m_options.m_type == eLookupTypeAddress && target) {
+ Address addr;
+ if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
+ addr)) {
+ SymbolContext sc;
+ ModuleSP module_sp(addr.GetModule());
+ module_sp->ResolveSymbolContextForAddress(addr,
+ eSymbolContextEverything, sc);
+ if (sc.function || sc.symbol) {
+ sc_list.Append(sc);
}
+ }
+ } else {
+ result.AppendError(
+ "address-expression or function name option must be specified.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- SymbolContextList sc_list;
+ size_t num_matches = sc_list.GetSize();
+ if (num_matches == 0) {
+ result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
+ m_options.m_str.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (m_options.m_type == eLookupTypeFunctionOrSymbol)
- {
- ConstString function_name (m_options.m_str.c_str());
- target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
- }
- else if (m_options.m_type == eLookupTypeAddress && target)
- {
- Address addr;
- if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr))
- {
- SymbolContext sc;
- ModuleSP module_sp (addr.GetModule());
- module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc);
- if (sc.function || sc.symbol)
- {
- sc_list.Append(sc);
- }
- }
- }
- else
- {
- result.AppendError ("address-expression or function name option must be specified.");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ for (uint32_t idx = 0; idx < num_matches; idx++) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(idx, sc);
+ if (sc.symbol == nullptr && sc.function == nullptr)
+ continue;
+ if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
+ continue;
+ AddressRange range;
+ if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
+ false, range))
+ continue;
+ if (!range.GetBaseAddress().IsValid())
+ continue;
+ ConstString funcname(sc.GetFunctionName());
+ if (funcname.IsEmpty())
+ continue;
+ addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
+ if (abi)
+ start_addr = abi->FixCodeAddress(start_addr);
+
+ FuncUnwindersSP func_unwinders_sp(
+ sc.module_sp->GetObjectFile()
+ ->GetUnwindTable()
+ .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
+ if (!func_unwinders_sp)
+ continue;
+
+ result.GetOutputStream().Printf(
+ "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
+ sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
+ funcname.AsCString(), start_addr);
+
+ UnwindPlanSP non_callsite_unwind_plan =
+ func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
+ if (non_callsite_unwind_plan) {
+ result.GetOutputStream().Printf(
+ "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
+ non_callsite_unwind_plan->GetSourceName().AsCString());
+ }
+ UnwindPlanSP callsite_unwind_plan =
+ func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
+ if (callsite_unwind_plan) {
+ result.GetOutputStream().Printf(
+ "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
+ callsite_unwind_plan->GetSourceName().AsCString());
+ }
+ UnwindPlanSP fast_unwind_plan =
+ func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
+ if (fast_unwind_plan) {
+ result.GetOutputStream().Printf(
+ "Fast UnwindPlan is '%s'\n",
+ fast_unwind_plan->GetSourceName().AsCString());
+ }
+
+ result.GetOutputStream().Printf("\n");
+
+ UnwindPlanSP assembly_sp =
+ func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
+ if (assembly_sp) {
+ result.GetOutputStream().Printf(
+ "Assembly language inspection UnwindPlan:\n");
+ assembly_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ UnwindPlanSP ehframe_sp =
+ func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
+ if (ehframe_sp) {
+ result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
+ ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ UnwindPlanSP ehframe_augmented_sp =
+ func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
+ if (ehframe_augmented_sp) {
+ result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
+ ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ UnwindPlanSP arm_unwind_sp =
+ func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
+ if (arm_unwind_sp) {
+ result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
+ arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ UnwindPlanSP compact_unwind_sp =
+ func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
+ if (compact_unwind_sp) {
+ result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
+ compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ if (fast_unwind_plan) {
+ result.GetOutputStream().Printf("Fast UnwindPlan:\n");
+ fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
+ }
+
+ ABISP abi_sp = process->GetABI();
+ if (abi_sp) {
+ UnwindPlan arch_default(lldb::eRegisterKindGeneric);
+ if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
+ result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
+ arch_default.Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
}
- size_t num_matches = sc_list.GetSize();
- if (num_matches == 0)
- {
- result.AppendErrorWithFormat ("no unwind data found that matches '%s'.", m_options.m_str.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
+ UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
+ if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
+ result.GetOutputStream().Printf(
+ "Arch default at entry point UnwindPlan:\n");
+ arch_entry.Dump(result.GetOutputStream(), thread.get(),
+ LLDB_INVALID_ADDRESS);
+ result.GetOutputStream().Printf("\n");
}
+ }
- for (uint32_t idx = 0; idx < num_matches; idx++)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(idx, sc);
- if (sc.symbol == nullptr && sc.function == nullptr)
- continue;
- if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
- continue;
- AddressRange range;
- if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
- continue;
- if (!range.GetBaseAddress().IsValid())
- continue;
- ConstString funcname(sc.GetFunctionName());
- if (funcname.IsEmpty())
- continue;
- addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
- if (abi)
- start_addr = abi->FixCodeAddress(start_addr);
-
- FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
- if (!func_unwinders_sp)
- continue;
-
- result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
-
- UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
- if (non_callsite_unwind_plan)
- {
- result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString());
- }
- UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
- if (callsite_unwind_plan)
- {
- result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString());
- }
- UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
- if (fast_unwind_plan)
- {
- result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString());
- }
-
- result.GetOutputStream().Printf("\n");
-
- UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
- if (assembly_sp)
- {
- result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n");
- assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf("\n");
- }
-
- UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
- if (ehframe_sp)
- {
- result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
- ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf("\n");
- }
-
- UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
- if (ehframe_augmented_sp)
- {
- result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
- ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf("\n");
- }
-
- UnwindPlanSP arm_unwind_sp = func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
- if (arm_unwind_sp)
- {
- result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
- arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf("\n");
- }
-
- UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
- if (compact_unwind_sp)
- {
- result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
- compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf("\n");
- }
-
- if (fast_unwind_plan)
- {
- result.GetOutputStream().Printf("Fast UnwindPlan:\n");
- fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf("\n");
- }
-
- ABISP abi_sp = process->GetABI();
- if (abi_sp)
- {
- UnwindPlan arch_default(lldb::eRegisterKindGeneric);
- if (abi_sp->CreateDefaultUnwindPlan (arch_default))
- {
- result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
- arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf("\n");
- }
-
- UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
- if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry))
- {
- result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n");
- arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
- result.GetOutputStream().Printf("\n");
- }
- }
-
- result.GetOutputStream().Printf ("\n");
- }
- return result.Succeeded();
+ result.GetOutputStream().Printf("\n");
}
+ return result.Succeeded();
+ }
- CommandOptions m_options;
-};
-
-OptionDefinition
-CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
- { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//----------------------------------------------------------------------
// Lookup information in images
//----------------------------------------------------------------------
-class CommandObjectTargetModulesLookup : public CommandObjectParsed
-{
-public:
- enum
- {
- eLookupTypeInvalid = -1,
- eLookupTypeAddress = 0,
- eLookupTypeSymbol,
- eLookupTypeFileLine, // Line is optional
- eLookupTypeFunction,
- eLookupTypeFunctionOrSymbol,
- eLookupTypeType,
- kNumLookupTypes
- };
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- OptionParsingStarting();
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
-
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'a':
- {
- m_type = eLookupTypeAddress;
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- }
- break;
-
- case 'o':
- m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS);
- if (m_offset == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
- break;
-
- case 's':
- m_str = option_arg;
- m_type = eLookupTypeSymbol;
- break;
-
- case 'f':
- m_file.SetFile (option_arg, false);
- m_type = eLookupTypeFileLine;
- break;
-
- case 'i':
- m_include_inlines = false;
- break;
-
- case 'l':
- m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX);
- if (m_line_number == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
- else if (m_line_number == 0)
- error.SetErrorString ("zero is an invalid line number");
- m_type = eLookupTypeFileLine;
- break;
-
- case 'F':
- m_str = option_arg;
- m_type = eLookupTypeFunction;
- break;
-
- case 'n':
- m_str = option_arg;
- m_type = eLookupTypeFunctionOrSymbol;
- break;
-
- case 't':
- m_str = option_arg;
- m_type = eLookupTypeType;
- break;
-
- case 'v':
- m_verbose = 1;
- break;
-
- case 'A':
- m_print_all = true;
- break;
-
- case 'r':
- m_use_regex = true;
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_type = eLookupTypeInvalid;
- m_str.clear();
- m_file.Clear();
- m_addr = LLDB_INVALID_ADDRESS;
- m_offset = 0;
- m_line_number = 0;
- m_use_regex = false;
- m_include_inlines = true;
- m_verbose = false;
- m_print_all = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+static OptionDefinition g_target_modules_lookup_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
+ { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup." },
+ /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
+ { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions." },
+ { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules." },
+ { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules." },
+ { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)." },
+ { LLDB_OPT_SET_FROM_TO(3,5), false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)." },
+ { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules." },
+ { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules." },
+ { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules." },
+ { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information." },
+ { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available." },
+ // clang-format on
+};
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
- int m_type; // Should be a eLookupTypeXXX enum after parsing options
- std::string m_str; // Holds name lookup
- FileSpec m_file; // Files for file lookups
- lldb::addr_t m_addr; // Holds the address to lookup
- lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
- uint32_t m_line_number; // Line number for file+line lookups
- bool m_use_regex; // Name lookups in m_str are regular expressions.
- bool m_include_inlines;// Check for inline entries when looking up by file/line.
- bool m_verbose; // Enable verbose lookup info
- bool m_print_all; // Print all matches, even in cases where there's a best match.
- };
-
- CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "target modules lookup",
- "Look up information within executable and dependent shared library images.",
- nullptr,
- eCommandRequiresTarget),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData file_arg;
-
- // Define the first (and only) variant of this arg.
- file_arg.arg_type = eArgTypeFilename;
- file_arg.arg_repetition = eArgRepeatStar;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (file_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+class CommandObjectTargetModulesLookup : public CommandObjectParsed {
+public:
+ enum {
+ eLookupTypeInvalid = -1,
+ eLookupTypeAddress = 0,
+ eLookupTypeSymbol,
+ eLookupTypeFileLine, // Line is optional
+ eLookupTypeFunction,
+ eLookupTypeFunctionOrSymbol,
+ eLookupTypeType,
+ kNumLookupTypes
+ };
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'a': {
+ m_type = eLookupTypeAddress;
+ m_addr = Args::StringToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
+ } break;
+
+ case 'o':
+ if (option_arg.getAsInteger(0, m_offset))
+ error.SetErrorStringWithFormat("invalid offset string '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 's':
+ m_str = option_arg;
+ m_type = eLookupTypeSymbol;
+ break;
+
+ case 'f':
+ m_file.SetFile(option_arg, false);
+ m_type = eLookupTypeFileLine;
+ break;
+
+ case 'i':
+ m_include_inlines = false;
+ break;
+
+ case 'l':
+ if (option_arg.getAsInteger(0, m_line_number))
+ error.SetErrorStringWithFormat("invalid line number string '%s'",
+ option_arg.str().c_str());
+ else if (m_line_number == 0)
+ error.SetErrorString("zero is an invalid line number");
+ m_type = eLookupTypeFileLine;
+ break;
+
+ case 'F':
+ m_str = option_arg;
+ m_type = eLookupTypeFunction;
+ break;
+
+ case 'n':
+ m_str = option_arg;
+ m_type = eLookupTypeFunctionOrSymbol;
+ break;
+
+ case 't':
+ m_str = option_arg;
+ m_type = eLookupTypeType;
+ break;
+
+ case 'v':
+ m_verbose = 1;
+ break;
+
+ case 'A':
+ m_print_all = true;
+ break;
+
+ case 'r':
+ m_use_regex = true;
+ break;
+ }
+
+ return error;
}
- ~CommandObjectTargetModulesLookup() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_type = eLookupTypeInvalid;
+ m_str.clear();
+ m_file.Clear();
+ m_addr = LLDB_INVALID_ADDRESS;
+ m_offset = 0;
+ m_line_number = 0;
+ m_use_regex = false;
+ m_include_inlines = true;
+ m_verbose = false;
+ m_print_all = false;
}
- bool
- LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
- {
- switch (m_options.m_type)
- {
- case eLookupTypeAddress:
- case eLookupTypeFileLine:
- case eLookupTypeFunction:
- case eLookupTypeFunctionOrSymbol:
- case eLookupTypeSymbol:
- default:
- return false;
- case eLookupTypeType:
- break;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_target_modules_lookup_options);
+ }
- StackFrameSP frame = m_exe_ctx.GetFrameSP();
+ int m_type; // Should be a eLookupTypeXXX enum after parsing options
+ std::string m_str; // Holds name lookup
+ FileSpec m_file; // Files for file lookups
+ lldb::addr_t m_addr; // Holds the address to lookup
+ lldb::addr_t
+ m_offset; // Subtract this offset from m_addr before doing lookups.
+ uint32_t m_line_number; // Line number for file+line lookups
+ bool m_use_regex; // Name lookups in m_str are regular expressions.
+ bool m_include_inlines; // Check for inline entries when looking up by
+ // file/line.
+ bool m_verbose; // Enable verbose lookup info
+ bool m_print_all; // Print all matches, even in cases where there's a best
+ // match.
+ };
+
+ CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target modules lookup",
+ "Look up information within executable and "
+ "dependent shared library images.",
+ nullptr, eCommandRequiresTarget),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData file_arg;
+
+ // Define the first (and only) variant of this arg.
+ file_arg.arg_type = eArgTypeFilename;
+ file_arg.arg_repetition = eArgRepeatStar;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(file_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectTargetModulesLookup() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
+ bool &syntax_error) {
+ switch (m_options.m_type) {
+ case eLookupTypeAddress:
+ case eLookupTypeFileLine:
+ case eLookupTypeFunction:
+ case eLookupTypeFunctionOrSymbol:
+ case eLookupTypeSymbol:
+ default:
+ return false;
+ case eLookupTypeType:
+ break;
+ }
- if (!frame)
- return false;
+ StackFrameSP frame = m_exe_ctx.GetFrameSP();
- const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
+ if (!frame)
+ return false;
- if (!sym_ctx.module_sp)
- return false;
+ const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
- switch (m_options.m_type)
- {
- default:
- return false;
- case eLookupTypeType:
- if (!m_options.m_str.empty())
- {
- if (LookupTypeHere (m_interpreter,
- result.GetOutputStream(),
- sym_ctx,
- m_options.m_str.c_str(),
- m_options.m_use_regex))
- {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- break;
+ if (!sym_ctx.module_sp)
+ return false;
+
+ switch (m_options.m_type) {
+ default:
+ return false;
+ case eLookupTypeType:
+ if (!m_options.m_str.empty()) {
+ if (LookupTypeHere(m_interpreter, result.GetOutputStream(), sym_ctx,
+ m_options.m_str.c_str(), m_options.m_use_regex)) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
}
-
- return true;
+ }
+ break;
}
- bool
- LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
- {
- switch (m_options.m_type)
- {
- case eLookupTypeAddress:
- if (m_options.m_addr != LLDB_INVALID_ADDRESS)
- {
- if (LookupAddressInModule (m_interpreter,
- result.GetOutputStream(),
- module,
- eSymbolContextEverything | (m_options.m_verbose ? static_cast<int>(eSymbolContextVariable) : 0),
- m_options.m_addr,
- m_options.m_offset,
- m_options.m_verbose))
- {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- break;
-
- case eLookupTypeSymbol:
- if (!m_options.m_str.empty())
- {
- if (LookupSymbolInModule (m_interpreter,
- result.GetOutputStream(),
- module,
- m_options.m_str.c_str(),
- m_options.m_use_regex,
- m_options.m_verbose))
- {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- break;
-
- case eLookupTypeFileLine:
- if (m_options.m_file)
- {
- if (LookupFileAndLineInModule (m_interpreter,
- result.GetOutputStream(),
- module,
- m_options.m_file,
- m_options.m_line_number,
- m_options.m_include_inlines,
- m_options.m_verbose))
- {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- break;
-
- case eLookupTypeFunctionOrSymbol:
- case eLookupTypeFunction:
- if (!m_options.m_str.empty())
- {
- if (LookupFunctionInModule (m_interpreter,
- result.GetOutputStream(),
- module,
- m_options.m_str.c_str(),
- m_options.m_use_regex,
- m_options.m_include_inlines,
- m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
- m_options.m_verbose))
- {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- break;
-
- case eLookupTypeType:
- if (!m_options.m_str.empty())
- {
- if (LookupTypeInModule (m_interpreter,
- result.GetOutputStream(),
- module,
- m_options.m_str.c_str(),
- m_options.m_use_regex))
- {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
- }
- break;
-
- default:
- m_options.GenerateOptionUsage (result.GetErrorStream(), this);
- syntax_error = true;
- break;
+ return true;
+ }
+
+ bool LookupInModule(CommandInterpreter &interpreter, Module *module,
+ CommandReturnObject &result, bool &syntax_error) {
+ switch (m_options.m_type) {
+ case eLookupTypeAddress:
+ if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
+ if (LookupAddressInModule(
+ m_interpreter, result.GetOutputStream(), module,
+ eSymbolContextEverything |
+ (m_options.m_verbose
+ ? static_cast<int>(eSymbolContextVariable)
+ : 0),
+ m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
}
-
- result.SetStatus (eReturnStatusFailed);
- return false;
+ }
+ break;
+
+ case eLookupTypeSymbol:
+ if (!m_options.m_str.empty()) {
+ if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
+ module, m_options.m_str.c_str(),
+ m_options.m_use_regex, m_options.m_verbose)) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ }
+ break;
+
+ case eLookupTypeFileLine:
+ if (m_options.m_file) {
+ if (LookupFileAndLineInModule(
+ m_interpreter, result.GetOutputStream(), module,
+ m_options.m_file, m_options.m_line_number,
+ m_options.m_include_inlines, m_options.m_verbose)) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ }
+ break;
+
+ case eLookupTypeFunctionOrSymbol:
+ case eLookupTypeFunction:
+ if (!m_options.m_str.empty()) {
+ if (LookupFunctionInModule(
+ m_interpreter, result.GetOutputStream(), module,
+ m_options.m_str.c_str(), m_options.m_use_regex,
+ m_options.m_include_inlines,
+ m_options.m_type ==
+ eLookupTypeFunctionOrSymbol, // include symbols
+ m_options.m_verbose)) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ }
+ break;
+
+ case eLookupTypeType:
+ if (!m_options.m_str.empty()) {
+ if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
+ m_options.m_str.c_str(),
+ m_options.m_use_regex)) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ }
+ break;
+
+ default:
+ m_options.GenerateOptionUsage(
+ result.GetErrorStream(), this,
+ GetCommandInterpreter().GetDebugger().GetTerminalWidth());
+ syntax_error = true;
+ break;
}
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ bool syntax_error = false;
+ uint32_t i;
+ uint32_t num_successful_lookups = 0;
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+ // Dump all sections for all modules images
+
+ if (command.GetArgumentCount() == 0) {
+ ModuleSP current_module;
+
+ // Where it is possible to look in the current symbol context
+ // first, try that. If this search was successful and --all
+ // was not passed, don't print anything else.
+ if (LookupHere(m_interpreter, result, syntax_error)) {
+ result.GetOutputStream().EOL();
+ num_successful_lookups++;
+ if (!m_options.m_print_all) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
}
- else
- {
- bool syntax_error = false;
- uint32_t i;
- uint32_t num_successful_lookups = 0;
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
- // Dump all sections for all modules images
-
- if (command.GetArgumentCount() == 0)
- {
- ModuleSP current_module;
-
- // Where it is possible to look in the current symbol context
- // first, try that. If this search was successful and --all
- // was not passed, don't print anything else.
- if (LookupHere (m_interpreter, result, syntax_error))
- {
- result.GetOutputStream().EOL();
- num_successful_lookups++;
- if (!m_options.m_print_all)
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return result.Succeeded();
- }
- }
- // Dump all sections for all other modules
-
- const ModuleList &target_modules = target->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
- const size_t num_modules = target_modules.GetSize();
- if (num_modules > 0)
- {
- for (i = 0; i < num_modules && !syntax_error; ++i)
- {
- Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
-
- if (module_pointer != current_module.get() &&
- LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
- {
- result.GetOutputStream().EOL();
- num_successful_lookups++;
- }
- }
- }
- else
- {
- result.AppendError ("the target has no associated executable images");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Dump all sections for all other modules
+
+ const ModuleList &target_modules = target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+ const size_t num_modules = target_modules.GetSize();
+ if (num_modules > 0) {
+ for (i = 0; i < num_modules && !syntax_error; ++i) {
+ Module *module_pointer =
+ target_modules.GetModulePointerAtIndexUnlocked(i);
+
+ if (module_pointer != current_module.get() &&
+ LookupInModule(
+ m_interpreter,
+ target_modules.GetModulePointerAtIndexUnlocked(i), result,
+ syntax_error)) {
+ result.GetOutputStream().EOL();
+ num_successful_lookups++;
}
- else
- {
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr;
- for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr && !syntax_error; ++i)
- {
- ModuleList module_list;
- const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
- if (num_matches > 0)
- {
- for (size_t j=0; j<num_matches; ++j)
- {
- Module *module = module_list.GetModulePointerAtIndex(j);
- if (module)
- {
- if (LookupInModule (m_interpreter, module, result, syntax_error))
- {
- result.GetOutputStream().EOL();
- num_successful_lookups++;
- }
- }
- }
- }
- else
- result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
+ }
+ } else {
+ result.AppendError("the target has no associated executable images");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr;
+ for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
+ !syntax_error;
+ ++i) {
+ ModuleList module_list;
+ const size_t num_matches =
+ FindModulesByName(target, arg_cstr, module_list, false);
+ if (num_matches > 0) {
+ for (size_t j = 0; j < num_matches; ++j) {
+ Module *module = module_list.GetModulePointerAtIndex(j);
+ if (module) {
+ if (LookupInModule(m_interpreter, module, result,
+ syntax_error)) {
+ result.GetOutputStream().EOL();
+ num_successful_lookups++;
}
+ }
}
-
- if (num_successful_lookups > 0)
- result.SetStatus (eReturnStatusSuccessFinishResult);
- else
- result.SetStatus (eReturnStatusFailed);
+ } else
+ result.AppendWarningWithFormat(
+ "Unable to find an image that matches '%s'.\n", arg_cstr);
}
- return result.Succeeded();
- }
+ }
- CommandOptions m_options;
-};
+ if (num_successful_lookups > 0)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
- { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup."},
- { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
- /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
- false, "regex", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
- { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules."},
- { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules."},
- { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."},
- { LLDB_OPT_SET_FROM_TO(3,5),
- false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."},
- { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."},
- { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules."},
- { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."},
- { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information."},
- { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
#pragma mark CommandObjectMultiwordImageSearchPaths
@@ -4330,22 +3833,33 @@ CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
// CommandObjectMultiwordImageSearchPaths
//-------------------------------------------------------------------------
-class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
-{
+class CommandObjectTargetModulesImageSearchPaths
+ : public CommandObjectMultiword {
public:
- CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "target modules search-paths",
- "Commands for managing module search paths for a target.",
- "target modules search-paths <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
- LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
- LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
- LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
- }
-
- ~CommandObjectTargetModulesImageSearchPaths() override = default;
+ CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "target modules search-paths",
+ "Commands for managing module search paths for a target.",
+ "target modules search-paths <subcommand> [<subcommand-options>]") {
+ LoadSubCommand(
+ "add", CommandObjectSP(
+ new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
+ LoadSubCommand(
+ "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
+ interpreter)));
+ LoadSubCommand(
+ "insert",
+ CommandObjectSP(
+ new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
+ LoadSubCommand(
+ "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
+ interpreter)));
+ LoadSubCommand(
+ "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
+ interpreter)));
+ }
+
+ ~CommandObjectTargetModulesImageSearchPaths() override = default;
};
#pragma mark CommandObjectTargetModules
@@ -4354,455 +3868,428 @@ public:
// CommandObjectTargetModules
//-------------------------------------------------------------------------
-class CommandObjectTargetModules : public CommandObjectMultiword
-{
+class CommandObjectTargetModules : public CommandObjectMultiword {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectTargetModules(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "target modules",
- "Commands for accessing information for one or more target modules.",
- "target modules <sub-command> ...")
- {
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
- LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
- LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
- LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
- LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
- LoadSubCommand ("show-unwind", CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));
-
- }
-
- ~CommandObjectTargetModules() override = default;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectTargetModules(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "target modules",
+ "Commands for accessing information for one or "
+ "more target modules.",
+ "target modules <sub-command> ...") {
+ LoadSubCommand(
+ "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
+ LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
+ interpreter)));
+ LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
+ interpreter)));
+ LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
+ interpreter)));
+ LoadSubCommand(
+ "lookup",
+ CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
+ LoadSubCommand(
+ "search-paths",
+ CommandObjectSP(
+ new CommandObjectTargetModulesImageSearchPaths(interpreter)));
+ LoadSubCommand(
+ "show-unwind",
+ CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
+ }
+
+ ~CommandObjectTargetModules() override = default;
private:
- //------------------------------------------------------------------
- // For CommandObjectTargetModules only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
+ //------------------------------------------------------------------
+ // For CommandObjectTargetModules only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
};
-class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
-{
+class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
public:
- CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target symbols add",
- "Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.",
- "target symbols add [<symfile>]", eCommandRequiresTarget),
- m_option_group (interpreter),
- m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
- m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
-
- {
- m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
- m_option_group.Finalize();
- }
-
- ~CommandObjectTargetSymbolsAdd() override = default;
-
- int
- HandleArgumentCompletion (Args &input,
- int &cursor_index,
- int &cursor_char_position,
- OptionElementVector &opt_element_vector,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches) override
- {
- std::string completion_str (input.GetArgumentAtIndex(cursor_index));
- completion_str.erase (cursor_char_position);
-
- CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
- CommandCompletions::eDiskFileCompletion,
- completion_str.c_str(),
- match_start_point,
- max_return_elements,
- nullptr,
- word_complete,
- matches);
- return matches.GetSize();
- }
-
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
+ CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "target symbols add",
+ "Add a debug symbol file to one of the target's current modules by "
+ "specifying a path to a debug symbols file, or using the options "
+ "to specify a module to download symbols for.",
+ "target symbols add [<symfile>]", eCommandRequiresTarget),
+ m_option_group(),
+ m_file_option(
+ LLDB_OPT_SET_1, false, "shlib", 's',
+ CommandCompletions::eModuleCompletion, eArgTypeShlibName,
+ "Fullpath or basename for module to find debug symbols for."),
+ m_current_frame_option(
+ LLDB_OPT_SET_2, false, "frame", 'F',
+ "Locate the debug symbols the currently selected frame.", false,
+ true)
+
+ {
+ m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
+ LLDB_OPT_SET_2);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectTargetSymbolsAdd() override = default;
+
+ int HandleArgumentCompletion(Args &input, int &cursor_index,
+ int &cursor_char_position,
+ OptionElementVector &opt_element_vector,
+ int match_start_point, int max_return_elements,
+ bool &word_complete,
+ StringList &matches) override {
+ std::string completion_str(input.GetArgumentAtIndex(cursor_index));
+ completion_str.erase(cursor_char_position);
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ completion_str.c_str(), match_start_point, max_return_elements, nullptr,
+ word_complete, matches);
+ return matches.GetSize();
+ }
+
+ Options *GetOptions() override { return &m_option_group; }
protected:
- bool
- AddModuleSymbols (Target *target,
- ModuleSpec &module_spec,
- bool &flush,
- CommandReturnObject &result)
- {
- const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
- if (symbol_fspec)
- {
- char symfile_path[PATH_MAX];
- symbol_fspec.GetPath (symfile_path, sizeof(symfile_path));
-
- if (!module_spec.GetUUID().IsValid())
- {
- if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
- module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
- }
- // We now have a module that represents a symbol file
- // that can be used for a module that might exist in the
- // current target, so we need to find that module in the
- // target
- ModuleList matching_module_list;
-
- size_t num_matches = 0;
- // First extract all module specs from the symbol file
- lldb_private::ModuleSpecList symfile_module_specs;
- if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs))
- {
- // Now extract the module spec that matches the target architecture
- ModuleSpec target_arch_module_spec;
- ModuleSpec symfile_module_spec;
- target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
- if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec))
- {
- // See if it has a UUID?
- if (symfile_module_spec.GetUUID().IsValid())
- {
- // It has a UUID, look for this UUID in the target modules
- ModuleSpec symfile_uuid_module_spec;
- symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
- num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
- }
- }
-
- if (num_matches == 0)
- {
- // No matches yet, iterate through the module specs to find a UUID value that
- // we can match up to an image in our target
- const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
- for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0; ++i)
- {
- if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec))
- {
- if (symfile_module_spec.GetUUID().IsValid())
- {
- // It has a UUID, look for this UUID in the target modules
- ModuleSpec symfile_uuid_module_spec;
- symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
- num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list);
- }
- }
- }
- }
- }
-
- // Just try to match up the file by basename if we have no matches at this point
- if (num_matches == 0)
- num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
-
- while (num_matches == 0)
- {
- ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension());
- // Empty string returned, lets bail
- if (!filename_no_extension)
- break;
-
- // Check if there was no extension to strip and the basename is the same
- if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
- break;
-
- // Replace basename with one less extension
- module_spec.GetFileSpec().GetFilename() = filename_no_extension;
+ bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
+ CommandReturnObject &result) {
+ const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
+ if (symbol_fspec) {
+ char symfile_path[PATH_MAX];
+ symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
+
+ if (!module_spec.GetUUID().IsValid()) {
+ if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
+ module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
+ }
+ // We now have a module that represents a symbol file
+ // that can be used for a module that might exist in the
+ // current target, so we need to find that module in the
+ // target
+ ModuleList matching_module_list;
+
+ size_t num_matches = 0;
+ // First extract all module specs from the symbol file
+ lldb_private::ModuleSpecList symfile_module_specs;
+ if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
+ 0, 0, symfile_module_specs)) {
+ // Now extract the module spec that matches the target architecture
+ ModuleSpec target_arch_module_spec;
+ ModuleSpec symfile_module_spec;
+ target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
+ if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
+ symfile_module_spec)) {
+ // See if it has a UUID?
+ if (symfile_module_spec.GetUUID().IsValid()) {
+ // It has a UUID, look for this UUID in the target modules
+ ModuleSpec symfile_uuid_module_spec;
+ symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
+ num_matches = target->GetImages().FindModules(
+ symfile_uuid_module_spec, matching_module_list);
+ }
+ }
- num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
+ if (num_matches == 0) {
+ // No matches yet, iterate through the module specs to find a UUID
+ // value that
+ // we can match up to an image in our target
+ const size_t num_symfile_module_specs =
+ symfile_module_specs.GetSize();
+ for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
+ ++i) {
+ if (symfile_module_specs.GetModuleSpecAtIndex(
+ i, symfile_module_spec)) {
+ if (symfile_module_spec.GetUUID().IsValid()) {
+ // It has a UUID, look for this UUID in the target modules
+ ModuleSpec symfile_uuid_module_spec;
+ symfile_uuid_module_spec.GetUUID() =
+ symfile_module_spec.GetUUID();
+ num_matches = target->GetImages().FindModules(
+ symfile_uuid_module_spec, matching_module_list);
+ }
}
-
- if (num_matches > 1)
- {
- result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path);
+ }
+ }
+ }
+
+ // Just try to match up the file by basename if we have no matches at this
+ // point
+ if (num_matches == 0)
+ num_matches =
+ target->GetImages().FindModules(module_spec, matching_module_list);
+
+ while (num_matches == 0) {
+ ConstString filename_no_extension(
+ module_spec.GetFileSpec().GetFileNameStrippingExtension());
+ // Empty string returned, lets bail
+ if (!filename_no_extension)
+ break;
+
+ // Check if there was no extension to strip and the basename is the same
+ if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
+ break;
+
+ // Replace basename with one less extension
+ module_spec.GetFileSpec().GetFilename() = filename_no_extension;
+
+ num_matches =
+ target->GetImages().FindModules(module_spec, matching_module_list);
+ }
+
+ if (num_matches > 1) {
+ result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
+ "use the --uuid option to resolve the "
+ "ambiguity.\n",
+ symfile_path);
+ } else if (num_matches == 1) {
+ ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
+
+ // The module has not yet created its symbol vendor, we can just
+ // give the existing target module the symfile path to use for
+ // when it decides to create it!
+ module_sp->SetSymbolFileFileSpec(symbol_fspec);
+
+ SymbolVendor *symbol_vendor =
+ module_sp->GetSymbolVendor(true, &result.GetErrorStream());
+ if (symbol_vendor) {
+ SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
+
+ if (symbol_file) {
+ ObjectFile *object_file = symbol_file->GetObjectFile();
+
+ if (object_file && object_file->GetFileSpec() == symbol_fspec) {
+ // Provide feedback that the symfile has been successfully added.
+ const FileSpec &module_fs = module_sp->GetFileSpec();
+ result.AppendMessageWithFormat(
+ "symbol file '%s' has been added to '%s'\n", symfile_path,
+ module_fs.GetPath().c_str());
+
+ // Let clients know something changed in the module
+ // if it is currently loaded
+ ModuleList module_list;
+ module_list.Append(module_sp);
+ target->SymbolsDidLoad(module_list);
+
+ // Make sure we load any scripting resources that may be embedded
+ // in the debug info files in case the platform supports that.
+ Error error;
+ StreamString feedback_stream;
+ module_sp->LoadScriptingResourceInTarget(target, error,
+ &feedback_stream);
+ if (error.Fail() && error.AsCString())
+ result.AppendWarningWithFormat(
+ "unable to load scripting data for module %s - error "
+ "reported was %s",
+ module_sp->GetFileSpec()
+ .GetFileNameStrippingExtension()
+ .GetCString(),
+ error.AsCString());
+ else if (feedback_stream.GetSize())
+ result.AppendWarningWithFormat("%s", feedback_stream.GetData());
+
+ flush = true;
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
}
- else if (num_matches == 1)
- {
- ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0));
-
- // The module has not yet created its symbol vendor, we can just
- // give the existing target module the symfile path to use for
- // when it decides to create it!
- module_sp->SetSymbolFileFileSpec (symbol_fspec);
-
- SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream());
- if (symbol_vendor)
- {
- SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
-
- if (symbol_file)
- {
- ObjectFile *object_file = symbol_file->GetObjectFile();
-
- if (object_file && object_file->GetFileSpec() == symbol_fspec)
- {
- // Provide feedback that the symfile has been successfully added.
- const FileSpec &module_fs = module_sp->GetFileSpec();
- result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n",
- symfile_path,
- module_fs.GetPath().c_str());
-
- // Let clients know something changed in the module
- // if it is currently loaded
- ModuleList module_list;
- module_list.Append (module_sp);
- target->SymbolsDidLoad (module_list);
-
- // Make sure we load any scripting resources that may be embedded
- // in the debug info files in case the platform supports that.
- Error error;
- StreamString feedback_stream;
- module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream);
- if (error.Fail() && error.AsCString())
- result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s",
- module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
- error.AsCString());
- else if (feedback_stream.GetSize())
- result.AppendWarningWithFormat("%s",feedback_stream.GetData());
-
- flush = true;
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
- }
- }
+ }
+ }
+ // Clear the symbol file spec if anything went wrong
+ module_sp->SetSymbolFileFileSpec(FileSpec());
+ }
+
+ if (module_spec.GetUUID().IsValid()) {
+ StreamString ss_symfile_uuid;
+ module_spec.GetUUID().Dump(&ss_symfile_uuid);
+ result.AppendErrorWithFormat(
+ "symbol file '%s' (%s) does not match any existing module%s\n",
+ symfile_path, ss_symfile_uuid.GetData(),
+ (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
+ ? "\n please specify the full path to the symbol file"
+ : "");
+ } else {
+ result.AppendErrorWithFormat(
+ "symbol file '%s' does not match any existing module%s\n",
+ symfile_path,
+ (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
+ ? "\n please specify the full path to the symbol file"
+ : "");
+ }
+ } else {
+ result.AppendError(
+ "one or more executable image paths must be specified");
+ }
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Target *target = m_exe_ctx.GetTargetPtr();
+ result.SetStatus(eReturnStatusFailed);
+ bool flush = false;
+ ModuleSpec module_spec;
+ const bool uuid_option_set =
+ m_uuid_option_group.GetOptionValue().OptionWasSet();
+ const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
+ const bool frame_option_set =
+ m_current_frame_option.GetOptionValue().OptionWasSet();
+ const size_t argc = args.GetArgumentCount();
+
+ if (argc == 0) {
+ if (uuid_option_set || file_option_set || frame_option_set) {
+ bool success = false;
+ bool error_set = false;
+ if (frame_option_set) {
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process) {
+ const StateType process_state = process->GetState();
+ if (StateIsStoppedState(process_state, true)) {
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
+ if (frame) {
+ ModuleSP frame_module_sp(
+ frame->GetSymbolContext(eSymbolContextModule).module_sp);
+ if (frame_module_sp) {
+ if (frame_module_sp->GetPlatformFileSpec().Exists()) {
+ module_spec.GetArchitecture() =
+ frame_module_sp->GetArchitecture();
+ module_spec.GetFileSpec() =
+ frame_module_sp->GetPlatformFileSpec();
+ }
+ module_spec.GetUUID() = frame_module_sp->GetUUID();
+ success = module_spec.GetUUID().IsValid() ||
+ module_spec.GetFileSpec();
+ } else {
+ result.AppendError("frame has no module");
+ error_set = true;
}
- // Clear the symbol file spec if anything went wrong
- module_sp->SetSymbolFileFileSpec (FileSpec());
- }
-
- if (module_spec.GetUUID().IsValid())
- {
- StreamString ss_symfile_uuid;
- module_spec.GetUUID().Dump(&ss_symfile_uuid);
- result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n",
- symfile_path,
- ss_symfile_uuid.GetData(),
- (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
- ? "\n please specify the full path to the symbol file"
- : "");
+ } else {
+ result.AppendError("invalid current frame");
+ error_set = true;
+ }
+ } else {
+ result.AppendErrorWithFormat("process is not stopped: %s",
+ StateAsCString(process_state));
+ error_set = true;
}
- else
- {
- result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n",
- symfile_path,
- (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
- ? "\n please specify the full path to the symbol file"
- : "");
+ } else {
+ result.AppendError(
+ "a process must exist in order to use the --frame option");
+ error_set = true;
+ }
+ } else {
+ if (uuid_option_set) {
+ module_spec.GetUUID() =
+ m_uuid_option_group.GetOptionValue().GetCurrentValue();
+ success |= module_spec.GetUUID().IsValid();
+ } else if (file_option_set) {
+ module_spec.GetFileSpec() =
+ m_file_option.GetOptionValue().GetCurrentValue();
+ ModuleSP module_sp(
+ target->GetImages().FindFirstModule(module_spec));
+ if (module_sp) {
+ module_spec.GetFileSpec() = module_sp->GetFileSpec();
+ module_spec.GetPlatformFileSpec() =
+ module_sp->GetPlatformFileSpec();
+ module_spec.GetUUID() = module_sp->GetUUID();
+ module_spec.GetArchitecture() = module_sp->GetArchitecture();
+ } else {
+ module_spec.GetArchitecture() = target->GetArchitecture();
}
+ success |= module_spec.GetUUID().IsValid() ||
+ module_spec.GetFileSpec().Exists();
+ }
}
- else
- {
- result.AppendError ("one or more executable image paths must be specified");
- }
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Target *target = m_exe_ctx.GetTargetPtr();
- result.SetStatus (eReturnStatusFailed);
- bool flush = false;
- ModuleSpec module_spec;
- const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
- const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
- const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
- const size_t argc = args.GetArgumentCount();
-
- if (argc == 0)
- {
- if (uuid_option_set || file_option_set || frame_option_set)
- {
- bool success = false;
- bool error_set = false;
- if (frame_option_set)
- {
- Process *process = m_exe_ctx.GetProcessPtr();
- if (process)
- {
- const StateType process_state = process->GetState();
- if (StateIsStoppedState (process_state, true))
- {
- StackFrame *frame = m_exe_ctx.GetFramePtr();
- if (frame)
- {
- ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
- if (frame_module_sp)
- {
- if (frame_module_sp->GetPlatformFileSpec().Exists())
- {
- module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
- module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
- }
- module_spec.GetUUID() = frame_module_sp->GetUUID();
- success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec();
- }
- else
- {
- result.AppendError ("frame has no module");
- error_set = true;
- }
- }
- else
- {
- result.AppendError ("invalid current frame");
- error_set = true;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
- error_set = true;
- }
- }
- else
- {
- result.AppendError ("a process must exist in order to use the --frame option");
- error_set = true;
- }
- }
- else
- {
- if (uuid_option_set)
- {
- module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
- success |= module_spec.GetUUID().IsValid();
- }
- else if (file_option_set)
- {
- module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
- ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
- if (module_sp)
- {
- module_spec.GetFileSpec() = module_sp->GetFileSpec();
- module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
- module_spec.GetUUID() = module_sp->GetUUID();
- module_spec.GetArchitecture() = module_sp->GetArchitecture();
- }
- else
- {
- module_spec.GetArchitecture() = target->GetArchitecture();
- }
- success |= module_spec.GetUUID().IsValid() || module_spec.GetFileSpec().Exists();
- }
- }
-
- if (success)
- {
- if (Symbols::DownloadObjectAndSymbolFile (module_spec))
- {
- if (module_spec.GetSymbolFileSpec())
- success = AddModuleSymbols (target, module_spec, flush, result);
- }
- }
+ if (success) {
+ if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
+ if (module_spec.GetSymbolFileSpec())
+ success = AddModuleSymbols(target, module_spec, flush, result);
+ }
+ }
- if (!success && !error_set)
- {
- StreamString error_strm;
- if (uuid_option_set)
- {
- error_strm.PutCString("unable to find debug symbols for UUID ");
- module_spec.GetUUID().Dump (&error_strm);
- }
- else if (file_option_set)
- {
- error_strm.PutCString("unable to find debug symbols for the executable file ");
- error_strm << module_spec.GetFileSpec();
- }
- else if (frame_option_set)
- {
- error_strm.PutCString("unable to find debug symbols for the current frame");
- }
- result.AppendError (error_strm.GetData());
- }
- }
- else
- {
- result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
- }
+ if (!success && !error_set) {
+ StreamString error_strm;
+ if (uuid_option_set) {
+ error_strm.PutCString("unable to find debug symbols for UUID ");
+ module_spec.GetUUID().Dump(&error_strm);
+ } else if (file_option_set) {
+ error_strm.PutCString(
+ "unable to find debug symbols for the executable file ");
+ error_strm << module_spec.GetFileSpec();
+ } else if (frame_option_set) {
+ error_strm.PutCString(
+ "unable to find debug symbols for the current frame");
+ }
+ result.AppendError(error_strm.GetString());
}
- else
- {
- if (uuid_option_set)
- {
- result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
+ } else {
+ result.AppendError("one or more symbol file paths must be specified, "
+ "or options must be specified");
+ }
+ } else {
+ if (uuid_option_set) {
+ result.AppendError("specify either one or more paths to symbol files "
+ "or use the --uuid option without arguments");
+ } else if (file_option_set) {
+ result.AppendError("specify either one or more paths to symbol files "
+ "or use the --file option without arguments");
+ } else if (frame_option_set) {
+ result.AppendError("specify either one or more paths to symbol files "
+ "or use the --frame option without arguments");
+ } else {
+ PlatformSP platform_sp(target->GetPlatform());
+
+ for (auto &entry : args.entries()) {
+ if (!entry.ref.empty()) {
+ module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
+ if (platform_sp) {
+ FileSpec symfile_spec;
+ if (platform_sp
+ ->ResolveSymbolFile(*target, module_spec, symfile_spec)
+ .Success())
+ module_spec.GetSymbolFileSpec() = symfile_spec;
}
- else if (file_option_set)
- {
- result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
- }
- else if (frame_option_set)
- {
- result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
- }
- else
- {
- PlatformSP platform_sp (target->GetPlatform());
-
- for (size_t i = 0; i < argc; ++i)
- {
- const char *symfile_path = args.GetArgumentAtIndex(i);
- if (symfile_path)
- {
- module_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
- if (platform_sp)
- {
- FileSpec symfile_spec;
- if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success())
- module_spec.GetSymbolFileSpec() = symfile_spec;
- }
- ArchSpec arch;
- bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
+ ArchSpec arch;
+ bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
- if (symfile_exists)
- {
- if (!AddModuleSymbols (target, module_spec, flush, result))
- break;
- }
- else
- {
- char resolved_symfile_path[PATH_MAX];
- if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
- {
- if (strcmp (resolved_symfile_path, symfile_path) != 0)
- {
- result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
- break;
- }
- }
- result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
- break;
- }
- }
- }
+ if (symfile_exists) {
+ if (!AddModuleSymbols(target, module_spec, flush, result))
+ break;
+ } else {
+ std::string resolved_symfile_path =
+ module_spec.GetSymbolFileSpec().GetPath();
+ if (resolved_symfile_path != entry.ref) {
+ result.AppendErrorWithFormat(
+ "invalid module path '%s' with resolved path '%s'\n",
+ entry.c_str(), resolved_symfile_path.c_str());
+ break;
+ }
+ result.AppendErrorWithFormat("invalid module path '%s'\n",
+ entry.c_str());
+ break;
}
+ }
}
+ }
+ }
- if (flush)
- {
- Process *process = m_exe_ctx.GetProcessPtr();
- if (process)
- process->Flush();
- }
- return result.Succeeded();
+ if (flush) {
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process)
+ process->Flush();
}
+ return result.Succeeded();
+ }
- OptionGroupOptions m_option_group;
- OptionGroupUUID m_uuid_option_group;
- OptionGroupFile m_file_option;
- OptionGroupBoolean m_current_frame_option;
+ OptionGroupOptions m_option_group;
+ OptionGroupUUID m_uuid_option_group;
+ OptionGroupFile m_file_option;
+ OptionGroupBoolean m_current_frame_option;
};
#pragma mark CommandObjectTargetSymbols
@@ -4811,26 +4298,27 @@ protected:
// CommandObjectTargetSymbols
//-------------------------------------------------------------------------
-class CommandObjectTargetSymbols : public CommandObjectMultiword
-{
+class CommandObjectTargetSymbols : public CommandObjectMultiword {
public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommandObjectTargetSymbols(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "target symbols", "Commands for adding and managing debug symbol files.",
- "target symbols <sub-command> ...")
- {
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
- }
-
- ~CommandObjectTargetSymbols() override = default;
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectTargetSymbols(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "target symbols",
+ "Commands for adding and managing debug symbol files.",
+ "target symbols <sub-command> ...") {
+ LoadSubCommand(
+ "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
+ }
+
+ ~CommandObjectTargetSymbols() override = default;
private:
- //------------------------------------------------------------------
- // For CommandObjectTargetModules only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
+ //------------------------------------------------------------------
+ // For CommandObjectTargetModules only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
};
#pragma mark CommandObjectTargetStopHookAdd
@@ -4839,360 +4327,313 @@ private:
// CommandObjectTargetStopHookAdd
//-------------------------------------------------------------------------
-class CommandObjectTargetStopHookAdd :
- public CommandObjectParsed,
- public IOHandlerDelegateMultiline
-{
-public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter),
- m_line_start(0),
- m_line_end (UINT_MAX),
- m_func_name_type_mask (eFunctionNameTypeAuto),
- m_sym_ctx_specified (false),
- m_thread_specified (false),
- m_use_one_liner (false),
- m_one_liner()
- {
- }
+static OptionDefinition g_target_stop_hook_add_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
+ { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run." },
+ { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The stop hook is run only for the thread whose index matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The stop hook is run only for the thread whose TID matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The stop hook is run only for the thread whose thread name matches this argument." },
+ { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The stop hook is run only for threads in the queue whose name is given by this argument." },
+ { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." },
+ { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Set the start of the line range for which the stop-hook is to be run." },
+ { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Set the end of the line range for which the stop-hook is to be run." },
+ { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." },
+ { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." },
+ // clang-format on
+};
- ~CommandOptions() override = default;
+class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
+ public IOHandlerDelegateMultiline {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_line_start(0), m_line_end(UINT_MAX),
+ m_func_name_type_mask(eFunctionNameTypeAuto),
+ m_sym_ctx_specified(false), m_thread_specified(false),
+ m_use_one_liner(false), m_one_liner() {}
+
+ ~CommandOptions() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_target_stop_hook_add_options);
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c':
+ m_class_name = option_arg;
+ m_sym_ctx_specified = true;
+ break;
+
+ case 'e':
+ if (option_arg.getAsInteger(0, m_line_end)) {
+ error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
+ option_arg.str().c_str());
+ break;
}
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
- bool success;
-
- switch (short_option)
- {
- case 'c':
- m_class_name = option_arg;
- m_sym_ctx_specified = true;
- break;
-
- case 'e':
- m_line_end = StringConvert::ToUInt32 (option_arg, UINT_MAX, 0, &success);
- if (!success)
- {
- error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
- break;
- }
- m_sym_ctx_specified = true;
- break;
-
- case 'l':
- m_line_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
- if (!success)
- {
- error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
- break;
- }
- m_sym_ctx_specified = true;
- break;
-
- case 'i':
- m_no_inlines = true;
- break;
-
- case 'n':
- m_function_name = option_arg;
- m_func_name_type_mask |= eFunctionNameTypeAuto;
- m_sym_ctx_specified = true;
- break;
-
- case 'f':
- m_file_name = option_arg;
- m_sym_ctx_specified = true;
- break;
-
- case 's':
- m_module_name = option_arg;
- m_sym_ctx_specified = true;
- break;
-
- case 't' :
- m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
- if (m_thread_id == LLDB_INVALID_THREAD_ID)
- error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
- m_thread_specified = true;
- break;
-
- case 'T':
- m_thread_name = option_arg;
- m_thread_specified = true;
- break;
-
- case 'q':
- m_queue_name = option_arg;
- m_thread_specified = true;
- break;
-
- case 'x':
- m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (m_thread_id == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
- m_thread_specified = true;
- break;
-
- case 'o':
- m_use_one_liner = true;
- m_one_liner = option_arg;
- break;
-
- default:
- error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_class_name.clear();
- m_function_name.clear();
- m_line_start = 0;
- m_line_end = UINT_MAX;
- m_file_name.clear();
- m_module_name.clear();
- m_func_name_type_mask = eFunctionNameTypeAuto;
- m_thread_id = LLDB_INVALID_THREAD_ID;
- m_thread_index = UINT32_MAX;
- m_thread_name.clear();
- m_queue_name.clear();
-
- m_no_inlines = false;
- m_sym_ctx_specified = false;
- m_thread_specified = false;
-
- m_use_one_liner = false;
- m_one_liner.clear();
+ m_sym_ctx_specified = true;
+ break;
+
+ case 'l':
+ if (option_arg.getAsInteger(0, m_line_start)) {
+ error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
+ option_arg.str().c_str());
+ break;
}
-
- static OptionDefinition g_option_table[];
-
- std::string m_class_name;
- std::string m_function_name;
- uint32_t m_line_start;
- uint32_t m_line_end;
- std::string m_file_name;
- std::string m_module_name;
- uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
- lldb::tid_t m_thread_id;
- uint32_t m_thread_index;
- std::string m_thread_name;
- std::string m_queue_name;
- bool m_sym_ctx_specified;
- bool m_no_inlines;
- bool m_thread_specified;
- // Instance variables to hold the values for one_liner options.
- bool m_use_one_liner;
- std::string m_one_liner;
- };
-
- CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target stop-hook add",
- "Add a hook to be executed when the target stops.",
- "target stop-hook add"),
- IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
- m_options (interpreter)
- {
+ m_sym_ctx_specified = true;
+ break;
+
+ case 'i':
+ m_no_inlines = true;
+ break;
+
+ case 'n':
+ m_function_name = option_arg;
+ m_func_name_type_mask |= eFunctionNameTypeAuto;
+ m_sym_ctx_specified = true;
+ break;
+
+ case 'f':
+ m_file_name = option_arg;
+ m_sym_ctx_specified = true;
+ break;
+
+ case 's':
+ m_module_name = option_arg;
+ m_sym_ctx_specified = true;
+ break;
+
+ case 't':
+ if (option_arg.getAsInteger(0, m_thread_id))
+ error.SetErrorStringWithFormat("invalid thread id string '%s'",
+ option_arg.str().c_str());
+ m_thread_specified = true;
+ break;
+
+ case 'T':
+ m_thread_name = option_arg;
+ m_thread_specified = true;
+ break;
+
+ case 'q':
+ m_queue_name = option_arg;
+ m_thread_specified = true;
+ break;
+
+ case 'x':
+ if (option_arg.getAsInteger(0, m_thread_index))
+ error.SetErrorStringWithFormat("invalid thread index string '%s'",
+ option_arg.str().c_str());
+ m_thread_specified = true;
+ break;
+
+ case 'o':
+ m_use_one_liner = true;
+ m_one_liner = option_arg;
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
+ break;
+ }
+ return error;
}
- ~CommandObjectTargetStopHookAdd() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_class_name.clear();
+ m_function_name.clear();
+ m_line_start = 0;
+ m_line_end = UINT_MAX;
+ m_file_name.clear();
+ m_module_name.clear();
+ m_func_name_type_mask = eFunctionNameTypeAuto;
+ m_thread_id = LLDB_INVALID_THREAD_ID;
+ m_thread_index = UINT32_MAX;
+ m_thread_name.clear();
+ m_queue_name.clear();
+
+ m_no_inlines = false;
+ m_sym_ctx_specified = false;
+ m_thread_specified = false;
+
+ m_use_one_liner = false;
+ m_one_liner.clear();
}
+ std::string m_class_name;
+ std::string m_function_name;
+ uint32_t m_line_start;
+ uint32_t m_line_end;
+ std::string m_file_name;
+ std::string m_module_name;
+ uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
+ lldb::tid_t m_thread_id;
+ uint32_t m_thread_index;
+ std::string m_thread_name;
+ std::string m_queue_name;
+ bool m_sym_ctx_specified;
+ bool m_no_inlines;
+ bool m_thread_specified;
+ // Instance variables to hold the values for one_liner options.
+ bool m_use_one_liner;
+ std::string m_one_liner;
+ };
+
+ CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target stop-hook add",
+ "Add a hook to be executed when the target stops.",
+ "target stop-hook add"),
+ IOHandlerDelegateMultiline("DONE",
+ IOHandlerDelegate::Completion::LLDBCommand),
+ m_options() {}
+
+ ~CommandObjectTargetStopHookAdd() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
protected:
- void
- IOHandlerActivated (IOHandler &io_handler) override
- {
+ void IOHandlerActivated(IOHandler &io_handler) override {
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp) {
+ output_sp->PutCString(
+ "Enter your stop hook command(s). Type 'DONE' to end.\n");
+ output_sp->Flush();
+ }
+ }
+
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &line) override {
+ if (m_stop_hook_sp) {
+ if (line.empty()) {
+ StreamFileSP error_sp(io_handler.GetErrorStreamFile());
+ if (error_sp) {
+ error_sp->Printf("error: stop hook #%" PRIu64
+ " aborted, no commands.\n",
+ m_stop_hook_sp->GetID());
+ error_sp->Flush();
+ }
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target)
+ target->RemoveStopHookByID(m_stop_hook_sp->GetID());
+ } else {
+ m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- if (output_sp)
- {
- output_sp->PutCString("Enter your stop hook command(s). Type 'DONE' to end.\n");
- output_sp->Flush();
+ if (output_sp) {
+ output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
+ m_stop_hook_sp->GetID());
+ output_sp->Flush();
}
+ }
+ m_stop_hook_sp.reset();
}
-
- void
- IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override
- {
- if (m_stop_hook_sp)
- {
- if (line.empty())
- {
- StreamFileSP error_sp(io_handler.GetErrorStreamFile());
- if (error_sp)
- {
- error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
- error_sp->Flush();
- }
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target)
- target->RemoveStopHookByID(m_stop_hook_sp->GetID());
- }
- else
- {
- m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- if (output_sp)
- {
- output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
- output_sp->Flush();
- }
- }
- m_stop_hook_sp.reset();
+ io_handler.SetIsDone(true);
+ }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ m_stop_hook_sp.reset();
+
+ Target *target = GetSelectedOrDummyTarget();
+ if (target) {
+ Target::StopHookSP new_hook_sp = target->CreateStopHook();
+
+ // First step, make the specifier.
+ std::unique_ptr<SymbolContextSpecifier> specifier_ap;
+ if (m_options.m_sym_ctx_specified) {
+ specifier_ap.reset(new SymbolContextSpecifier(
+ m_interpreter.GetDebugger().GetSelectedTarget()));
+
+ if (!m_options.m_module_name.empty()) {
+ specifier_ap->AddSpecification(
+ m_options.m_module_name.c_str(),
+ SymbolContextSpecifier::eModuleSpecified);
}
- io_handler.SetIsDone(true);
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- m_stop_hook_sp.reset();
-
- Target *target = GetSelectedOrDummyTarget();
- if (target)
- {
- Target::StopHookSP new_hook_sp = target->CreateStopHook();
-
- // First step, make the specifier.
- std::unique_ptr<SymbolContextSpecifier> specifier_ap;
- if (m_options.m_sym_ctx_specified)
- {
- specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
-
- if (!m_options.m_module_name.empty())
- {
- specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
- }
-
- if (!m_options.m_class_name.empty())
- {
- specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
- }
- if (!m_options.m_file_name.empty())
- {
- specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
- }
-
- if (m_options.m_line_start != 0)
- {
- specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
- }
-
- if (m_options.m_line_end != UINT_MAX)
- {
- specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
- }
-
- if (!m_options.m_function_name.empty())
- {
- specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
- }
- }
-
- if (specifier_ap)
- new_hook_sp->SetSpecifier (specifier_ap.release());
+ if (!m_options.m_class_name.empty()) {
+ specifier_ap->AddSpecification(
+ m_options.m_class_name.c_str(),
+ SymbolContextSpecifier::eClassOrNamespaceSpecified);
+ }
- // Next see if any of the thread options have been entered:
+ if (!m_options.m_file_name.empty()) {
+ specifier_ap->AddSpecification(
+ m_options.m_file_name.c_str(),
+ SymbolContextSpecifier::eFileSpecified);
+ }
- if (m_options.m_thread_specified)
- {
- ThreadSpec *thread_spec = new ThreadSpec();
+ if (m_options.m_line_start != 0) {
+ specifier_ap->AddLineSpecification(
+ m_options.m_line_start,
+ SymbolContextSpecifier::eLineStartSpecified);
+ }
- if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
- {
- thread_spec->SetTID (m_options.m_thread_id);
- }
+ if (m_options.m_line_end != UINT_MAX) {
+ specifier_ap->AddLineSpecification(
+ m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
+ }
- if (m_options.m_thread_index != UINT32_MAX)
- thread_spec->SetIndex (m_options.m_thread_index);
+ if (!m_options.m_function_name.empty()) {
+ specifier_ap->AddSpecification(
+ m_options.m_function_name.c_str(),
+ SymbolContextSpecifier::eFunctionSpecified);
+ }
+ }
- if (!m_options.m_thread_name.empty())
- thread_spec->SetName (m_options.m_thread_name.c_str());
+ if (specifier_ap)
+ new_hook_sp->SetSpecifier(specifier_ap.release());
- if (!m_options.m_queue_name.empty())
- thread_spec->SetQueueName (m_options.m_queue_name.c_str());
+ // Next see if any of the thread options have been entered:
- new_hook_sp->SetThreadSpecifier (thread_spec);
+ if (m_options.m_thread_specified) {
+ ThreadSpec *thread_spec = new ThreadSpec();
- }
- if (m_options.m_use_one_liner)
- {
- // Use one-liner.
- new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
- result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID());
- }
- else
- {
- m_stop_hook_sp = new_hook_sp;
- m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
- *this, // IOHandlerDelegate
- true, // Run IOHandler in async mode
- nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
-
- }
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError ("invalid target\n");
- result.SetStatus (eReturnStatusFailed);
+ if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
+ thread_spec->SetTID(m_options.m_thread_id);
}
- return result.Succeeded();
+ if (m_options.m_thread_index != UINT32_MAX)
+ thread_spec->SetIndex(m_options.m_thread_index);
+
+ if (!m_options.m_thread_name.empty())
+ thread_spec->SetName(m_options.m_thread_name.c_str());
+
+ if (!m_options.m_queue_name.empty())
+ thread_spec->SetQueueName(m_options.m_queue_name.c_str());
+
+ new_hook_sp->SetThreadSpecifier(thread_spec);
+ }
+ if (m_options.m_use_one_liner) {
+ // Use one-liner.
+ new_hook_sp->GetCommandPointer()->AppendString(
+ m_options.m_one_liner.c_str());
+ result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
+ new_hook_sp->GetID());
+ } else {
+ m_stop_hook_sp = new_hook_sp;
+ m_interpreter.GetLLDBCommandsFromIOHandler(
+ "> ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ nullptr); // Baton for the "io_handler" that will be passed back
+ // into our IOHandlerDelegate functions
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("invalid target\n");
+ result.SetStatus(eReturnStatusFailed);
}
-private:
- CommandOptions m_options;
- Target::StopHookSP m_stop_hook_sp;
-};
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
- "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
- { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
- "Set the module within which the stop-hook is to be run."},
- { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex,
- "The stop hook is run only for the thread whose index matches this argument."},
- { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID,
- "The stop hook is run only for the thread whose TID matches this argument."},
- { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName,
- "The stop hook is run only for the thread whose thread name matches this argument."},
- { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName,
- "The stop hook is run only for threads in the queue whose name is given by this argument."},
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
- "Specify the source file within which the stop-hook is to be run." },
- { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
- "Set the start of the line range for which the stop-hook is to be run."},
- { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
- "Set the end of the line range for which the stop-hook is to be run."},
- { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeClassName,
- "Specify the class within which the stop-hook is to be run." },
- { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "Set the function name within which the stop hook will be run." },
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
+ Target::StopHookSP m_stop_hook_sp;
};
#pragma mark CommandObjectTargetStopHookDelete
@@ -5201,71 +4642,56 @@ CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
// CommandObjectTargetStopHookDelete
//-------------------------------------------------------------------------
-class CommandObjectTargetStopHookDelete : public CommandObjectParsed
-{
+class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
public:
- CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target stop-hook delete",
- "Delete a stop-hook.",
- "target stop-hook delete [<idx>]")
- {
- }
+ CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target stop-hook delete",
+ "Delete a stop-hook.",
+ "target stop-hook delete [<idx>]") {}
- ~CommandObjectTargetStopHookDelete() override = default;
+ ~CommandObjectTargetStopHookDelete() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget();
- if (target)
- {
- // FIXME: see if we can use the breakpoint id style parser?
- size_t num_args = command.GetArgumentCount();
- if (num_args == 0)
- {
- if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
- {
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- target->RemoveAllStopHooks();
- }
- }
- else
- {
- bool success;
- for (size_t i = 0; i < num_args; i++)
- {
- lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- success = target->RemoveStopHookByID (user_id);
- if (!success)
- {
- result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- }
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target) {
+ // FIXME: see if we can use the breakpoint id style parser?
+ size_t num_args = command.GetArgumentCount();
+ if (num_args == 0) {
+ if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ target->RemoveAllStopHooks();
}
- else
- {
- result.AppendError ("invalid target\n");
- result.SetStatus (eReturnStatusFailed);
+ } else {
+ bool success;
+ for (size_t i = 0; i < num_args; i++) {
+ lldb::user_id_t user_id = StringConvert::ToUInt32(
+ command.GetArgumentAtIndex(i), 0, 0, &success);
+ if (!success) {
+ result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ success = target->RemoveStopHookByID(user_id);
+ if (!success) {
+ result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
-
- return result.Succeeded();
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("invalid target\n");
+ result.SetStatus(eReturnStatusFailed);
}
+
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectTargetStopHookEnableDisable
@@ -5274,66 +4700,55 @@ protected:
// CommandObjectTargetStopHookEnableDisable
//-------------------------------------------------------------------------
-class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
-{
+class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
public:
- CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
- CommandObjectParsed (interpreter,
- name,
- help,
- syntax),
- m_enable (enable)
- {
- }
+ CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
+ bool enable, const char *name,
+ const char *help, const char *syntax)
+ : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
+ }
- ~CommandObjectTargetStopHookEnableDisable() override = default;
+ ~CommandObjectTargetStopHookEnableDisable() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget();
- if (target)
- {
- // FIXME: see if we can use the breakpoint id style parser?
- size_t num_args = command.GetArgumentCount();
- bool success;
-
- if (num_args == 0)
- {
- target->SetAllStopHooksActiveState (m_enable);
- }
- else
- {
- for (size_t i = 0; i < num_args; i++)
- {
- lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- success = target->SetStopHookActiveStateByID (user_id, m_enable);
- if (!success)
- {
- result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- }
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError ("invalid target\n");
- result.SetStatus (eReturnStatusFailed);
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (target) {
+ // FIXME: see if we can use the breakpoint id style parser?
+ size_t num_args = command.GetArgumentCount();
+ bool success;
+
+ if (num_args == 0) {
+ target->SetAllStopHooksActiveState(m_enable);
+ } else {
+ for (size_t i = 0; i < num_args; i++) {
+ lldb::user_id_t user_id = StringConvert::ToUInt32(
+ command.GetArgumentAtIndex(i), 0, 0, &success);
+ if (!success) {
+ result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ success = target->SetStopHookActiveStateByID(user_id, m_enable);
+ if (!success) {
+ result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
- return result.Succeeded();
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("invalid target\n");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
+
private:
- bool m_enable;
+ bool m_enable;
};
#pragma mark CommandObjectTargetStopHookList
@@ -5342,49 +4757,39 @@ private:
// CommandObjectTargetStopHookList
//-------------------------------------------------------------------------
-class CommandObjectTargetStopHookList : public CommandObjectParsed
-{
+class CommandObjectTargetStopHookList : public CommandObjectParsed {
public:
- CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "target stop-hook list",
- "List all stop-hooks.",
- "target stop-hook list [<type>]")
- {
- }
+ CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "target stop-hook list",
+ "List all stop-hooks.",
+ "target stop-hook list [<type>]") {}
- ~CommandObjectTargetStopHookList() override = default;
+ ~CommandObjectTargetStopHookList() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = GetSelectedOrDummyTarget();
- if (!target)
- {
- result.AppendError ("invalid target\n");
- result.SetStatus (eReturnStatusFailed);
- return result.Succeeded();
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = GetSelectedOrDummyTarget();
+ if (!target) {
+ result.AppendError("invalid target\n");
+ result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
+ }
- size_t num_hooks = target->GetNumStopHooks ();
- if (num_hooks == 0)
- {
- result.GetOutputStream().PutCString ("No stop hooks.\n");
- }
- else
- {
- for (size_t i = 0; i < num_hooks; i++)
- {
- Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
- if (i > 0)
- result.GetOutputStream().PutCString ("\n");
- this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
- }
- }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return result.Succeeded();
+ size_t num_hooks = target->GetNumStopHooks();
+ if (num_hooks == 0) {
+ result.GetOutputStream().PutCString("No stop hooks.\n");
+ } else {
+ for (size_t i = 0; i < num_hooks; i++) {
+ Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
+ if (i > 0)
+ result.GetOutputStream().PutCString("\n");
+ this_hook->GetDescription(&(result.GetOutputStream()),
+ eDescriptionLevelFull);
+ }
}
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
};
#pragma mark CommandObjectMultiwordTargetStopHooks
@@ -5393,30 +4798,31 @@ protected:
// CommandObjectMultiwordTargetStopHooks
//-------------------------------------------------------------------------
-class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
-{
+class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
public:
- CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "target stop-hook",
- "Commands for operating on debugger target stop-hooks.",
- "target stop-hook <subcommand> [<subcommand-options>]")
- {
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
- LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
- false,
- "target stop-hook disable [<id>]",
- "Disable a stop-hook.",
- "target stop-hook disable")));
- LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
- true,
- "target stop-hook enable [<id>]",
- "Enable a stop-hook.",
- "target stop-hook enable")));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
- }
-
- ~CommandObjectMultiwordTargetStopHooks() override = default;
+ CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "target stop-hook",
+ "Commands for operating on debugger target stop-hooks.",
+ "target stop-hook <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("add", CommandObjectSP(
+ new CommandObjectTargetStopHookAdd(interpreter)));
+ LoadSubCommand(
+ "delete",
+ CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
+ LoadSubCommand("disable",
+ CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
+ interpreter, false, "target stop-hook disable [<id>]",
+ "Disable a stop-hook.", "target stop-hook disable")));
+ LoadSubCommand("enable",
+ CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
+ interpreter, true, "target stop-hook enable [<id>]",
+ "Enable a stop-hook.", "target stop-hook enable")));
+ LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
+ interpreter)));
+ }
+
+ ~CommandObjectMultiwordTargetStopHooks() override = default;
};
#pragma mark CommandObjectMultiwordTarget
@@ -5425,18 +4831,28 @@ public:
// CommandObjectMultiwordTarget
//-------------------------------------------------------------------------
-CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "target", "Commands for operating on debugger targets.",
- "target <subcommand> [<subcommand-options>]")
-{
- LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
- LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
- LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
- LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter)));
- LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
- LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
+CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "target",
+ "Commands for operating on debugger targets.",
+ "target <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("create",
+ CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
+ LoadSubCommand("delete",
+ CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
+ LoadSubCommand("list",
+ CommandObjectSP(new CommandObjectTargetList(interpreter)));
+ LoadSubCommand("select",
+ CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
+ LoadSubCommand(
+ "stop-hook",
+ CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
+ LoadSubCommand("modules",
+ CommandObjectSP(new CommandObjectTargetModules(interpreter)));
+ LoadSubCommand("symbols",
+ CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
+ LoadSubCommand("variable",
+ CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
}
CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
diff --git a/source/Commands/CommandObjectTarget.h b/source/Commands/CommandObjectTarget.h
index d99a2b07f9a7..865534111eec 100644
--- a/source/Commands/CommandObjectTarget.h
+++ b/source/Commands/CommandObjectTarget.h
@@ -14,9 +14,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Options.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/Options.h"
namespace lldb_private {
@@ -24,13 +24,11 @@ namespace lldb_private {
// CommandObjectMultiwordTarget
//-------------------------------------------------------------------------
-class CommandObjectMultiwordTarget : public CommandObjectMultiword
-{
+class CommandObjectMultiwordTarget : public CommandObjectMultiword {
public:
+ CommandObjectMultiwordTarget(CommandInterpreter &interpreter);
- CommandObjectMultiwordTarget (CommandInterpreter &interpreter);
-
- ~CommandObjectMultiwordTarget() override;
+ ~CommandObjectMultiwordTarget() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index 9e4bffdeb6a5..0c4072b19b84 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -13,9 +13,8 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Core/State.h"
#include "lldb/Core/SourceManager.h"
+#include "lldb/Core/State.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/StringConvert.h"
@@ -24,18 +23,19 @@
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/LineEntry.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanStepInRange.h"
#include "lldb/Target/ThreadPlanStepInstruction.h"
#include "lldb/Target/ThreadPlanStepOut.h"
#include "lldb/Target/ThreadPlanStepRange.h"
-#include "lldb/Target/ThreadPlanStepInRange.h"
+#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
@@ -44,1913 +44,1679 @@ using namespace lldb_private;
// CommandObjectThreadBacktrace
//-------------------------------------------------------------------------
-class CommandObjectIterateOverThreads : public CommandObjectParsed
-{
+class CommandObjectIterateOverThreads : public CommandObjectParsed {
public:
- CommandObjectIterateOverThreads (CommandInterpreter &interpreter,
- const char *name,
- const char *help,
- const char *syntax,
- uint32_t flags) :
- CommandObjectParsed (interpreter, name, help, syntax, flags)
- {
+ CommandObjectIterateOverThreads(CommandInterpreter &interpreter,
+ const char *name, const char *help,
+ const char *syntax, uint32_t flags)
+ : CommandObjectParsed(interpreter, name, help, syntax, flags) {}
+
+ ~CommandObjectIterateOverThreads() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ result.SetStatus(m_success_return);
+
+ if (command.GetArgumentCount() == 0) {
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ if (!HandleOneThread(thread->GetID(), result))
+ return false;
+ return result.Succeeded();
}
- ~CommandObjectIterateOverThreads() override = default;
+ // Use tids instead of ThreadSPs to prevent deadlocking problems which
+ // result from JIT-ing
+ // code while iterating over the (locked) ThreadSP list.
+ std::vector<lldb::tid_t> tids;
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- result.SetStatus (m_success_return);
+ if (command.GetArgumentCount() == 1 &&
+ ::strcmp(command.GetArgumentAtIndex(0), "all") == 0) {
+ Process *process = m_exe_ctx.GetProcessPtr();
- if (command.GetArgumentCount() == 0)
- {
- Thread *thread = m_exe_ctx.GetThreadPtr();
- if (!HandleOneThread (thread->GetID(), result))
- return false;
- return result.Succeeded();
- }
+ for (ThreadSP thread_sp : process->Threads())
+ tids.push_back(thread_sp->GetID());
+ } else {
+ const size_t num_args = command.GetArgumentCount();
+ Process *process = m_exe_ctx.GetProcessPtr();
- // Use tids instead of ThreadSPs to prevent deadlocking problems which result from JIT-ing
- // code while iterating over the (locked) ThreadSP list.
- std::vector<lldb::tid_t> tids;
+ std::lock_guard<std::recursive_mutex> guard(
+ process->GetThreadList().GetMutex());
- if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
- {
- Process *process = m_exe_ctx.GetProcessPtr();
+ for (size_t i = 0; i < num_args; i++) {
+ bool success;
- for (ThreadSP thread_sp : process->Threads())
- tids.push_back(thread_sp->GetID());
+ uint32_t thread_idx = StringConvert::ToUInt32(
+ command.GetArgumentAtIndex(i), 0, 0, &success);
+ if (!success) {
+ result.AppendErrorWithFormat("invalid thread specification: \"%s\"\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- else
- {
- const size_t num_args = command.GetArgumentCount();
- Process *process = m_exe_ctx.GetProcessPtr();
-
- std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
-
- for (size_t i = 0; i < num_args; i++)
- {
- bool success;
-
- uint32_t thread_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success);
- if (!success)
- {
- result.AppendErrorWithFormat ("invalid thread specification: \"%s\"\n", command.GetArgumentAtIndex(i));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- ThreadSP thread = process->GetThreadList().FindThreadByIndexID(thread_idx);
-
- if (!thread)
- {
- result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- tids.push_back(thread->GetID());
- }
+
+ ThreadSP thread =
+ process->GetThreadList().FindThreadByIndexID(thread_idx);
+
+ if (!thread) {
+ result.AppendErrorWithFormat("no thread with index: \"%s\"\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- uint32_t idx = 0;
- for (const lldb::tid_t &tid : tids)
- {
- if (idx != 0 && m_add_return)
- result.AppendMessage("");
+ tids.push_back(thread->GetID());
+ }
+ }
- if (!HandleOneThread (tid, result))
- return false;
+ uint32_t idx = 0;
+ for (const lldb::tid_t &tid : tids) {
+ if (idx != 0 && m_add_return)
+ result.AppendMessage("");
- ++idx;
- }
- return result.Succeeded();
+ if (!HandleOneThread(tid, result))
+ return false;
+
+ ++idx;
}
+ return result.Succeeded();
+ }
protected:
- // Override this to do whatever you need to do for one thread.
- //
- // If you return false, the iteration will stop, otherwise it will proceed.
- // The result is set to m_success_return (defaults to eReturnStatusSuccessFinishResult) before the iteration,
- // so you only need to set the return status in HandleOneThread if you want to indicate an error.
- // If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.)
-
- virtual bool
- HandleOneThread (lldb::tid_t, CommandReturnObject &result) = 0;
-
- ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
- bool m_add_return = true;
+ // Override this to do whatever you need to do for one thread.
+ //
+ // If you return false, the iteration will stop, otherwise it will proceed.
+ // The result is set to m_success_return (defaults to
+ // eReturnStatusSuccessFinishResult) before the iteration,
+ // so you only need to set the return status in HandleOneThread if you want to
+ // indicate an error.
+ // If m_add_return is true, a blank line will be inserted between each of the
+ // listings (except the last one.)
+
+ virtual bool HandleOneThread(lldb::tid_t, CommandReturnObject &result) = 0;
+
+ ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
+ bool m_add_return = true;
};
//-------------------------------------------------------------------------
// CommandObjectThreadBacktrace
//-------------------------------------------------------------------------
-class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads
-{
-public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'c':
- {
- bool success;
- int32_t input_count = StringConvert::ToSInt32 (option_arg, -1, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
- if (input_count < -1)
- m_count = UINT32_MAX;
- else
- m_count = input_count;
- }
- break;
- case 's':
- {
- bool success;
- m_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
- }
- break;
- case 'e':
- {
- bool success;
- m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
- }
- break;
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_count = UINT32_MAX;
- m_start = 0;
- m_extended_backtrace = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+static OptionDefinition g_thread_backtrace_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many frames to display (-1 for all)" },
+ { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace" },
+ { LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show the extended backtrace, if available" }
+ // clang-format on
+};
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
- uint32_t m_count;
- uint32_t m_start;
- bool m_extended_backtrace;
- };
-
- CommandObjectThreadBacktrace(CommandInterpreter &interpreter)
- : CommandObjectIterateOverThreads(
- interpreter, "thread backtrace", "Show thread call stacks. Defaults to the current thread, thread "
- "indexes can be specified as arguments. Use the thread-index \"all\" "
- "to see all threads.",
- nullptr, eCommandRequiresProcess | eCommandRequiresThread | eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
- m_options(interpreter)
- {
+class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
}
- ~CommandObjectThreadBacktrace() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c': {
+ int32_t input_count = 0;
+ if (option_arg.getAsInteger(0, m_count)) {
+ m_count = UINT32_MAX;
+ error.SetErrorStringWithFormat(
+ "invalid integer value for option '%c'", short_option);
+ } else if (input_count < 0)
+ m_count = UINT32_MAX;
+ } break;
+ case 's':
+ if (option_arg.getAsInteger(0, m_start))
+ error.SetErrorStringWithFormat(
+ "invalid integer value for option '%c'", short_option);
+ break;
+ case 'e': {
+ bool success;
+ m_extended_backtrace =
+ Args::StringToBoolean(option_arg, false, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid boolean value for option '%c'", short_option);
+ } break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
}
-protected:
- void
- DoExtendedBacktrace (Thread *thread, CommandReturnObject &result)
- {
- SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
- if (runtime)
- {
- Stream &strm = result.GetOutputStream();
- const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes();
- for (auto type : types)
- {
- ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type);
- if (ext_thread_sp && ext_thread_sp->IsValid ())
- {
- const uint32_t num_frames_with_source = 0;
- if (ext_thread_sp->GetStatus (strm,
- m_options.m_start,
- m_options.m_count,
- num_frames_with_source))
- {
- DoExtendedBacktrace (ext_thread_sp.get(), result);
- }
- }
- }
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_count = UINT32_MAX;
+ m_start = 0;
+ m_extended_backtrace = false;
}
- bool
- HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override
- {
- ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
- if (!thread_sp)
- {
- result.AppendErrorWithFormat ("thread disappeared while computing backtraces: 0x%" PRIx64 "\n", tid);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_backtrace_options);
+ }
- Thread *thread = thread_sp.get();
+ // Instance variables to hold the values for command options.
+ uint32_t m_count;
+ uint32_t m_start;
+ bool m_extended_backtrace;
+ };
+
+ CommandObjectThreadBacktrace(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread backtrace",
+ "Show thread call stacks. Defaults to the current thread, thread "
+ "indexes can be specified as arguments. Use the thread-index "
+ "\"all\" "
+ "to see all threads.",
+ nullptr,
+ eCommandRequiresProcess | eCommandRequiresThread |
+ eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_options() {}
+
+ ~CommandObjectThreadBacktrace() override = default;
+
+ Options *GetOptions() override { return &m_options; }
- Stream &strm = result.GetOutputStream();
+protected:
+ void DoExtendedBacktrace(Thread *thread, CommandReturnObject &result) {
+ SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
+ if (runtime) {
+ Stream &strm = result.GetOutputStream();
+ const std::vector<ConstString> &types =
+ runtime->GetExtendedBacktraceTypes();
+ for (auto type : types) {
+ ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread(
+ thread->shared_from_this(), type);
+ if (ext_thread_sp && ext_thread_sp->IsValid()) {
+ const uint32_t num_frames_with_source = 0;
+ const bool stop_format = false;
+ if (ext_thread_sp->GetStatus(strm, m_options.m_start,
+ m_options.m_count,
+ num_frames_with_source,
+ stop_format)) {
+ DoExtendedBacktrace(ext_thread_sp.get(), result);
+ }
+ }
+ }
+ }
+ }
+
+ bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
+ ThreadSP thread_sp =
+ m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+ if (!thread_sp) {
+ result.AppendErrorWithFormat(
+ "thread disappeared while computing backtraces: 0x%" PRIx64 "\n",
+ tid);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- // Don't show source context when doing backtraces.
- const uint32_t num_frames_with_source = 0;
+ Thread *thread = thread_sp.get();
- if (!thread->GetStatus (strm,
- m_options.m_start,
- m_options.m_count,
- num_frames_with_source))
- {
- result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread->GetIndexID());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (m_options.m_extended_backtrace)
- {
- DoExtendedBacktrace (thread, result);
- }
+ Stream &strm = result.GetOutputStream();
- return true;
+ // Don't show source context when doing backtraces.
+ const uint32_t num_frames_with_source = 0;
+ const bool stop_format = true;
+ if (!thread->GetStatus(strm, m_options.m_start, m_options.m_count,
+ num_frames_with_source, stop_format)) {
+ result.AppendErrorWithFormat(
+ "error displaying backtrace for thread: \"0x%4.4x\"\n",
+ thread->GetIndexID());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ if (m_options.m_extended_backtrace) {
+ DoExtendedBacktrace(thread, result);
}
- CommandOptions m_options;
-};
+ return true;
+ }
-OptionDefinition
-CommandObjectThreadBacktrace::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many frames to display (-1 for all)"},
-{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"},
-{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show the extended backtrace, if available"},
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
-enum StepScope
-{
- eStepScopeSource,
- eStepScopeInstruction
+enum StepScope { eStepScopeSource, eStepScopeInstruction };
+
+static OptionEnumValueElement g_tri_running_mode[] = {
+ {eOnlyThisThread, "this-thread", "Run only this thread"},
+ {eAllThreads, "all-threads", "Run all threads"},
+ {eOnlyDuringStepping, "while-stepping",
+ "Run only this thread while stepping"},
+ {0, nullptr, nullptr}};
+
+static OptionEnumValueElement g_duo_running_mode[] = {
+ {eOnlyThisThread, "this-thread", "Run only this thread"},
+ {eAllThreads, "all-threads", "Run all threads"},
+ {0, nullptr, nullptr}};
+
+static OptionDefinition g_thread_step_scope_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information." },
+ { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information." },
+ { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst." },
+ { LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over. You can also pass the string 'block' to step to the end of the current block. This is particularly useful in conjunction with --step-target to step through a complex calling sequence." },
+ { LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread." },
+ { LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in." },
+ { LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into." },
+ { LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step." }
+ // clang-format on
};
-class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed
-{
+class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed {
public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'a':
- {
- bool success;
- bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
- else
- {
- m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
- }
- }
- break;
-
- case 'A':
- {
- bool success;
- bool avoid_no_debug = Args::StringToBoolean (option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option);
- else
- {
- m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
- }
- }
- break;
-
- case 'c':
- m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (m_step_count == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid step count '%s'", option_arg);
- break;
-
- case 'C':
- m_class_name.clear();
- m_class_name.assign(option_arg);
- break;
-
- case 'm':
- {
- OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
- m_run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
- }
- break;
-
- case 'e':
- {
- if (strcmp(option_arg, "block") == 0)
- {
- m_end_line_is_block_end = 1;
- break;
- }
- uint32_t tmp_end_line = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (tmp_end_line == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid end line number '%s'", option_arg);
- else
- m_end_line = tmp_end_line;
- break;
- }
- break;
-
- case 'r':
- m_avoid_regexp.clear();
- m_avoid_regexp.assign(option_arg);
- break;
-
- case 't':
- m_step_in_target.clear();
- m_step_in_target.assign(option_arg);
- break;
-
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
+ ~CommandOptions() override = default;
- void
- OptionParsingStarting () override
- {
- m_step_in_avoid_no_debug = eLazyBoolCalculate;
- m_step_out_avoid_no_debug = eLazyBoolCalculate;
- m_run_mode = eOnlyDuringStepping;
-
- // Check if we are in Non-Stop mode
- lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
- if (target_sp && target_sp->GetNonStopModeEnabled())
- m_run_mode = eOnlyThisThread;
-
- m_avoid_regexp.clear();
- m_step_in_target.clear();
- m_class_name.clear();
- m_step_count = 1;
- m_end_line = LLDB_INVALID_LINE_NUMBER;
- m_end_line_is_block_end = false;
- }
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
+ switch (short_option) {
+ case 'a': {
+ bool success;
+ bool avoid_no_debug = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid boolean value for option '%c'", short_option);
+ else {
+ m_step_in_avoid_no_debug =
+ avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
}
+ } break;
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
- LazyBool m_step_in_avoid_no_debug;
- LazyBool m_step_out_avoid_no_debug;
- RunMode m_run_mode;
- std::string m_avoid_regexp;
- std::string m_step_in_target;
- std::string m_class_name;
- uint32_t m_step_count;
- uint32_t m_end_line;
- bool m_end_line_is_block_end;
- };
-
- CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
- const char *name,
- const char *help,
- const char *syntax,
- StepType step_type,
- StepScope step_scope) :
- CommandObjectParsed (interpreter, name, help, syntax,
- eCommandRequiresProcess |
- eCommandRequiresThread |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_step_type (step_type),
- m_step_scope (step_scope),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData thread_id_arg;
-
- // Define the first (and only) variant of this arg.
- thread_id_arg.arg_type = eArgTypeThreadID;
- thread_id_arg.arg_repetition = eArgRepeatOptional;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (thread_id_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+ case 'A': {
+ bool success;
+ bool avoid_no_debug = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid boolean value for option '%c'", short_option);
+ else {
+ m_step_out_avoid_no_debug =
+ avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
+ }
+ } break;
+
+ case 'c':
+ if (option_arg.getAsInteger(0, m_step_count))
+ error.SetErrorStringWithFormat("invalid step count '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'C':
+ m_class_name.clear();
+ m_class_name.assign(option_arg);
+ break;
+
+ case 'm': {
+ OptionEnumValueElement *enum_values =
+ GetDefinitions()[option_idx].enum_values;
+ m_run_mode = (lldb::RunMode)Args::StringToOptionEnum(
+ option_arg, enum_values, eOnlyDuringStepping, error);
+ } break;
+
+ case 'e':
+ if (option_arg == "block") {
+ m_end_line_is_block_end = 1;
+ break;
+ }
+ if (option_arg.getAsInteger(0, m_end_line))
+ error.SetErrorStringWithFormat("invalid end line number '%s'",
+ option_arg.str().c_str());
+ break;
+
+ case 'r':
+ m_avoid_regexp.clear();
+ m_avoid_regexp.assign(option_arg);
+ break;
+
+ case 't':
+ m_step_in_target.clear();
+ m_step_in_target.assign(option_arg);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
}
- ~CommandObjectThreadStepWithTypeAndScope() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_step_in_avoid_no_debug = eLazyBoolCalculate;
+ m_step_out_avoid_no_debug = eLazyBoolCalculate;
+ m_run_mode = eOnlyDuringStepping;
+
+ // Check if we are in Non-Stop mode
+ TargetSP target_sp =
+ execution_context ? execution_context->GetTargetSP() : TargetSP();
+ if (target_sp && target_sp->GetNonStopModeEnabled())
+ m_run_mode = eOnlyThisThread;
+
+ m_avoid_regexp.clear();
+ m_step_in_target.clear();
+ m_class_name.clear();
+ m_step_count = 1;
+ m_end_line = LLDB_INVALID_LINE_NUMBER;
+ m_end_line_is_block_end = false;
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Process *process = m_exe_ctx.GetProcessPtr();
- bool synchronous_execution = m_interpreter.GetSynchronous();
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_step_scope_options);
+ }
- const uint32_t num_threads = process->GetThreadList().GetSize();
- Thread *thread = nullptr;
+ // Instance variables to hold the values for command options.
+ LazyBool m_step_in_avoid_no_debug;
+ LazyBool m_step_out_avoid_no_debug;
+ RunMode m_run_mode;
+ std::string m_avoid_regexp;
+ std::string m_step_in_target;
+ std::string m_class_name;
+ uint32_t m_step_count;
+ uint32_t m_end_line;
+ bool m_end_line_is_block_end;
+ };
+
+ CommandObjectThreadStepWithTypeAndScope(CommandInterpreter &interpreter,
+ const char *name, const char *help,
+ const char *syntax,
+ StepType step_type,
+ StepScope step_scope)
+ : CommandObjectParsed(interpreter, name, help, syntax,
+ eCommandRequiresProcess | eCommandRequiresThread |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_step_type(step_type), m_step_scope(step_scope), m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData thread_id_arg;
+
+ // Define the first (and only) variant of this arg.
+ thread_id_arg.arg_type = eArgTypeThreadID;
+ thread_id_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(thread_id_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectThreadStepWithTypeAndScope() override = default;
+
+ Options *GetOptions() override { return &m_options; }
- if (command.GetArgumentCount() == 0)
- {
- thread = GetDefaultThread();
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Process *process = m_exe_ctx.GetProcessPtr();
+ bool synchronous_execution = m_interpreter.GetSynchronous();
+
+ const uint32_t num_threads = process->GetThreadList().GetSize();
+ Thread *thread = nullptr;
+
+ if (command.GetArgumentCount() == 0) {
+ thread = GetDefaultThread();
+
+ if (thread == nullptr) {
+ result.AppendError("no selected thread in process");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
+ uint32_t step_thread_idx =
+ StringConvert::ToUInt32(thread_idx_cstr, LLDB_INVALID_INDEX32);
+ if (step_thread_idx == LLDB_INVALID_INDEX32) {
+ result.AppendErrorWithFormat("invalid thread index '%s'.\n",
+ thread_idx_cstr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ thread =
+ process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
+ if (thread == nullptr) {
+ result.AppendErrorWithFormat(
+ "Thread index %u is out of range (valid values are 0 - %u).\n",
+ step_thread_idx, num_threads);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
- if (thread == nullptr)
- {
- result.AppendError ("no selected thread in process");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
- uint32_t step_thread_idx = StringConvert::ToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
- if (step_thread_idx == LLDB_INVALID_INDEX32)
- {
- result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
- if (thread == nullptr)
- {
- result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
- step_thread_idx, num_threads);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
+ if (m_step_type == eStepTypeScripted) {
+ if (m_options.m_class_name.empty()) {
+ result.AppendErrorWithFormat("empty class name for scripted step.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(
+ m_options.m_class_name.c_str())) {
+ result.AppendErrorWithFormat(
+ "class for scripted step: \"%s\" does not exist.",
+ m_options.m_class_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
- if (m_step_type == eStepTypeScripted)
- {
- if (m_options.m_class_name.empty())
- {
- result.AppendErrorWithFormat ("empty class name for scripted step.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else if (!m_interpreter.GetScriptInterpreter()->CheckObjectExists(m_options.m_class_name.c_str()))
- {
- result.AppendErrorWithFormat ("class for scripted step: \"%s\" does not exist.", m_options.m_class_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
+ if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER &&
+ m_step_type != eStepTypeInto) {
+ result.AppendErrorWithFormat(
+ "end line option is only valid for step into");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER
- && m_step_type != eStepTypeInto)
- {
- result.AppendErrorWithFormat("end line option is only valid for step into");
+ const bool abort_other_plans = false;
+ const lldb::RunMode stop_other_threads = m_options.m_run_mode;
+
+ // This is a bit unfortunate, but not all the commands in this command
+ // object support
+ // only while stepping, so I use the bool for them.
+ bool bool_stop_other_threads;
+ if (m_options.m_run_mode == eAllThreads)
+ bool_stop_other_threads = false;
+ else if (m_options.m_run_mode == eOnlyDuringStepping)
+ bool_stop_other_threads =
+ (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted);
+ else
+ bool_stop_other_threads = true;
+
+ ThreadPlanSP new_plan_sp;
+
+ if (m_step_type == eStepTypeInto) {
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+ assert(frame != nullptr);
+
+ if (frame->HasDebugInformation()) {
+ AddressRange range;
+ SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
+ if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER) {
+ Error error;
+ if (!sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range,
+ error)) {
+ result.AppendErrorWithFormat("invalid end-line option: %s.",
+ error.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
- }
-
- const bool abort_other_plans = false;
- const lldb::RunMode stop_other_threads = m_options.m_run_mode;
-
- // This is a bit unfortunate, but not all the commands in this command object support
- // only while stepping, so I use the bool for them.
- bool bool_stop_other_threads;
- if (m_options.m_run_mode == eAllThreads)
- bool_stop_other_threads = false;
- else if (m_options.m_run_mode == eOnlyDuringStepping)
- bool_stop_other_threads = (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted);
- else
- bool_stop_other_threads = true;
-
- ThreadPlanSP new_plan_sp;
-
- if (m_step_type == eStepTypeInto)
- {
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- assert(frame != nullptr);
-
- if (frame->HasDebugInformation ())
- {
- AddressRange range;
- SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
- if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER)
- {
- Error error;
- if (!sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range, error))
- {
- result.AppendErrorWithFormat("invalid end-line option: %s.", error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- else if (m_options.m_end_line_is_block_end)
- {
- Error error;
- Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
- if (!block)
- {
- result.AppendErrorWithFormat("Could not find the current block.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- AddressRange block_range;
- Address pc_address = frame->GetFrameCodeAddress();
- block->GetRangeContainingAddress(pc_address, block_range);
- if (!block_range.GetBaseAddress().IsValid())
- {
- result.AppendErrorWithFormat("Could not find the current block address.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- lldb::addr_t pc_offset_in_block = pc_address.GetFileAddress() - block_range.GetBaseAddress().GetFileAddress();
- lldb::addr_t range_length = block_range.GetByteSize() - pc_offset_in_block;
- range = AddressRange(pc_address, range_length);
- }
- else
- {
- range = sc.line_entry.range;
- }
-
- new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
- range,
- frame->GetSymbolContext(eSymbolContextEverything),
- m_options.m_step_in_target.c_str(),
- stop_other_threads,
- m_options.m_step_in_avoid_no_debug,
- m_options.m_step_out_avoid_no_debug);
-
- if (new_plan_sp && !m_options.m_avoid_regexp.empty())
- {
- ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
- step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
- }
- }
- else
- new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
- }
- else if (m_step_type == eStepTypeOver)
- {
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
-
- if (frame->HasDebugInformation())
- new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
- frame->GetSymbolContext(eSymbolContextEverything).line_entry,
- frame->GetSymbolContext(eSymbolContextEverything),
- stop_other_threads,
- m_options.m_step_out_avoid_no_debug);
- else
- new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
- abort_other_plans,
- bool_stop_other_threads);
- }
- else if (m_step_type == eStepTypeTrace)
- {
- new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
- }
- else if (m_step_type == eStepTypeTraceOver)
- {
- new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
- }
- else if (m_step_type == eStepTypeOut)
- {
- new_plan_sp = thread->QueueThreadPlanForStepOut(abort_other_plans,
- nullptr,
- false,
- bool_stop_other_threads,
- eVoteYes,
- eVoteNoOpinion,
- thread->GetSelectedFrameIndex(),
- m_options.m_step_out_avoid_no_debug);
- }
- else if (m_step_type == eStepTypeScripted)
- {
- new_plan_sp = thread->QueueThreadPlanForStepScripted (abort_other_plans,
- m_options.m_class_name.c_str(),
- bool_stop_other_threads);
- }
- else
- {
- result.AppendError ("step type is not supported");
- result.SetStatus (eReturnStatusFailed);
+ }
+ } else if (m_options.m_end_line_is_block_end) {
+ Error error;
+ Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
+ if (!block) {
+ result.AppendErrorWithFormat("Could not find the current block.");
+ result.SetStatus(eReturnStatusFailed);
return false;
- }
-
- // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
- // so that they can be interruptible). Then resume the process.
-
- if (new_plan_sp)
- {
- new_plan_sp->SetIsMasterPlan (true);
- new_plan_sp->SetOkayToDiscard (false);
-
- if (m_options.m_step_count > 1)
- {
- if (new_plan_sp->SetIterationCount(m_options.m_step_count))
- {
- result.AppendWarning ("step operation does not support iteration count.");
- }
- }
-
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-
- const uint32_t iohandler_id = process->GetIOHandlerID();
-
- StreamString stream;
- Error error;
- if (synchronous_execution)
- error = process->ResumeSynchronous (&stream);
- else
- error = process->Resume ();
-
- // There is a race condition where this thread will return up the call stack to the main command handler
- // and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
- // a chance to call PushProcessIOHandler().
- process->SyncIOHandler(iohandler_id, 2000);
-
- if (synchronous_execution)
- {
- // If any state changed events had anything to say, add that to the result
- if (stream.GetData())
- result.AppendMessage(stream.GetData());
+ }
+
+ AddressRange block_range;
+ Address pc_address = frame->GetFrameCodeAddress();
+ block->GetRangeContainingAddress(pc_address, block_range);
+ if (!block_range.GetBaseAddress().IsValid()) {
+ result.AppendErrorWithFormat(
+ "Could not find the current block address.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ lldb::addr_t pc_offset_in_block =
+ pc_address.GetFileAddress() -
+ block_range.GetBaseAddress().GetFileAddress();
+ lldb::addr_t range_length =
+ block_range.GetByteSize() - pc_offset_in_block;
+ range = AddressRange(pc_address, range_length);
+ } else {
+ range = sc.line_entry.range;
+ }
+
+ new_plan_sp = thread->QueueThreadPlanForStepInRange(
+ abort_other_plans, range,
+ frame->GetSymbolContext(eSymbolContextEverything),
+ m_options.m_step_in_target.c_str(), stop_other_threads,
+ m_options.m_step_in_avoid_no_debug,
+ m_options.m_step_out_avoid_no_debug);
+
+ if (new_plan_sp && !m_options.m_avoid_regexp.empty()) {
+ ThreadPlanStepInRange *step_in_range_plan =
+ static_cast<ThreadPlanStepInRange *>(new_plan_sp.get());
+ step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
+ }
+ } else
+ new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
+ false, abort_other_plans, bool_stop_other_threads);
+ } else if (m_step_type == eStepTypeOver) {
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+
+ if (frame->HasDebugInformation())
+ new_plan_sp = thread->QueueThreadPlanForStepOverRange(
+ abort_other_plans,
+ frame->GetSymbolContext(eSymbolContextEverything).line_entry,
+ frame->GetSymbolContext(eSymbolContextEverything),
+ stop_other_threads, m_options.m_step_out_avoid_no_debug);
+ else
+ new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
+ true, abort_other_plans, bool_stop_other_threads);
+ } else if (m_step_type == eStepTypeTrace) {
+ new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
+ false, abort_other_plans, bool_stop_other_threads);
+ } else if (m_step_type == eStepTypeTraceOver) {
+ new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
+ true, abort_other_plans, bool_stop_other_threads);
+ } else if (m_step_type == eStepTypeOut) {
+ new_plan_sp = thread->QueueThreadPlanForStepOut(
+ abort_other_plans, nullptr, false, bool_stop_other_threads, eVoteYes,
+ eVoteNoOpinion, thread->GetSelectedFrameIndex(),
+ m_options.m_step_out_avoid_no_debug);
+ } else if (m_step_type == eStepTypeScripted) {
+ new_plan_sp = thread->QueueThreadPlanForStepScripted(
+ abort_other_plans, m_options.m_class_name.c_str(),
+ bool_stop_other_threads);
+ } else {
+ result.AppendError("step type is not supported");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- result.SetDidChangeProcessState (true);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- }
- }
- else
- {
- result.AppendError ("Couldn't find thread plan to implement step type.");
- result.SetStatus (eReturnStatusFailed);
- }
- return result.Succeeded();
+ // If we got a new plan, then set it to be a master plan (User level Plans
+ // should be master plans
+ // so that they can be interruptible). Then resume the process.
+
+ if (new_plan_sp) {
+ new_plan_sp->SetIsMasterPlan(true);
+ new_plan_sp->SetOkayToDiscard(false);
+
+ if (m_options.m_step_count > 1) {
+ if (new_plan_sp->SetIterationCount(m_options.m_step_count)) {
+ result.AppendWarning(
+ "step operation does not support iteration count.");
+ }
+ }
+
+ process->GetThreadList().SetSelectedThreadByID(thread->GetID());
+
+ const uint32_t iohandler_id = process->GetIOHandlerID();
+
+ StreamString stream;
+ Error error;
+ if (synchronous_execution)
+ error = process->ResumeSynchronous(&stream);
+ else
+ error = process->Resume();
+
+ // There is a race condition where this thread will return up the call
+ // stack to the main command handler
+ // and show an (lldb) prompt before HandlePrivateEvent (from
+ // PrivateStateThread) has
+ // a chance to call PushProcessIOHandler().
+ process->SyncIOHandler(iohandler_id, 2000);
+
+ if (synchronous_execution) {
+ // If any state changed events had anything to say, add that to the
+ // result
+ if (stream.GetSize() > 0)
+ result.AppendMessage(stream.GetString());
+
+ process->GetThreadList().SetSelectedThreadByID(thread->GetID());
+ result.SetDidChangeProcessState(true);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.SetStatus(eReturnStatusSuccessContinuingNoResult);
+ }
+ } else {
+ result.AppendError("Couldn't find thread plan to implement step type.");
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
protected:
- StepType m_step_type;
- StepScope m_step_scope;
- CommandOptions m_options;
-};
-
-static OptionEnumValueElement
-g_tri_running_mode[] =
-{
-{ eOnlyThisThread, "this-thread", "Run only this thread"},
-{ eAllThreads, "all-threads", "Run all threads"},
-{ eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"},
-{ 0, nullptr, nullptr }
-};
-
-static OptionEnumValueElement
-g_duo_running_mode[] =
-{
-{ eOnlyThisThread, "this-thread", "Run only this thread"},
-{ eAllThreads, "all-threads", "Run all threads"},
-{ 0, nullptr, nullptr }
-};
-
-OptionDefinition
-CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
-{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."},
-{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},
-{ LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over."
- " You can also pass the string 'block' to step to the end of the current block."
- " This is particularly useful in conjunction with --step-target to step through a complex calling sequence."},
-{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
-{ LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
-{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
-{ LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."},
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ StepType m_step_type;
+ StepScope m_step_scope;
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectThreadContinue
//-------------------------------------------------------------------------
-class CommandObjectThreadContinue : public CommandObjectParsed
-{
+class CommandObjectThreadContinue : public CommandObjectParsed {
public:
- CommandObjectThreadContinue(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "thread continue", "Continue execution of the current target process. One "
- "or more threads may be specified, by default all "
- "threads continue.",
- nullptr, eCommandRequiresThread | eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
- {
- CommandArgumentEntry arg;
- CommandArgumentData thread_idx_arg;
-
- // Define the first (and only) variant of this arg.
- thread_idx_arg.arg_type = eArgTypeThreadIndex;
- thread_idx_arg.arg_repetition = eArgRepeatPlus;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (thread_idx_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+ CommandObjectThreadContinue(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "thread continue",
+ "Continue execution of the current target process. One "
+ "or more threads may be specified, by default all "
+ "threads continue.",
+ nullptr,
+ eCommandRequiresThread | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
+ CommandArgumentEntry arg;
+ CommandArgumentData thread_idx_arg;
+
+ // Define the first (and only) variant of this arg.
+ thread_idx_arg.arg_type = eArgTypeThreadIndex;
+ thread_idx_arg.arg_repetition = eArgRepeatPlus;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(thread_idx_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectThreadContinue() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ bool synchronous_execution = m_interpreter.GetSynchronous();
+
+ if (!m_interpreter.GetDebugger().GetSelectedTarget()) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- ~CommandObjectThreadContinue() override = default;
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- bool synchronous_execution = m_interpreter.GetSynchronous ();
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process == nullptr) {
+ result.AppendError("no process exists. Cannot continue");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (!m_interpreter.GetDebugger().GetSelectedTarget())
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
+ StateType state = process->GetState();
+ if ((state == eStateCrashed) || (state == eStateStopped) ||
+ (state == eStateSuspended)) {
+ const size_t argc = command.GetArgumentCount();
+ if (argc > 0) {
+ // These two lines appear at the beginning of both blocks in
+ // this if..else, but that is because we need to release the
+ // lock before calling process->Resume below.
+ std::lock_guard<std::recursive_mutex> guard(
+ process->GetThreadList().GetMutex());
+ const uint32_t num_threads = process->GetThreadList().GetSize();
+ std::vector<Thread *> resume_threads;
+ for (auto &entry : command.entries()) {
+ uint32_t thread_idx;
+ if (entry.ref.getAsInteger(0, thread_idx)) {
+ result.AppendErrorWithFormat(
+ "invalid thread index argument: \"%s\".\n", entry.c_str());
+ result.SetStatus(eReturnStatusFailed);
return false;
- }
-
- Process *process = m_exe_ctx.GetProcessPtr();
- if (process == nullptr)
- {
- result.AppendError ("no process exists. Cannot continue");
- result.SetStatus (eReturnStatusFailed);
+ }
+ Thread *thread =
+ process->GetThreadList().FindThreadByIndexID(thread_idx).get();
+
+ if (thread) {
+ resume_threads.push_back(thread);
+ } else {
+ result.AppendErrorWithFormat("invalid thread index %u.\n",
+ thread_idx);
+ result.SetStatus(eReturnStatusFailed);
return false;
- }
-
- StateType state = process->GetState();
- if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended))
- {
- const size_t argc = command.GetArgumentCount();
- if (argc > 0)
- {
- // These two lines appear at the beginning of both blocks in
- // this if..else, but that is because we need to release the
- // lock before calling process->Resume below.
- std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
- const uint32_t num_threads = process->GetThreadList().GetSize();
- std::vector<Thread *> resume_threads;
- for (uint32_t i = 0; i < argc; ++i)
- {
- bool success;
- const int base = 0;
- uint32_t thread_idx = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), LLDB_INVALID_INDEX32, base, &success);
- if (success)
- {
- Thread *thread = process->GetThreadList().FindThreadByIndexID(thread_idx).get();
-
- if (thread)
- {
- resume_threads.push_back(thread);
- }
- else
- {
- result.AppendErrorWithFormat("invalid thread index %u.\n", thread_idx);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- result.AppendErrorWithFormat ("invalid thread index argument: \"%s\".\n", command.GetArgumentAtIndex(i));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
-
- if (resume_threads.empty())
- {
- result.AppendError ("no valid thread indexes were specified");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- {
- if (resume_threads.size() == 1)
- result.AppendMessageWithFormat ("Resuming thread: ");
- else
- result.AppendMessageWithFormat ("Resuming threads: ");
-
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- {
- Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
- std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread);
-
- if (this_thread_pos != resume_threads.end())
- {
- resume_threads.erase(this_thread_pos);
- if (!resume_threads.empty())
- result.AppendMessageWithFormat ("%u, ", thread->GetIndexID());
- else
- result.AppendMessageWithFormat ("%u ", thread->GetIndexID());
-
- const bool override_suspend = true;
- thread->SetResumeState (eStateRunning, override_suspend);
- }
- else
- {
- thread->SetResumeState (eStateSuspended);
- }
- }
- result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
- }
- }
- else
- {
- // These two lines appear at the beginning of both blocks in
- // this if..else, but that is because we need to release the
- // lock before calling process->Resume below.
- std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex());
- const uint32_t num_threads = process->GetThreadList().GetSize();
- Thread *current_thread = GetDefaultThread();
- if (current_thread == nullptr)
- {
- result.AppendError ("the process doesn't have a current thread");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- // Set the actions that the threads should each take when resuming
- for (uint32_t idx = 0; idx < num_threads; ++idx)
- {
- Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
- if (thread == current_thread)
- {
- result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
- const bool override_suspend = true;
- thread->SetResumeState (eStateRunning, override_suspend);
- }
- else
- {
- thread->SetResumeState (eStateSuspended);
- }
- }
- }
-
- StreamString stream;
- Error error;
- if (synchronous_execution)
- error = process->ResumeSynchronous (&stream);
- else
- error = process->Resume ();
-
- // We should not be holding the thread list lock when we do this.
- if (error.Success())
- {
- result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
- if (synchronous_execution)
- {
- // If any state changed events had anything to say, add that to the result
- if (stream.GetData())
- result.AppendMessage(stream.GetData());
-
- result.SetDidChangeProcessState (true);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- }
- }
- else
- {
- result.AppendErrorWithFormat("Failed to resume process: %s\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
+ }
+ }
+
+ if (resume_threads.empty()) {
+ result.AppendError("no valid thread indexes were specified");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ if (resume_threads.size() == 1)
+ result.AppendMessageWithFormat("Resuming thread: ");
+ else
+ result.AppendMessageWithFormat("Resuming threads: ");
+
+ for (uint32_t idx = 0; idx < num_threads; ++idx) {
+ Thread *thread =
+ process->GetThreadList().GetThreadAtIndex(idx).get();
+ std::vector<Thread *>::iterator this_thread_pos =
+ find(resume_threads.begin(), resume_threads.end(), thread);
+
+ if (this_thread_pos != resume_threads.end()) {
+ resume_threads.erase(this_thread_pos);
+ if (!resume_threads.empty())
+ result.AppendMessageWithFormat("%u, ", thread->GetIndexID());
+ else
+ result.AppendMessageWithFormat("%u ", thread->GetIndexID());
+
+ const bool override_suspend = true;
+ thread->SetResumeState(eStateRunning, override_suspend);
+ } else {
+ thread->SetResumeState(eStateSuspended);
}
- }
- else
- {
- result.AppendErrorWithFormat ("Process cannot be continued from its current state (%s).\n",
- StateAsCString(state));
- result.SetStatus (eReturnStatusFailed);
- }
-
- return result.Succeeded();
+ }
+ result.AppendMessageWithFormat("in process %" PRIu64 "\n",
+ process->GetID());
+ }
+ } else {
+ // These two lines appear at the beginning of both blocks in
+ // this if..else, but that is because we need to release the
+ // lock before calling process->Resume below.
+ std::lock_guard<std::recursive_mutex> guard(
+ process->GetThreadList().GetMutex());
+ const uint32_t num_threads = process->GetThreadList().GetSize();
+ Thread *current_thread = GetDefaultThread();
+ if (current_thread == nullptr) {
+ result.AppendError("the process doesn't have a current thread");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ // Set the actions that the threads should each take when resuming
+ for (uint32_t idx = 0; idx < num_threads; ++idx) {
+ Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
+ if (thread == current_thread) {
+ result.AppendMessageWithFormat("Resuming thread 0x%4.4" PRIx64
+ " in process %" PRIu64 "\n",
+ thread->GetID(), process->GetID());
+ const bool override_suspend = true;
+ thread->SetResumeState(eStateRunning, override_suspend);
+ } else {
+ thread->SetResumeState(eStateSuspended);
+ }
+ }
+ }
+
+ StreamString stream;
+ Error error;
+ if (synchronous_execution)
+ error = process->ResumeSynchronous(&stream);
+ else
+ error = process->Resume();
+
+ // We should not be holding the thread list lock when we do this.
+ if (error.Success()) {
+ result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
+ process->GetID());
+ if (synchronous_execution) {
+ // If any state changed events had anything to say, add that to the
+ // result
+ if (stream.GetSize() > 0)
+ result.AppendMessage(stream.GetString());
+
+ result.SetDidChangeProcessState(true);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.SetStatus(eReturnStatusSuccessContinuingNoResult);
+ }
+ } else {
+ result.AppendErrorWithFormat("Failed to resume process: %s\n",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ result.AppendErrorWithFormat(
+ "Process cannot be continued from its current state (%s).\n",
+ StateAsCString(state));
+ result.SetStatus(eReturnStatusFailed);
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectThreadUntil
//-------------------------------------------------------------------------
-class CommandObjectThreadUntil : public CommandObjectParsed
-{
-public:
- class CommandOptions : public Options
- {
- public:
- uint32_t m_thread_idx;
- uint32_t m_frame_idx;
-
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_thread_idx(LLDB_INVALID_THREAD_ID),
- m_frame_idx(LLDB_INVALID_FRAME_ID)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
+static OptionDefinition g_thread_until_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0" },
+ { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation" },
+ { LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, nullptr, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one" },
+ { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times." }
+ // clang-format on
+};
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'a':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- if (error.Success())
- m_until_addrs.push_back(tmp_addr);
- }
- break;
- case 't':
- m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32);
- if (m_thread_idx == LLDB_INVALID_INDEX32)
- {
- error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg);
- }
- break;
- case 'f':
- m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID);
- if (m_frame_idx == LLDB_INVALID_FRAME_ID)
- {
- error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg);
- }
- break;
- case 'm':
- {
- OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values;
- lldb::RunMode run_mode = (lldb::RunMode) Args::StringToOptionEnum(option_arg, enum_values, eOnlyDuringStepping, error);
-
- if (error.Success())
- {
- if (run_mode == eAllThreads)
- m_stop_others = false;
- else
- m_stop_others = true;
- }
- }
- break;
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
+class CommandObjectThreadUntil : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ uint32_t m_thread_idx;
+ uint32_t m_frame_idx;
+
+ CommandOptions()
+ : Options(), m_thread_idx(LLDB_INVALID_THREAD_ID),
+ m_frame_idx(LLDB_INVALID_FRAME_ID) {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- void
- OptionParsingStarting () override
- {
- m_thread_idx = LLDB_INVALID_THREAD_ID;
- m_frame_idx = 0;
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'a': {
+ lldb::addr_t tmp_addr = Args::StringToAddress(
+ execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
+ if (error.Success())
+ m_until_addrs.push_back(tmp_addr);
+ } break;
+ case 't':
+ if (option_arg.getAsInteger(0, m_thread_idx)) {
+ m_thread_idx = LLDB_INVALID_INDEX32;
+ error.SetErrorStringWithFormat("invalid thread index '%s'",
+ option_arg.str().c_str());
+ }
+ break;
+ case 'f':
+ if (option_arg.getAsInteger(0, m_frame_idx)) {
+ m_frame_idx = LLDB_INVALID_FRAME_ID;
+ error.SetErrorStringWithFormat("invalid frame index '%s'",
+ option_arg.str().c_str());
+ }
+ break;
+ case 'm': {
+ OptionEnumValueElement *enum_values =
+ GetDefinitions()[option_idx].enum_values;
+ lldb::RunMode run_mode = (lldb::RunMode)Args::StringToOptionEnum(
+ option_arg, enum_values, eOnlyDuringStepping, error);
+
+ if (error.Success()) {
+ if (run_mode == eAllThreads)
m_stop_others = false;
- m_until_addrs.clear();
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- uint32_t m_step_thread_idx;
- bool m_stop_others;
- std::vector<lldb::addr_t> m_until_addrs;
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
- };
-
- CommandObjectThreadUntil(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "thread until", "Continue until a line number or address is reached by the "
- "current or specified thread. Stops when returning from "
- "the current function as a safety measure.",
- nullptr, eCommandRequiresThread | eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
- m_options(interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData line_num_arg;
-
- // Define the first (and only) variant of this arg.
- line_num_arg.arg_type = eArgTypeLineNum;
- line_num_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (line_num_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+ else
+ m_stop_others = true;
+ }
+ } break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
}
- ~CommandObjectThreadUntil() override = default;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_thread_idx = LLDB_INVALID_THREAD_ID;
+ m_frame_idx = 0;
+ m_stop_others = false;
+ m_until_addrs.clear();
+ }
- Options *
- GetOptions () override
- {
- return &m_options;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_until_options);
}
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- bool synchronous_execution = m_interpreter.GetSynchronous ();
-
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ uint32_t m_step_thread_idx;
+ bool m_stop_others;
+ std::vector<lldb::addr_t> m_until_addrs;
- Process *process = m_exe_ctx.GetProcessPtr();
- if (process == nullptr)
- {
- result.AppendError ("need a valid process to step");
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- Thread *thread = nullptr;
- std::vector<uint32_t> line_numbers;
-
- if (command.GetArgumentCount() >= 1)
- {
- size_t num_args = command.GetArgumentCount();
- for (size_t i = 0; i < num_args; i++)
- {
- uint32_t line_number;
- line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX);
- if (line_number == UINT32_MAX)
- {
- result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else
- line_numbers.push_back(line_number);
- }
- }
- else if (m_options.m_until_addrs.empty())
- {
- result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Instance variables to hold the values for command options.
+ };
- if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID)
- {
- thread = GetDefaultThread();
- }
- else
- {
- thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get();
- }
+ CommandObjectThreadUntil(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "thread until",
+ "Continue until a line number or address is reached by the "
+ "current or specified thread. Stops when returning from "
+ "the current function as a safety measure. "
+ "The target line number(s) are given as arguments, and if more than one"
+ " is provided, stepping will stop when the first one is hit.",
+ nullptr,
+ eCommandRequiresThread | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData line_num_arg;
- if (thread == nullptr)
- {
- const uint32_t num_threads = process->GetThreadList().GetSize();
- result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
- m_options.m_thread_idx,
- num_threads);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Define the first (and only) variant of this arg.
+ line_num_arg.arg_type = eArgTypeLineNum;
+ line_num_arg.arg_repetition = eArgRepeatPlain;
- const bool abort_other_plans = false;
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(line_num_arg);
- StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
- if (frame == nullptr)
- {
- result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n",
- m_options.m_frame_idx,
- m_options.m_thread_idx);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
- ThreadPlanSP new_plan_sp;
-
- if (frame->HasDebugInformation ())
- {
- // Finally we got here... Translate the given line number to a bunch of addresses:
- SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit));
- LineTable *line_table = nullptr;
- if (sc.comp_unit)
- line_table = sc.comp_unit->GetLineTable();
-
- if (line_table == nullptr)
- {
- result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n",
- m_options.m_frame_idx, m_options.m_thread_idx);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- LineEntry function_start;
- uint32_t index_ptr = 0, end_ptr;
- std::vector<addr_t> address_list;
-
- // Find the beginning & end index of the
- AddressRange fun_addr_range = sc.function->GetAddressRange();
- Address fun_start_addr = fun_addr_range.GetBaseAddress();
- line_table->FindLineEntryByAddress (fun_start_addr, function_start, &index_ptr);
-
- Address fun_end_addr(fun_start_addr.GetSection(),
- fun_start_addr.GetOffset() + fun_addr_range.GetByteSize());
-
- bool all_in_function = true;
-
- line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr);
-
- for (uint32_t line_number : line_numbers)
- {
- uint32_t start_idx_ptr = index_ptr;
- while (start_idx_ptr <= end_ptr)
- {
- LineEntry line_entry;
- const bool exact = false;
- start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry);
- if (start_idx_ptr == UINT32_MAX)
- break;
-
- addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target);
- if (address != LLDB_INVALID_ADDRESS)
- {
- if (fun_addr_range.ContainsLoadAddress (address, target))
- address_list.push_back (address);
- else
- all_in_function = false;
- }
- start_idx_ptr++;
- }
- }
-
- for (lldb::addr_t address : m_options.m_until_addrs)
- {
- if (fun_addr_range.ContainsLoadAddress (address, target))
- address_list.push_back (address);
- else
- all_in_function = false;
- }
-
- if (address_list.empty())
- {
- if (all_in_function)
- result.AppendErrorWithFormat ("No line entries matching until target.\n");
- else
- result.AppendErrorWithFormat ("Until target outside of the current function.\n");
-
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
- &address_list.front(),
- address_list.size(),
- m_options.m_stop_others,
- m_options.m_frame_idx);
- // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
- // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
- // will resume the original plan.
- new_plan_sp->SetIsMasterPlan (true);
- new_plan_sp->SetOkayToDiscard(false);
- }
- else
- {
- result.AppendErrorWithFormat ("Frame index %u of thread %u has no debug information.\n",
- m_options.m_frame_idx,
- m_options.m_thread_idx);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ ~CommandObjectThreadUntil() override = default;
- process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx);
-
- StreamString stream;
- Error error;
- if (synchronous_execution)
- error = process->ResumeSynchronous (&stream);
- else
- error = process->Resume ();
-
- if (error.Success())
- {
- result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
- if (synchronous_execution)
- {
- // If any state changed events had anything to say, add that to the result
- if (stream.GetData())
- result.AppendMessage(stream.GetData());
-
- result.SetDidChangeProcessState (true);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- }
- }
- else
- {
- result.AppendErrorWithFormat("Failed to resume process: %s.\n", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
+ Options *GetOptions() override { return &m_options; }
- }
- return result.Succeeded();
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ bool synchronous_execution = m_interpreter.GetSynchronous();
+
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("invalid target, create a debug target using the "
+ "'target create' command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- CommandOptions m_options;
-};
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process == nullptr) {
+ result.AppendError("need a valid process to step");
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ Thread *thread = nullptr;
+ std::vector<uint32_t> line_numbers;
+
+ if (command.GetArgumentCount() >= 1) {
+ size_t num_args = command.GetArgumentCount();
+ for (size_t i = 0; i < num_args; i++) {
+ uint32_t line_number;
+ line_number = StringConvert::ToUInt32(command.GetArgumentAtIndex(i),
+ UINT32_MAX);
+ if (line_number == UINT32_MAX) {
+ result.AppendErrorWithFormat("invalid line number: '%s'.\n",
+ command.GetArgumentAtIndex(i));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else
+ line_numbers.push_back(line_number);
+ }
+ } else if (m_options.m_until_addrs.empty()) {
+ result.AppendErrorWithFormat("No line number or address provided:\n%s",
+ GetSyntax().str().c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) {
+ thread = GetDefaultThread();
+ } else {
+ thread = process->GetThreadList()
+ .FindThreadByIndexID(m_options.m_thread_idx)
+ .get();
+ }
+
+ if (thread == nullptr) {
+ const uint32_t num_threads = process->GetThreadList().GetSize();
+ result.AppendErrorWithFormat(
+ "Thread index %u is out of range (valid values are 0 - %u).\n",
+ m_options.m_thread_idx, num_threads);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const bool abort_other_plans = false;
+
+ StackFrame *frame =
+ thread->GetStackFrameAtIndex(m_options.m_frame_idx).get();
+ if (frame == nullptr) {
+ result.AppendErrorWithFormat(
+ "Frame index %u is out of range for thread %u.\n",
+ m_options.m_frame_idx, m_options.m_thread_idx);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ThreadPlanSP new_plan_sp;
+
+ if (frame->HasDebugInformation()) {
+ // Finally we got here... Translate the given line number to a bunch of
+ // addresses:
+ SymbolContext sc(frame->GetSymbolContext(eSymbolContextCompUnit));
+ LineTable *line_table = nullptr;
+ if (sc.comp_unit)
+ line_table = sc.comp_unit->GetLineTable();
+
+ if (line_table == nullptr) {
+ result.AppendErrorWithFormat("Failed to resolve the line table for "
+ "frame %u of thread index %u.\n",
+ m_options.m_frame_idx,
+ m_options.m_thread_idx);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ LineEntry function_start;
+ uint32_t index_ptr = 0, end_ptr;
+ std::vector<addr_t> address_list;
+
+ // Find the beginning & end index of the
+ AddressRange fun_addr_range = sc.function->GetAddressRange();
+ Address fun_start_addr = fun_addr_range.GetBaseAddress();
+ line_table->FindLineEntryByAddress(fun_start_addr, function_start,
+ &index_ptr);
+
+ Address fun_end_addr(fun_start_addr.GetSection(),
+ fun_start_addr.GetOffset() +
+ fun_addr_range.GetByteSize());
+
+ bool all_in_function = true;
+
+ line_table->FindLineEntryByAddress(fun_end_addr, function_start,
+ &end_ptr);
+
+ for (uint32_t line_number : line_numbers) {
+ uint32_t start_idx_ptr = index_ptr;
+ while (start_idx_ptr <= end_ptr) {
+ LineEntry line_entry;
+ const bool exact = false;
+ start_idx_ptr = sc.comp_unit->FindLineEntry(
+ start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry);
+ if (start_idx_ptr == UINT32_MAX)
+ break;
+
+ addr_t address =
+ line_entry.range.GetBaseAddress().GetLoadAddress(target);
+ if (address != LLDB_INVALID_ADDRESS) {
+ if (fun_addr_range.ContainsLoadAddress(address, target))
+ address_list.push_back(address);
+ else
+ all_in_function = false;
+ }
+ start_idx_ptr++;
+ }
+ }
+
+ for (lldb::addr_t address : m_options.m_until_addrs) {
+ if (fun_addr_range.ContainsLoadAddress(address, target))
+ address_list.push_back(address);
+ else
+ all_in_function = false;
+ }
+
+ if (address_list.empty()) {
+ if (all_in_function)
+ result.AppendErrorWithFormat(
+ "No line entries matching until target.\n");
+ else
+ result.AppendErrorWithFormat(
+ "Until target outside of the current function.\n");
+
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ new_plan_sp = thread->QueueThreadPlanForStepUntil(
+ abort_other_plans, &address_list.front(), address_list.size(),
+ m_options.m_stop_others, m_options.m_frame_idx);
+ // User level plans should be master plans so they can be interrupted
+ // (e.g. by hitting a breakpoint)
+ // and other plans executed by the user (stepping around the breakpoint)
+ // and then a "continue"
+ // will resume the original plan.
+ new_plan_sp->SetIsMasterPlan(true);
+ new_plan_sp->SetOkayToDiscard(false);
+ } else {
+ result.AppendErrorWithFormat(
+ "Frame index %u of thread %u has no debug information.\n",
+ m_options.m_frame_idx, m_options.m_thread_idx);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ process->GetThreadList().SetSelectedThreadByID(m_options.m_thread_idx);
+
+ StreamString stream;
+ Error error;
+ if (synchronous_execution)
+ error = process->ResumeSynchronous(&stream);
+ else
+ error = process->Resume();
+
+ if (error.Success()) {
+ result.AppendMessageWithFormat("Process %" PRIu64 " resuming\n",
+ process->GetID());
+ if (synchronous_execution) {
+ // If any state changed events had anything to say, add that to the
+ // result
+ if (stream.GetSize() > 0)
+ result.AppendMessage(stream.GetString());
+
+ result.SetDidChangeProcessState(true);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.SetStatus(eReturnStatusSuccessContinuingNoResult);
+ }
+ } else {
+ result.AppendErrorWithFormat("Failed to resume process: %s.\n",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectThreadUntil::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"},
-{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"},
-{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, nullptr, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one"},
-{ LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."},
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectThreadSelect
//-------------------------------------------------------------------------
-class CommandObjectThreadSelect : public CommandObjectParsed
-{
+class CommandObjectThreadSelect : public CommandObjectParsed {
public:
- CommandObjectThreadSelect(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "thread select", "Change the currently selected thread.", nullptr,
- eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused)
- {
- CommandArgumentEntry arg;
- CommandArgumentData thread_idx_arg;
-
- // Define the first (and only) variant of this arg.
- thread_idx_arg.arg_type = eArgTypeThreadIndex;
- thread_idx_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (thread_idx_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ CommandObjectThreadSelect(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "thread select",
+ "Change the currently selected thread.", nullptr,
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused) {
+ CommandArgumentEntry arg;
+ CommandArgumentData thread_idx_arg;
- ~CommandObjectThreadSelect() override = default;
+ // Define the first (and only) variant of this arg.
+ thread_idx_arg.arg_type = eArgTypeThreadIndex;
+ thread_idx_arg.arg_repetition = eArgRepeatPlain;
-protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Process *process = m_exe_ctx.GetProcessPtr();
- if (process == nullptr)
- {
- result.AppendError ("no process");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- else if (command.GetArgumentCount() != 1)
- {
- result.AppendErrorWithFormat("'%s' takes exactly one thread index argument:\nUsage: %s\n", m_cmd_name.c_str(), m_cmd_syntax.c_str());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(thread_idx_arg);
- uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
- Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get();
- if (new_thread == nullptr)
- {
- result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ ~CommandObjectThreadSelect() override = default;
- process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
-
- return result.Succeeded();
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process == nullptr) {
+ result.AppendError("no process");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else if (command.GetArgumentCount() != 1) {
+ result.AppendErrorWithFormat(
+ "'%s' takes exactly one thread index argument:\nUsage: %s\n",
+ m_cmd_name.c_str(), m_cmd_syntax.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ uint32_t index_id =
+ StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0);
+
+ Thread *new_thread =
+ process->GetThreadList().FindThreadByIndexID(index_id).get();
+ if (new_thread == nullptr) {
+ result.AppendErrorWithFormat("invalid thread #%s.\n",
+ command.GetArgumentAtIndex(0));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectThreadList
//-------------------------------------------------------------------------
-class CommandObjectThreadList : public CommandObjectParsed
-{
+class CommandObjectThreadList : public CommandObjectParsed {
public:
- CommandObjectThreadList(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "thread list",
- "Show a summary of each thread in the current target process.", "thread list",
- eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused)
- {
- }
+ CommandObjectThreadList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "thread list",
+ "Show a summary of each thread in the current target process.",
+ "thread list",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
- ~CommandObjectThreadList() override = default;
+ ~CommandObjectThreadList() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Stream &strm = result.GetOutputStream();
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- Process *process = m_exe_ctx.GetProcessPtr();
- const bool only_threads_with_stop_reason = false;
- const uint32_t start_frame = 0;
- const uint32_t num_frames = 0;
- const uint32_t num_frames_with_source = 0;
- process->GetStatus(strm);
- process->GetThreadStatus (strm,
- only_threads_with_stop_reason,
- start_frame,
- num_frames,
- num_frames_with_source);
- return result.Succeeded();
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Stream &strm = result.GetOutputStream();
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ Process *process = m_exe_ctx.GetProcessPtr();
+ const bool only_threads_with_stop_reason = false;
+ const uint32_t start_frame = 0;
+ const uint32_t num_frames = 0;
+ const uint32_t num_frames_with_source = 0;
+ process->GetStatus(strm);
+ process->GetThreadStatus(strm, only_threads_with_stop_reason, start_frame,
+ num_frames, num_frames_with_source, false);
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectThreadInfo
//-------------------------------------------------------------------------
-class CommandObjectThreadInfo : public CommandObjectIterateOverThreads
-{
-public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- OptionParsingStarting ();
- }
+static OptionDefinition g_thread_info_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "json", 'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format." },
+ { LLDB_OPT_SET_ALL, false, "stop-info", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the extended stop info in JSON format." }
+ // clang-format on
+};
- ~CommandOptions() override = default;
+class CommandObjectThreadInfo : public CommandObjectIterateOverThreads {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
- void
- OptionParsingStarting () override
- {
- m_json_thread = false;
- m_json_stopinfo = false;
- }
+ ~CommandOptions() override = default;
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- const int short_option = m_getopt_table[option_idx].val;
- Error error;
-
- switch (short_option)
- {
- case 'j':
- m_json_thread = true;
- break;
-
- case 's':
- m_json_stopinfo = true;
- break;
-
- default:
- return Error("invalid short option character '%c'", short_option);
- }
- return error;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_json_thread = false;
+ m_json_stopinfo = false;
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ const int short_option = m_getopt_table[option_idx].val;
+ Error error;
- bool m_json_thread;
- bool m_json_stopinfo;
-
- static OptionDefinition g_option_table[];
- };
-
- CommandObjectThreadInfo(CommandInterpreter &interpreter)
- : CommandObjectIterateOverThreads(
- interpreter, "thread info",
- "Show an extended summary of one or more threads. Defaults to the current thread.", "thread info",
- eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused),
- m_options(interpreter)
- {
- m_add_return = false;
- }
+ switch (short_option) {
+ case 'j':
+ m_json_thread = true;
+ break;
- ~CommandObjectThreadInfo() override = default;
+ case 's':
+ m_json_stopinfo = true;
+ break;
- Options *
- GetOptions () override
- {
- return &m_options;
+ default:
+ return Error("invalid short option character '%c'", short_option);
+ }
+ return error;
}
- bool
- HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override
- {
- ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
- if (!thread_sp)
- {
- result.AppendErrorWithFormat ("thread no longer exists: 0x%" PRIx64 "\n", tid);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- Thread *thread = thread_sp.get();
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_info_options);
+ }
- Stream &strm = result.GetOutputStream();
- if (!thread->GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo))
- {
- result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread->GetIndexID());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- return true;
+ bool m_json_thread;
+ bool m_json_stopinfo;
+ };
+
+ CommandObjectThreadInfo(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread info", "Show an extended summary of one or "
+ "more threads. Defaults to the "
+ "current thread.",
+ "thread info",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options() {
+ m_add_return = false;
+ }
+
+ ~CommandObjectThreadInfo() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
+ ThreadSP thread_sp =
+ m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+ if (!thread_sp) {
+ result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
+ tid);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- CommandOptions m_options;
-};
+ Thread *thread = thread_sp.get();
-OptionDefinition
-CommandObjectThreadInfo::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format."},
- { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the extended stop info in JSON format."},
+ Stream &strm = result.GetOutputStream();
+ if (!thread->GetDescription(strm, eDescriptionLevelFull,
+ m_options.m_json_thread,
+ m_options.m_json_stopinfo)) {
+ result.AppendErrorWithFormat("error displaying info for thread: \"%d\"\n",
+ thread->GetIndexID());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ return true;
+ }
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectThreadReturn
//-------------------------------------------------------------------------
-class CommandObjectThreadReturn : public CommandObjectRaw
-{
+static OptionDefinition g_thread_return_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation." }
+ // clang-format on
+};
+
+class CommandObjectThreadReturn : public CommandObjectRaw {
public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_from_expression (false)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_from_expression(false) {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'x':
- {
- bool success;
- bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
- if (success)
- m_from_expression = tmp_value;
- else
- {
- error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
- }
- }
- break;
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
+ ~CommandOptions() override = default;
- void
- OptionParsingStarting () override
- {
- m_from_expression = false;
- }
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ switch (short_option) {
+ case 'x': {
+ bool success;
+ bool tmp_value = Args::StringToBoolean(option_arg, false, &success);
+ if (success)
+ m_from_expression = tmp_value;
+ else {
+ error.SetErrorStringWithFormat(
+ "invalid boolean value '%s' for 'x' option",
+ option_arg.str().c_str());
+ }
+ } break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
+ }
- bool m_from_expression;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_from_expression = false;
+ }
- // Options table: Required for subclasses of Options.
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_return_options);
+ }
- static OptionDefinition g_option_table[];
+ bool m_from_expression;
- // Instance variables to hold the values for command options.
- };
+ // Instance variables to hold the values for command options.
+ };
- CommandObjectThreadReturn(CommandInterpreter &interpreter)
- : CommandObjectRaw(interpreter, "thread return",
- "Prematurely return from a stack frame, short-circuiting execution of newer frames "
- "and optionally yielding a specified value. Defaults to the exiting the current stack "
- "frame.",
- "thread return", eCommandRequiresFrame | eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
- m_options(interpreter)
- {
- CommandArgumentEntry arg;
- CommandArgumentData expression_arg;
+ CommandObjectThreadReturn(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "thread return",
+ "Prematurely return from a stack frame, "
+ "short-circuiting execution of newer frames "
+ "and optionally yielding a specified value. Defaults "
+ "to the exiting the current stack "
+ "frame.",
+ "thread return",
+ eCommandRequiresFrame | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandArgumentData expression_arg;
+
+ // Define the first (and only) variant of this arg.
+ expression_arg.arg_type = eArgTypeExpression;
+ expression_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(expression_arg);
- // Define the first (and only) variant of this arg.
- expression_arg.arg_type = eArgTypeExpression;
- expression_arg.arg_repetition = eArgRepeatOptional;
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (expression_arg);
+ ~CommandObjectThreadReturn() override = default;
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecute(const char *command, CommandReturnObject &result) override {
+ // I am going to handle this by hand, because I don't want you to have to
+ // say:
+ // "thread return -- -5".
+ if (command[0] == '-' && command[1] == 'x') {
+ if (command && command[2] != '\0')
+ result.AppendWarning("Return values ignored when returning from user "
+ "called expressions");
+
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ Error error;
+ error = thread->UnwindInnermostExpression();
+ if (!error.Success()) {
+ result.AppendErrorWithFormat("Unwinding expression failed - %s.",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ bool success =
+ thread->SetSelectedFrameByIndexNoisily(0, result.GetOutputStream());
+ if (success) {
+ m_exe_ctx.SetFrameSP(thread->GetSelectedFrame());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat(
+ "Could not select 0th frame after unwinding expression.");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ }
+ return result.Succeeded();
}
- ~CommandObjectThreadReturn() override = default;
+ ValueObjectSP return_valobj_sp;
- Options *
- GetOptions() override
- {
- return &m_options;
+ StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
+ uint32_t frame_idx = frame_sp->GetFrameIndex();
+
+ if (frame_sp->IsInlined()) {
+ result.AppendError("Don't know how to return from inlined frames.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-protected:
- bool
- DoExecute (const char *command, CommandReturnObject &result) override
- {
- // I am going to handle this by hand, because I don't want you to have to say:
- // "thread return -- -5".
- if (command[0] == '-' && command[1] == 'x')
- {
- if (command && command[2] != '\0')
- result.AppendWarning("Return values ignored when returning from user called expressions");
-
- Thread *thread = m_exe_ctx.GetThreadPtr();
- Error error;
- error = thread->UnwindInnermostExpression();
- if (!error.Success())
- {
- result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
- if (success)
- {
- m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
- result.SetStatus (eReturnStatusFailed);
- }
- }
- return result.Succeeded();
- }
-
- ValueObjectSP return_valobj_sp;
-
- StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
- uint32_t frame_idx = frame_sp->GetFrameIndex();
-
- if (frame_sp->IsInlined())
- {
- result.AppendError("Don't know how to return from inlined frames.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- if (command && command[0] != '\0')
- {
- Target *target = m_exe_ctx.GetTargetPtr();
- EvaluateExpressionOptions options;
-
- options.SetUnwindOnError(true);
- options.SetUseDynamic(eNoDynamicValues);
-
- ExpressionResults exe_results = eExpressionSetupError;
- exe_results = target->EvaluateExpression (command,
- frame_sp.get(),
- return_valobj_sp,
- options);
- if (exe_results != eExpressionCompleted)
- {
- if (return_valobj_sp)
- result.AppendErrorWithFormat("Error evaluating result expression: %s", return_valobj_sp->GetError().AsCString());
- else
- result.AppendErrorWithFormat("Unknown error evaluating result expression.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
-
- Error error;
- ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
- const bool broadcast = true;
- error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
- if (!error.Success())
- {
- result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (command && command[0] != '\0') {
+ Target *target = m_exe_ctx.GetTargetPtr();
+ EvaluateExpressionOptions options;
+
+ options.SetUnwindOnError(true);
+ options.SetUseDynamic(eNoDynamicValues);
+
+ ExpressionResults exe_results = eExpressionSetupError;
+ exe_results = target->EvaluateExpression(command, frame_sp.get(),
+ return_valobj_sp, options);
+ if (exe_results != eExpressionCompleted) {
+ if (return_valobj_sp)
+ result.AppendErrorWithFormat(
+ "Error evaluating result expression: %s",
+ return_valobj_sp->GetError().AsCString());
+ else
+ result.AppendErrorWithFormat(
+ "Unknown error evaluating result expression.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
+ Error error;
+ ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
+ const bool broadcast = true;
+ error = thread_sp->ReturnFromFrame(frame_sp, return_valobj_sp, broadcast);
+ if (!error.Success()) {
+ result.AppendErrorWithFormat(
+ "Error returning from frame %d of thread %d: %s.", frame_idx,
+ thread_sp->GetIndexID(), error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- CommandOptions m_options;
-};
-OptionDefinition
-CommandObjectThreadReturn::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectThreadJump
//-------------------------------------------------------------------------
-class CommandObjectThreadJump : public CommandObjectParsed
-{
-public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- OptionParsingStarting ();
- }
-
- ~CommandOptions() override = default;
-
- void
- OptionParsingStarting () override
- {
- m_filenames.Clear();
- m_line_num = 0;
- m_line_offset = 0;
- m_load_addr = LLDB_INVALID_ADDRESS;
- m_force = false;
- }
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- bool success;
- const int short_option = m_getopt_table[option_idx].val;
- Error error;
-
- switch (short_option)
- {
- case 'f':
- m_filenames.AppendIfUnique (FileSpec(option_arg, false));
- if (m_filenames.GetSize() > 1)
- return Error("only one source file expected.");
- break;
- case 'l':
- m_line_num = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
- if (!success || m_line_num == 0)
- return Error("invalid line number: '%s'.", option_arg);
- break;
- case 'b':
- m_line_offset = StringConvert::ToSInt32 (option_arg, 0, 0, &success);
- if (!success)
- return Error("invalid line offset: '%s'.", option_arg);
- break;
- case 'a':
- {
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
- }
- break;
- case 'r':
- m_force = true;
- break;
- default:
- return Error("invalid short option character '%c'", short_option);
- }
- return error;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+static OptionDefinition g_thread_jump_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file to jump to." },
+ { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number to jump to." },
+ { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "Jumps by a relative line offset from the current line." },
+ { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Jumps to a specific address." },
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allows the PC to leave the current function." }
+ // clang-format on
+};
- FileSpecList m_filenames;
- uint32_t m_line_num;
- int32_t m_line_offset;
- lldb::addr_t m_load_addr;
- bool m_force;
-
- static OptionDefinition g_option_table[];
- };
-
- CommandObjectThreadJump (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
- "thread jump",
- "Sets the program counter to a new address.",
- "thread jump",
- eCommandRequiresFrame |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_options (interpreter)
- {
+class CommandObjectThreadJump : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_filenames.Clear();
+ m_line_num = 0;
+ m_line_offset = 0;
+ m_load_addr = LLDB_INVALID_ADDRESS;
+ m_force = false;
}
- ~CommandObjectThreadJump() override = default;
-
- Options *
- GetOptions() override
- {
- return &m_options;
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ const int short_option = m_getopt_table[option_idx].val;
+ Error error;
+
+ switch (short_option) {
+ case 'f':
+ m_filenames.AppendIfUnique(FileSpec(option_arg, false));
+ if (m_filenames.GetSize() > 1)
+ return Error("only one source file expected.");
+ break;
+ case 'l':
+ if (option_arg.getAsInteger(0, m_line_num))
+ return Error("invalid line number: '%s'.", option_arg.str().c_str());
+ break;
+ case 'b':
+ if (option_arg.getAsInteger(0, m_line_offset))
+ return Error("invalid line offset: '%s'.", option_arg.str().c_str());
+ break;
+ case 'a':
+ m_load_addr = Args::StringToAddress(execution_context, option_arg,
+ LLDB_INVALID_ADDRESS, &error);
+ break;
+ case 'r':
+ m_force = true;
+ break;
+ default:
+ return Error("invalid short option character '%c'", short_option);
+ }
+ return error;
}
-protected:
- bool DoExecute (Args& args, CommandReturnObject &result) override
- {
- RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
- StackFrame *frame = m_exe_ctx.GetFramePtr();
- Thread *thread = m_exe_ctx.GetThreadPtr();
- Target *target = m_exe_ctx.GetTargetPtr();
- const SymbolContext &sym_ctx = frame->GetSymbolContext (eSymbolContextLineEntry);
-
- if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
- {
- // Use this address directly.
- Address dest = Address(m_options.m_load_addr);
-
- lldb::addr_t callAddr = dest.GetCallableLoadAddress (target);
- if (callAddr == LLDB_INVALID_ADDRESS)
- {
- result.AppendErrorWithFormat ("Invalid destination address.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- if (!reg_ctx->SetPC (callAddr))
- {
- result.AppendErrorWithFormat ("Error changing PC value for thread %d.", thread->GetIndexID());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- // Pick either the absolute line, or work out a relative one.
- int32_t line = (int32_t)m_options.m_line_num;
- if (line == 0)
- line = sym_ctx.line_entry.line + m_options.m_line_offset;
-
- // Try the current file, but override if asked.
- FileSpec file = sym_ctx.line_entry.file;
- if (m_options.m_filenames.GetSize() == 1)
- file = m_options.m_filenames.GetFileSpecAtIndex(0);
-
- if (!file)
- {
- result.AppendErrorWithFormat ("No source file available for the current location.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- std::string warnings;
- Error err = thread->JumpToLine (file, line, m_options.m_force, &warnings);
-
- if (err.Fail())
- {
- result.SetError (err);
- return false;
- }
-
- if (!warnings.empty())
- result.AppendWarning (warnings.c_str());
- }
-
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_jump_options);
}
- CommandOptions m_options;
-};
+ FileSpecList m_filenames;
+ uint32_t m_line_num;
+ int32_t m_line_offset;
+ lldb::addr_t m_load_addr;
+ bool m_force;
+ };
-OptionDefinition
-CommandObjectThreadJump::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
- "Specifies the source file to jump to."},
+ CommandObjectThreadJump(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "thread jump",
+ "Sets the program counter to a new address.", "thread jump",
+ eCommandRequiresFrame | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options() {}
- { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum,
- "Specifies the line number to jump to."},
+ ~CommandObjectThreadJump() override = default;
- { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset,
- "Jumps by a relative line offset from the current line."},
+ Options *GetOptions() override { return &m_options; }
- { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression,
- "Jumps to a specific address."},
+protected:
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext();
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ Target *target = m_exe_ctx.GetTargetPtr();
+ const SymbolContext &sym_ctx =
+ frame->GetSymbolContext(eSymbolContextLineEntry);
+
+ if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) {
+ // Use this address directly.
+ Address dest = Address(m_options.m_load_addr);
+
+ lldb::addr_t callAddr = dest.GetCallableLoadAddress(target);
+ if (callAddr == LLDB_INVALID_ADDRESS) {
+ result.AppendErrorWithFormat("Invalid destination address.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (!reg_ctx->SetPC(callAddr)) {
+ result.AppendErrorWithFormat("Error changing PC value for thread %d.",
+ thread->GetIndexID());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ // Pick either the absolute line, or work out a relative one.
+ int32_t line = (int32_t)m_options.m_line_num;
+ if (line == 0)
+ line = sym_ctx.line_entry.line + m_options.m_line_offset;
+
+ // Try the current file, but override if asked.
+ FileSpec file = sym_ctx.line_entry.file;
+ if (m_options.m_filenames.GetSize() == 1)
+ file = m_options.m_filenames.GetFileSpecAtIndex(0);
+
+ if (!file) {
+ result.AppendErrorWithFormat(
+ "No source file available for the current location.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ std::string warnings;
+ Error err = thread->JumpToLine(file, line, m_options.m_force, &warnings);
+
+ if (err.Fail()) {
+ result.SetError(err);
+ return false;
+ }
+
+ if (!warnings.empty())
+ result.AppendWarning(warnings.c_str());
+ }
- { LLDB_OPT_SET_1|
- LLDB_OPT_SET_2|
- LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,"Allows the PC to leave the current function."},
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -1961,264 +1727,261 @@ CommandObjectThreadJump::CommandOptions::g_option_table[] =
// CommandObjectThreadPlanList
//-------------------------------------------------------------------------
-class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads
-{
-public:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'i':
- m_internal = true;
- break;
- case 'v':
- m_verbose = true;
- break;
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
- return error;
- }
+static OptionDefinition g_thread_plan_list_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans" },
+ { LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans" }
+ // clang-format on
+};
- void
- OptionParsingStarting () override
- {
- m_verbose = false;
- m_internal = false;
- }
+class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'i':
+ m_internal = true;
+ break;
+ case 'v':
+ m_verbose = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
+ }
- // Options table: Required for subclasses of Options.
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_verbose = false;
+ m_internal = false;
+ }
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_plan_list_options);
+ }
- // Instance variables to hold the values for command options.
- bool m_verbose;
- bool m_internal;
- };
+ // Instance variables to hold the values for command options.
+ bool m_verbose;
+ bool m_internal;
+ };
- CommandObjectThreadPlanList(CommandInterpreter &interpreter)
- : CommandObjectIterateOverThreads(
- interpreter, "thread plan list",
- "Show thread plans for one or more threads. If no threads are specified, show the "
- "current thread. Use the thread-index \"all\" to see all threads.",
- nullptr, eCommandRequiresProcess | eCommandRequiresThread | eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
- m_options(interpreter)
- {
- }
+ CommandObjectThreadPlanList(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread plan list",
+ "Show thread plans for one or more threads. If no threads are "
+ "specified, show the "
+ "current thread. Use the thread-index \"all\" to see all threads.",
+ nullptr,
+ eCommandRequiresProcess | eCommandRequiresThread |
+ eCommandTryTargetAPILock | eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
+ m_options() {}
- ~CommandObjectThreadPlanList() override = default;
+ ~CommandObjectThreadPlanList() override = default;
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ Options *GetOptions() override { return &m_options; }
protected:
- bool
- HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override
- {
- ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
- if (!thread_sp)
- {
- result.AppendErrorWithFormat ("thread no longer exists: 0x%" PRIx64 "\n", tid);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
+ ThreadSP thread_sp =
+ m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+ if (!thread_sp) {
+ result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n",
+ tid);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- Thread *thread = thread_sp.get();
+ Thread *thread = thread_sp.get();
- Stream &strm = result.GetOutputStream();
- DescriptionLevel desc_level = eDescriptionLevelFull;
- if (m_options.m_verbose)
- desc_level = eDescriptionLevelVerbose;
+ Stream &strm = result.GetOutputStream();
+ DescriptionLevel desc_level = eDescriptionLevelFull;
+ if (m_options.m_verbose)
+ desc_level = eDescriptionLevelVerbose;
- thread->DumpThreadPlans (&strm, desc_level, m_options.m_internal, true);
- return true;
- }
-
- CommandOptions m_options;
-};
+ thread->DumpThreadPlans(&strm, desc_level, m_options.m_internal, true);
+ return true;
+ }
-OptionDefinition
-CommandObjectThreadPlanList::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans"},
-{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans"},
-{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ CommandOptions m_options;
};
-class CommandObjectThreadPlanDiscard : public CommandObjectParsed
-{
+class CommandObjectThreadPlanDiscard : public CommandObjectParsed {
public:
- CommandObjectThreadPlanDiscard(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "thread plan discard",
- "Discards thread plans up to and including the specified index (see 'thread plan list'.) "
- "Only user visible plans can be discarded.",
- nullptr, eCommandRequiresProcess | eCommandRequiresThread | eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
- {
- CommandArgumentEntry arg;
- CommandArgumentData plan_index_arg;
-
- // Define the first (and only) variant of this arg.
- plan_index_arg.arg_type = eArgTypeUnsignedInteger;
- plan_index_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (plan_index_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
+ CommandObjectThreadPlanDiscard(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "thread plan discard",
+ "Discards thread plans up to and including the "
+ "specified index (see 'thread plan list'.) "
+ "Only user visible plans can be discarded.",
+ nullptr,
+ eCommandRequiresProcess | eCommandRequiresThread |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused) {
+ CommandArgumentEntry arg;
+ CommandArgumentData plan_index_arg;
+
+ // Define the first (and only) variant of this arg.
+ plan_index_arg.arg_type = eArgTypeUnsignedInteger;
+ plan_index_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(plan_index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectThreadPlanDiscard() override = default;
+
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ if (args.GetArgumentCount() != 1) {
+ result.AppendErrorWithFormat("Too many arguments, expected one - the "
+ "thread plan index - but got %zu.",
+ args.GetArgumentCount());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- ~CommandObjectThreadPlanDiscard() override = default;
-
- bool
- DoExecute (Args& args, CommandReturnObject &result) override
- {
- Thread *thread = m_exe_ctx.GetThreadPtr();
- if (args.GetArgumentCount() != 1)
- {
- result.AppendErrorWithFormat("Too many arguments, expected one - the thread plan index - but got %zu.",
- args.GetArgumentCount());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- bool success;
- uint32_t thread_plan_idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
- if (!success)
- {
- result.AppendErrorWithFormat("Invalid thread index: \"%s\" - should be unsigned int.",
- args.GetArgumentAtIndex(0));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool success;
+ uint32_t thread_plan_idx =
+ StringConvert::ToUInt32(args.GetArgumentAtIndex(0), 0, 0, &success);
+ if (!success) {
+ result.AppendErrorWithFormat(
+ "Invalid thread index: \"%s\" - should be unsigned int.",
+ args.GetArgumentAtIndex(0));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (thread_plan_idx == 0)
- {
- result.AppendErrorWithFormat("You wouldn't really want me to discard the base thread plan.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (thread_plan_idx == 0) {
+ result.AppendErrorWithFormat(
+ "You wouldn't really want me to discard the base thread plan.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx))
- {
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return true;
- }
- else
- {
- result.AppendErrorWithFormat("Could not find User thread plan with index %s.",
- args.GetArgumentAtIndex(0));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (thread->DiscardUserThreadPlansUpToIndex(thread_plan_idx)) {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
+ } else {
+ result.AppendErrorWithFormat(
+ "Could not find User thread plan with index %s.",
+ args.GetArgumentAtIndex(0));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ }
};
//-------------------------------------------------------------------------
// CommandObjectMultiwordThreadPlan
//-------------------------------------------------------------------------
-class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword
-{
+class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword {
public:
- CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "plan", "Commands for managing thread plans that control execution.",
- "thread plan <subcommand> [<subcommand objects]")
- {
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter)));
- LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter)));
- }
+ CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "plan",
+ "Commands for managing thread plans that control execution.",
+ "thread plan <subcommand> [<subcommand objects]") {
+ LoadSubCommand(
+ "list", CommandObjectSP(new CommandObjectThreadPlanList(interpreter)));
+ LoadSubCommand(
+ "discard",
+ CommandObjectSP(new CommandObjectThreadPlanDiscard(interpreter)));
+ }
- ~CommandObjectMultiwordThreadPlan() override = default;
+ ~CommandObjectMultiwordThreadPlan() override = default;
};
//-------------------------------------------------------------------------
// CommandObjectMultiwordThread
//-------------------------------------------------------------------------
-CommandObjectMultiwordThread::CommandObjectMultiwordThread(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "thread",
- "Commands for operating on one or more threads in the current process.",
- "thread <subcommand> [<subcommand-options>]")
-{
- LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter)));
- LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadList (interpreter)));
- LoadSubCommand ("return", CommandObjectSP (new CommandObjectThreadReturn (interpreter)));
- LoadSubCommand ("jump", CommandObjectSP (new CommandObjectThreadJump (interpreter)));
- LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter)));
- LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter)));
- LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter)));
- LoadSubCommand("step-in",
- CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
- interpreter, "thread step-in",
- "Source level single step, stepping into calls. Defaults to current thread unless specified.",
- nullptr, eStepTypeInto, eStepScopeSource)));
-
- LoadSubCommand("step-out",
- CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
- interpreter, "thread step-out", "Finish executing the current stack frame and stop after "
- "returning. Defaults to current thread unless specified.",
- nullptr, eStepTypeOut, eStepScopeSource)));
-
- LoadSubCommand("step-over",
- CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
- interpreter, "thread step-over",
- "Source level single step, stepping over calls. Defaults to current thread unless specified.",
- nullptr, eStepTypeOver, eStepScopeSource)));
-
- LoadSubCommand(
- "step-inst",
- CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
- interpreter, "thread step-inst",
- "Instruction level single step, stepping into calls. Defaults to current thread unless specified.",
- nullptr, eStepTypeTrace, eStepScopeInstruction)));
-
- LoadSubCommand(
- "step-inst-over",
- CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
- interpreter, "thread step-inst-over",
- "Instruction level single step, stepping over calls. Defaults to current thread unless specified.",
- nullptr, eStepTypeTraceOver, eStepScopeInstruction)));
-
- LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope (
- interpreter,
- "thread step-scripted",
- "Step as instructed by the script class passed in the -C option.",
- nullptr,
- eStepTypeScripted,
- eStepScopeSource)));
-
- LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter)));
+CommandObjectMultiwordThread::CommandObjectMultiwordThread(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "thread", "Commands for operating on "
+ "one or more threads in "
+ "the current process.",
+ "thread <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("backtrace", CommandObjectSP(new CommandObjectThreadBacktrace(
+ interpreter)));
+ LoadSubCommand("continue",
+ CommandObjectSP(new CommandObjectThreadContinue(interpreter)));
+ LoadSubCommand("list",
+ CommandObjectSP(new CommandObjectThreadList(interpreter)));
+ LoadSubCommand("return",
+ CommandObjectSP(new CommandObjectThreadReturn(interpreter)));
+ LoadSubCommand("jump",
+ CommandObjectSP(new CommandObjectThreadJump(interpreter)));
+ LoadSubCommand("select",
+ CommandObjectSP(new CommandObjectThreadSelect(interpreter)));
+ LoadSubCommand("until",
+ CommandObjectSP(new CommandObjectThreadUntil(interpreter)));
+ LoadSubCommand("info",
+ CommandObjectSP(new CommandObjectThreadInfo(interpreter)));
+ LoadSubCommand("step-in",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-in",
+ "Source level single step, stepping into calls. Defaults "
+ "to current thread unless specified.",
+ nullptr, eStepTypeInto, eStepScopeSource)));
+
+ LoadSubCommand("step-out",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-out",
+ "Finish executing the current stack frame and stop after "
+ "returning. Defaults to current thread unless specified.",
+ nullptr, eStepTypeOut, eStepScopeSource)));
+
+ LoadSubCommand("step-over",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-over",
+ "Source level single step, stepping over calls. Defaults "
+ "to current thread unless specified.",
+ nullptr, eStepTypeOver, eStepScopeSource)));
+
+ LoadSubCommand("step-inst",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-inst",
+ "Instruction level single step, stepping into calls. "
+ "Defaults to current thread unless specified.",
+ nullptr, eStepTypeTrace, eStepScopeInstruction)));
+
+ LoadSubCommand("step-inst-over",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-inst-over",
+ "Instruction level single step, stepping over calls. "
+ "Defaults to current thread unless specified.",
+ nullptr, eStepTypeTraceOver, eStepScopeInstruction)));
+
+ LoadSubCommand(
+ "step-scripted",
+ CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope(
+ interpreter, "thread step-scripted",
+ "Step as instructed by the script class passed in the -C option.",
+ nullptr, eStepTypeScripted, eStepScopeSource)));
+
+ LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan(
+ interpreter)));
}
CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;
diff --git a/source/Commands/CommandObjectThread.h b/source/Commands/CommandObjectThread.h
index 90f8236b4428..589031e0a038 100644
--- a/source/Commands/CommandObjectThread.h
+++ b/source/Commands/CommandObjectThread.h
@@ -18,13 +18,11 @@
namespace lldb_private {
-class CommandObjectMultiwordThread : public CommandObjectMultiword
-{
+class CommandObjectMultiwordThread : public CommandObjectMultiword {
public:
+ CommandObjectMultiwordThread(CommandInterpreter &interpreter);
- CommandObjectMultiwordThread (CommandInterpreter &interpreter);
-
- ~CommandObjectMultiwordThread() override;
+ ~CommandObjectMultiwordThread() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp
index 6f1199de69de..621ef581a978 100644
--- a/source/Commands/CommandObjectType.cpp
+++ b/source/Commands/CommandObjectType.cpp
@@ -15,9 +15,6 @@
#include <cctype>
#include <functional>
-// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
-
// Project includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Debugger.h"
@@ -29,11 +26,11 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Interpreter/OptionValueLanguage.h"
#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
@@ -42,698 +39,600 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadList.h"
+// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
+
using namespace lldb;
using namespace lldb_private;
-class ScriptAddOptions
-{
+class ScriptAddOptions {
public:
- TypeSummaryImpl::Flags m_flags;
- StringList m_target_types;
- bool m_regex;
- ConstString m_name;
- std::string m_category;
-
- ScriptAddOptions(const TypeSummaryImpl::Flags& flags,
- bool regx,
- const ConstString& name,
- std::string catg) :
- m_flags(flags),
- m_regex(regx),
- m_name(name),
- m_category(catg)
- {
- }
-
- typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
+ TypeSummaryImpl::Flags m_flags;
+ StringList m_target_types;
+ bool m_regex;
+ ConstString m_name;
+ std::string m_category;
+
+ ScriptAddOptions(const TypeSummaryImpl::Flags &flags, bool regx,
+ const ConstString &name, std::string catg)
+ : m_flags(flags), m_regex(regx), m_name(name), m_category(catg) {}
+
+ typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
};
-class SynthAddOptions
-{
+class SynthAddOptions {
public:
- bool m_skip_pointers;
- bool m_skip_references;
- bool m_cascade;
- bool m_regex;
- StringList m_target_types;
- std::string m_category;
-
- SynthAddOptions(bool sptr,
- bool sref,
- bool casc,
- bool regx,
- std::string catg) :
- m_skip_pointers(sptr),
- m_skip_references(sref),
- m_cascade(casc),
- m_regex(regx),
- m_target_types(),
- m_category(catg)
- {
- }
-
- typedef std::shared_ptr<SynthAddOptions> SharedPointer;
+ bool m_skip_pointers;
+ bool m_skip_references;
+ bool m_cascade;
+ bool m_regex;
+ StringList m_target_types;
+ std::string m_category;
+
+ SynthAddOptions(bool sptr, bool sref, bool casc, bool regx, std::string catg)
+ : m_skip_pointers(sptr), m_skip_references(sref), m_cascade(casc),
+ m_regex(regx), m_target_types(), m_category(catg) {}
+
+ typedef std::shared_ptr<SynthAddOptions> SharedPointer;
};
-static bool
-WarnOnPotentialUnquotedUnsignedType (Args& command, CommandReturnObject &result)
-{
- for (unsigned idx = 0; idx < command.GetArgumentCount(); idx++)
- {
- const char* arg = command.GetArgumentAtIndex(idx);
- if (idx+1 < command.GetArgumentCount())
- {
- if (arg && 0 == strcmp(arg,"unsigned"))
- {
- const char* next = command.GetArgumentAtIndex(idx+1);
- if (next &&
- (0 == strcmp(next, "int") ||
- 0 == strcmp(next, "short") ||
- 0 == strcmp(next, "char") ||
- 0 == strcmp(next, "long")))
- {
- result.AppendWarningWithFormat("%s %s being treated as two types. if you meant the combined type name use quotes, as in \"%s %s\"\n",
- arg,next,arg,next);
- return true;
- }
- }
- }
- }
+static bool WarnOnPotentialUnquotedUnsignedType(Args &command,
+ CommandReturnObject &result) {
+ if (command.empty())
return false;
+
+ for (auto entry : llvm::enumerate(command.entries().drop_back())) {
+ if (entry.Value.ref != "unsigned")
+ continue;
+ auto next = command.entries()[entry.Index + 1].ref;
+ if (next == "int" || next == "short" || next == "char" || next == "long") {
+ result.AppendWarningWithFormat(
+ "unsigned %s being treated as two types. if you meant the combined "
+ "type "
+ "name use quotes, as in \"unsigned %s\"\n",
+ next.str().c_str(), next.str().c_str());
+ return true;
+ }
+ }
+ return false;
}
-class CommandObjectTypeSummaryAdd :
- public CommandObjectParsed,
- public IOHandlerDelegateMultiline
-{
+static OptionDefinition g_type_summary_add_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one." },
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains." },
+ { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type." },
+ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." },
+ { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects." },
+ { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions." },
+ { LLDB_OPT_SET_1, true, "inline-children", 'c', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If true, inline all child values into summary string." },
+ { LLDB_OPT_SET_1, false, "omit-names", 'O', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If true, omit value names in the summary display." },
+ { LLDB_OPT_SET_2, true, "summary-string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSummaryString, "Summary string used to display text and object contents." },
+ { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command." },
+ { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type." },
+ { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Input Python code to use for this type manually." },
+ { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines." },
+ { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "hide-empty", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Do not expand aggregate data types with no children." },
+ { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "A name for this summary string." }
+ // clang-format on
+};
+
+class CommandObjectTypeSummaryAdd : public CommandObjectParsed,
+ public IOHandlerDelegateMultiline {
private:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions(CommandInterpreter &interpreter) : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_type_summary_add_options);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ TypeSummaryImpl::Flags m_flags;
+ bool m_regex;
+ std::string m_format_string;
+ ConstString m_name;
+ std::string m_python_script;
+ std::string m_python_function;
+ bool m_is_add_script;
+ std::string m_category;
+ };
+
+ CommandOptions m_options;
+
+ Options *GetOptions() override { return &m_options; }
+
+ bool Execute_ScriptSummary(Args &command, CommandReturnObject &result);
+
+ bool Execute_StringSummary(Args &command, CommandReturnObject &result);
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override;
-
- void
- OptionParsingStarting () override;
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- TypeSummaryImpl::Flags m_flags;
- bool m_regex;
- std::string m_format_string;
- ConstString m_name;
- std::string m_python_script;
- std::string m_python_function;
- bool m_is_add_script;
- std::string m_category;
- };
-
- CommandOptions m_options;
-
- Options *
- GetOptions () override
- {
- return &m_options;
- }
-
- bool
- Execute_ScriptSummary (Args& command, CommandReturnObject &result);
-
- bool
- Execute_StringSummary (Args& command, CommandReturnObject &result);
-
public:
- enum SummaryFormatType
- {
- eRegularSummary,
- eRegexSummary,
- eNamedSummary
- };
-
- CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter);
+ enum SummaryFormatType { eRegularSummary, eRegexSummary, eNamedSummary };
- ~CommandObjectTypeSummaryAdd() override = default;
+ CommandObjectTypeSummaryAdd(CommandInterpreter &interpreter);
- void
- IOHandlerActivated (IOHandler &io_handler) override
- {
- static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
+ ~CommandObjectTypeSummaryAdd() override = default;
+
+ void IOHandlerActivated(IOHandler &io_handler) override {
+ static const char *g_summary_addreader_instructions =
+ "Enter your Python command(s). Type 'DONE' to end.\n"
"def function (valobj,internal_dict):\n"
- " \"\"\"valobj: an SBValue which you want to provide a summary for\n"
+ " \"\"\"valobj: an SBValue which you want to provide a summary "
+ "for\n"
" internal_dict: an LLDB support object not to be used\"\"\"\n";
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- if (output_sp)
- {
- output_sp->PutCString(g_summary_addreader_instructions);
- output_sp->Flush();
- }
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp) {
+ output_sp->PutCString(g_summary_addreader_instructions);
+ output_sp->Flush();
}
+ }
+
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) override {
+ StreamFileSP error_sp = io_handler.GetErrorStreamFile();
- void
- IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
- {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
-
#ifndef LLDB_DISABLE_PYTHON
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (interpreter)
- {
- StringList lines;
- lines.SplitIntoLines(data);
- if (lines.GetSize() > 0)
- {
- ScriptAddOptions *options_ptr = ((ScriptAddOptions*)io_handler.GetUserData());
- if (options_ptr)
- {
- ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
-
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (interpreter)
- {
- std::string funct_name_str;
- if (interpreter->GenerateTypeScriptFunction (lines, funct_name_str))
- {
- if (funct_name_str.empty())
- {
- error_sp->Printf ("unable to obtain a valid function name from the script interpreter.\n");
- error_sp->Flush();
- }
- else
- {
- // now I have a valid function name, let's add this as script for every type in the list
-
- TypeSummaryImplSP script_format;
- script_format.reset(new ScriptSummaryFormat(options->m_flags,
- funct_name_str.c_str(),
- lines.CopyList(" ").c_str()));
-
- Error error;
-
- for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
- {
- const char *type_name = options->m_target_types.GetStringAtIndex(i);
- CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
- script_format,
- (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
- options->m_category,
- &error);
- if (error.Fail())
- {
- error_sp->Printf ("error: %s", error.AsCString());
- error_sp->Flush();
- }
- }
-
- if (options->m_name)
- {
- CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
- script_format,
- CommandObjectTypeSummaryAdd::eNamedSummary,
- options->m_category,
- &error);
- if (error.Fail())
- {
- CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
- script_format,
- CommandObjectTypeSummaryAdd::eNamedSummary,
- options->m_category,
- &error);
- if (error.Fail())
- {
- error_sp->Printf ("error: %s", error.AsCString());
- error_sp->Flush();
- }
- }
- else
- {
- error_sp->Printf ("error: %s", error.AsCString());
- error_sp->Flush();
- }
- }
- else
- {
- if (error.AsCString())
- {
- error_sp->Printf ("error: %s", error.AsCString());
- error_sp->Flush();
- }
- }
- }
- }
- else
- {
- error_sp->Printf ("error: unable to generate a function.\n");
- error_sp->Flush();
- }
- }
- else
- {
- error_sp->Printf ("error: no script interpreter.\n");
- error_sp->Flush();
- }
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (interpreter) {
+ StringList lines;
+ lines.SplitIntoLines(data);
+ if (lines.GetSize() > 0) {
+ ScriptAddOptions *options_ptr =
+ ((ScriptAddOptions *)io_handler.GetUserData());
+ if (options_ptr) {
+ ScriptAddOptions::SharedPointer options(
+ options_ptr); // this will ensure that we get rid of the pointer
+ // when going out of scope
+
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (interpreter) {
+ std::string funct_name_str;
+ if (interpreter->GenerateTypeScriptFunction(lines,
+ funct_name_str)) {
+ if (funct_name_str.empty()) {
+ error_sp->Printf("unable to obtain a valid function name from "
+ "the script interpreter.\n");
+ error_sp->Flush();
+ } else {
+ // now I have a valid function name, let's add this as script
+ // for every type in the list
+
+ TypeSummaryImplSP script_format;
+ script_format.reset(new ScriptSummaryFormat(
+ options->m_flags, funct_name_str.c_str(),
+ lines.CopyList(" ").c_str()));
+
+ Error error;
+
+ for (size_t i = 0; i < options->m_target_types.GetSize(); i++) {
+ const char *type_name =
+ options->m_target_types.GetStringAtIndex(i);
+ CommandObjectTypeSummaryAdd::AddSummary(
+ ConstString(type_name), script_format,
+ (options->m_regex
+ ? CommandObjectTypeSummaryAdd::eRegexSummary
+ : CommandObjectTypeSummaryAdd::eRegularSummary),
+ options->m_category, &error);
+ if (error.Fail()) {
+ error_sp->Printf("error: %s", error.AsCString());
+ error_sp->Flush();
+ }
}
- else
- {
- error_sp->Printf ("error: internal synchronization information missing or invalid.\n");
+
+ if (options->m_name) {
+ CommandObjectTypeSummaryAdd::AddSummary(
+ options->m_name, script_format,
+ CommandObjectTypeSummaryAdd::eNamedSummary,
+ options->m_category, &error);
+ if (error.Fail()) {
+ CommandObjectTypeSummaryAdd::AddSummary(
+ options->m_name, script_format,
+ CommandObjectTypeSummaryAdd::eNamedSummary,
+ options->m_category, &error);
+ if (error.Fail()) {
+ error_sp->Printf("error: %s", error.AsCString());
+ error_sp->Flush();
+ }
+ } else {
+ error_sp->Printf("error: %s", error.AsCString());
+ error_sp->Flush();
+ }
+ } else {
+ if (error.AsCString()) {
+ error_sp->Printf("error: %s", error.AsCString());
error_sp->Flush();
+ }
}
+ }
+ } else {
+ error_sp->Printf("error: unable to generate a function.\n");
+ error_sp->Flush();
}
- else
- {
- error_sp->Printf ("error: empty function, didn't add python command.\n");
- error_sp->Flush();
- }
- }
- else
- {
- error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
+ } else {
+ error_sp->Printf("error: no script interpreter.\n");
error_sp->Flush();
- }
-#endif // LLDB_DISABLE_PYTHON
- io_handler.SetIsDone(true);
+ }
+ } else {
+ error_sp->Printf("error: internal synchronization information "
+ "missing or invalid.\n");
+ error_sp->Flush();
+ }
+ } else {
+ error_sp->Printf("error: empty function, didn't add python command.\n");
+ error_sp->Flush();
+ }
+ } else {
+ error_sp->Printf(
+ "error: script interpreter missing, didn't add python command.\n");
+ error_sp->Flush();
}
-
- static bool
- AddSummary(ConstString type_name,
- lldb::TypeSummaryImplSP entry,
- SummaryFormatType type,
- std::string category,
- Error* error = nullptr);
+#endif // LLDB_DISABLE_PYTHON
+ io_handler.SetIsDone(true);
+ }
+
+ static bool AddSummary(ConstString type_name, lldb::TypeSummaryImplSP entry,
+ SummaryFormatType type, std::string category,
+ Error *error = nullptr);
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override;
+ bool DoExecute(Args &command, CommandReturnObject &result) override;
};
-static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
-"You must define a Python class with these methods:\n"
-" def __init__(self, valobj, dict):\n"
-" def num_children(self):\n"
-" def get_child_at_index(self, index):\n"
-" def get_child_index(self, name):\n"
-" def update(self):\n"
-" '''Optional'''\n"
-"class synthProvider:\n";
-
-class CommandObjectTypeSynthAdd :
- public CommandObjectParsed,
- public IOHandlerDelegateMultiline
-{
+static const char *g_synth_addreader_instructions =
+ "Enter your Python command(s). Type 'DONE' to end.\n"
+ "You must define a Python class with these methods:\n"
+ " def __init__(self, valobj, dict):\n"
+ " def num_children(self):\n"
+ " def get_child_at_index(self, index):\n"
+ " def get_child_index(self, name):\n"
+ " def update(self):\n"
+ " '''Optional'''\n"
+ "class synthProvider:\n";
+
+static OptionDefinition g_type_synth_add_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains." },
+ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." },
+ { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects." },
+ { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one." },
+ { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children." },
+ { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children." },
+ { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions." }
+ // clang-format on
+};
+
+class CommandObjectTypeSynthAdd : public CommandObjectParsed,
+ public IOHandlerDelegateMultiline {
private:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ bool success;
+
+ switch (short_option) {
+ case 'C':
+ m_cascade = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid value for cascade: %s",
+ option_arg.str().c_str());
+ break;
+ case 'P':
+ handwrite_python = true;
+ break;
+ case 'l':
+ m_class_name = std::string(option_arg);
+ is_class_based = true;
+ break;
+ case 'p':
+ m_skip_pointers = true;
+ break;
+ case 'r':
+ m_skip_references = true;
+ break;
+ case 'w':
+ m_category = std::string(option_arg);
+ break;
+ case 'x':
+ m_regex = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_cascade = true;
+ m_class_name = "";
+ m_skip_pointers = false;
+ m_skip_references = false;
+ m_category = "default";
+ is_class_based = false;
+ handwrite_python = false;
+ m_regex = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_type_synth_add_options);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ bool m_cascade;
+ bool m_skip_references;
+ bool m_skip_pointers;
+ std::string m_class_name;
+ bool m_input_python;
+ std::string m_category;
+ bool is_class_based;
+ bool handwrite_python;
+ bool m_regex;
+ };
+
+ CommandOptions m_options;
+
+ Options *GetOptions() override { return &m_options; }
+
+ bool Execute_HandwritePython(Args &command, CommandReturnObject &result);
+
+ bool Execute_PythonClass(Args &command, CommandReturnObject &result);
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
- bool success;
-
- switch (short_option)
- {
- case 'C':
- m_cascade = Args::StringToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
- break;
- case 'P':
- handwrite_python = true;
- break;
- case 'l':
- m_class_name = std::string(option_arg);
- is_class_based = true;
- break;
- case 'p':
- m_skip_pointers = true;
- break;
- case 'r':
- m_skip_references = true;
- break;
- case 'w':
- m_category = std::string(option_arg);
- break;
- case 'x':
- m_regex = true;
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_cascade = true;
- m_class_name = "";
- m_skip_pointers = false;
- m_skip_references = false;
- m_category = "default";
- is_class_based = false;
- handwrite_python = false;
- m_regex = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool m_cascade;
- bool m_skip_references;
- bool m_skip_pointers;
- std::string m_class_name;
- bool m_input_python;
- std::string m_category;
- bool is_class_based;
- bool handwrite_python;
- bool m_regex;
- };
-
- CommandOptions m_options;
-
- Options *
- GetOptions () override
- {
- return &m_options;
- }
-
- bool
- Execute_HandwritePython (Args& command, CommandReturnObject &result);
-
- bool
- Execute_PythonClass (Args& command, CommandReturnObject &result);
-
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- WarnOnPotentialUnquotedUnsignedType(command, result);
-
- if (m_options.handwrite_python)
- return Execute_HandwritePython(command, result);
- else if (m_options.is_class_based)
- return Execute_PythonClass(command, result);
- else
- {
- result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ WarnOnPotentialUnquotedUnsignedType(command, result);
+
+ if (m_options.handwrite_python)
+ return Execute_HandwritePython(command, result);
+ else if (m_options.is_class_based)
+ return Execute_PythonClass(command, result);
+ else {
+ result.AppendError("must either provide a children list, a Python class "
+ "name, or use -P and type a Python class "
+ "line-by-line");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- void
- IOHandlerActivated (IOHandler &io_handler) override
- {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- if (output_sp)
- {
- output_sp->PutCString(g_synth_addreader_instructions);
- output_sp->Flush();
- }
+ }
+
+ void IOHandlerActivated(IOHandler &io_handler) override {
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp) {
+ output_sp->PutCString(g_synth_addreader_instructions);
+ output_sp->Flush();
}
+ }
+
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) override {
+ StreamFileSP error_sp = io_handler.GetErrorStreamFile();
- void
- IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
- {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
-
#ifndef LLDB_DISABLE_PYTHON
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (interpreter)
- {
- StringList lines;
- lines.SplitIntoLines(data);
- if (lines.GetSize() > 0)
- {
- SynthAddOptions *options_ptr = ((SynthAddOptions*)io_handler.GetUserData());
- if (options_ptr)
- {
- SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
-
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (interpreter)
- {
- std::string class_name_str;
- if (interpreter->GenerateTypeSynthClass (lines, class_name_str))
- {
- if (class_name_str.empty())
- {
- error_sp->Printf ("error: unable to obtain a proper name for the class.\n");
- error_sp->Flush();
- }
- else
- {
- // everything should be fine now, let's add the synth provider class
-
- SyntheticChildrenSP synth_provider;
- synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
- SetSkipPointers(options->m_skip_pointers).
- SetSkipReferences(options->m_skip_references),
- class_name_str.c_str()));
-
-
- lldb::TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category);
-
- Error error;
-
- for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
- {
- const char *type_name = options->m_target_types.GetStringAtIndex(i);
- ConstString const_type_name(type_name);
- if (const_type_name)
- {
- if (!CommandObjectTypeSynthAdd::AddSynth(const_type_name,
- synth_provider,
- options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
- options->m_category,
- &error))
- {
- error_sp->Printf("error: %s\n", error.AsCString());
- error_sp->Flush();
- break;
- }
- }
- else
- {
- error_sp->Printf ("error: invalid type name.\n");
- error_sp->Flush();
- break;
- }
- }
- }
- }
- else
- {
- error_sp->Printf ("error: unable to generate a class.\n");
- error_sp->Flush();
- }
- }
- else
- {
- error_sp->Printf ("error: no script interpreter.\n");
- error_sp->Flush();
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (interpreter) {
+ StringList lines;
+ lines.SplitIntoLines(data);
+ if (lines.GetSize() > 0) {
+ SynthAddOptions *options_ptr =
+ ((SynthAddOptions *)io_handler.GetUserData());
+ if (options_ptr) {
+ SynthAddOptions::SharedPointer options(
+ options_ptr); // this will ensure that we get rid of the pointer
+ // when going out of scope
+
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (interpreter) {
+ std::string class_name_str;
+ if (interpreter->GenerateTypeSynthClass(lines, class_name_str)) {
+ if (class_name_str.empty()) {
+ error_sp->Printf(
+ "error: unable to obtain a proper name for the class.\n");
+ error_sp->Flush();
+ } else {
+ // everything should be fine now, let's add the synth provider
+ // class
+
+ SyntheticChildrenSP synth_provider;
+ synth_provider.reset(new ScriptedSyntheticChildren(
+ SyntheticChildren::Flags()
+ .SetCascades(options->m_cascade)
+ .SetSkipPointers(options->m_skip_pointers)
+ .SetSkipReferences(options->m_skip_references),
+ class_name_str.c_str()));
+
+ lldb::TypeCategoryImplSP category;
+ DataVisualization::Categories::GetCategory(
+ ConstString(options->m_category.c_str()), category);
+
+ Error error;
+
+ for (size_t i = 0; i < options->m_target_types.GetSize(); i++) {
+ const char *type_name =
+ options->m_target_types.GetStringAtIndex(i);
+ ConstString const_type_name(type_name);
+ if (const_type_name) {
+ if (!CommandObjectTypeSynthAdd::AddSynth(
+ const_type_name, synth_provider,
+ options->m_regex
+ ? CommandObjectTypeSynthAdd::eRegexSynth
+ : CommandObjectTypeSynthAdd::eRegularSynth,
+ options->m_category, &error)) {
+ error_sp->Printf("error: %s\n", error.AsCString());
+ error_sp->Flush();
+ break;
}
- }
- else
- {
- error_sp->Printf ("error: internal synchronization data missing.\n");
+ } else {
+ error_sp->Printf("error: invalid type name.\n");
error_sp->Flush();
+ break;
+ }
}
+ }
+ } else {
+ error_sp->Printf("error: unable to generate a class.\n");
+ error_sp->Flush();
}
- else
- {
- error_sp->Printf ("error: empty function, didn't add python command.\n");
- error_sp->Flush();
- }
- }
- else
- {
- error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
+ } else {
+ error_sp->Printf("error: no script interpreter.\n");
error_sp->Flush();
+ }
+ } else {
+ error_sp->Printf("error: internal synchronization data missing.\n");
+ error_sp->Flush();
}
-
-#endif // LLDB_DISABLE_PYTHON
- io_handler.SetIsDone(true);
+ } else {
+ error_sp->Printf("error: empty function, didn't add python command.\n");
+ error_sp->Flush();
+ }
+ } else {
+ error_sp->Printf(
+ "error: script interpreter missing, didn't add python command.\n");
+ error_sp->Flush();
}
+#endif // LLDB_DISABLE_PYTHON
+ io_handler.SetIsDone(true);
+ }
+
public:
- enum SynthFormatType
- {
- eRegularSynth,
- eRegexSynth
- };
-
- CommandObjectTypeSynthAdd (CommandInterpreter &interpreter);
+ enum SynthFormatType { eRegularSynth, eRegexSynth };
+
+ CommandObjectTypeSynthAdd(CommandInterpreter &interpreter);
- ~CommandObjectTypeSynthAdd() override = default;
+ ~CommandObjectTypeSynthAdd() override = default;
- static bool
- AddSynth(ConstString type_name,
- lldb::SyntheticChildrenSP entry,
- SynthFormatType type,
- std::string category_name,
- Error* error);
+ static bool AddSynth(ConstString type_name, lldb::SyntheticChildrenSP entry,
+ SynthFormatType type, std::string category_name,
+ Error *error);
};
//-------------------------------------------------------------------------
// CommandObjectTypeFormatAdd
//-------------------------------------------------------------------------
-class CommandObjectTypeFormatAdd : public CommandObjectParsed
-{
+static OptionDefinition g_type_format_add_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one." },
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains." },
+ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." },
+ { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects." },
+ { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions." },
+ { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Format variables as if they were of this type." }
+ // clang-format on
+};
+
+class CommandObjectTypeFormatAdd : public CommandObjectParsed {
private:
- class CommandOptions : public OptionGroup
- {
- public:
- CommandOptions () :
- OptionGroup()
- {
- }
+ class CommandOptions : public OptionGroup {
+ public:
+ CommandOptions() : OptionGroup() {}
+
+ ~CommandOptions() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_type_format_add_options);
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_cascade = true;
+ m_skip_pointers = false;
+ m_skip_references = false;
+ m_regex = false;
+ m_category.assign("default");
+ m_custom_type_name.clear();
+ }
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option =
+ g_type_format_add_options[option_idx].short_option;
+ bool success;
+
+ switch (short_option) {
+ case 'C':
+ m_cascade = Args::StringToBoolean(option_value, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid value for cascade: %s",
+ option_value.str().c_str());
+ break;
+ case 'p':
+ m_skip_pointers = true;
+ break;
+ case 'w':
+ m_category.assign(option_value);
+ break;
+ case 'r':
+ m_skip_references = true;
+ break;
+ case 'x':
+ m_regex = true;
+ break;
+ case 't':
+ m_custom_type_name.assign(option_value);
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ // Instance variables to hold the values for command options.
- ~CommandOptions() override = default;
+ bool m_cascade;
+ bool m_skip_references;
+ bool m_skip_pointers;
+ bool m_regex;
+ std::string m_category;
+ std::string m_custom_type_name;
+ };
- uint32_t
- GetNumDefinitions () override;
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- void
- OptionParsingStarting (CommandInterpreter &interpreter) override
- {
- m_cascade = true;
- m_skip_pointers = false;
- m_skip_references = false;
- m_regex = false;
- m_category.assign("default");
- m_custom_type_name.clear();
- }
+ OptionGroupOptions m_option_group;
+ OptionGroupFormat m_format_options;
+ CommandOptions m_command_options;
+
+ Options *GetOptions() override { return &m_option_group; }
- Error
- SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_value) override
- {
- Error error;
- const int short_option = g_option_table[option_idx].short_option;
- bool success;
-
- switch (short_option)
- {
- case 'C':
- m_cascade = Args::StringToBoolean(option_value, true, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value);
- break;
- case 'p':
- m_skip_pointers = true;
- break;
- case 'w':
- m_category.assign(option_value);
- break;
- case 'r':
- m_skip_references = true;
- break;
- case 'x':
- m_regex = true;
- break;
- case 't':
- m_custom_type_name.assign(option_value);
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool m_cascade;
- bool m_skip_references;
- bool m_skip_pointers;
- bool m_regex;
- std::string m_category;
- std::string m_custom_type_name;
- };
-
- OptionGroupOptions m_option_group;
- OptionGroupFormat m_format_options;
- CommandOptions m_command_options;
-
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
-
public:
- CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "type format add",
- "Add a new formatting style for a type.",
- nullptr),
- m_option_group (interpreter),
- m_format_options (eFormatInvalid),
- m_command_options ()
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlus;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
-
- SetHelpLong(
-R"(
+ CommandObjectTypeFormatAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "type format add",
+ "Add a new formatting style for a type.", nullptr),
+ m_option_group(), m_format_options(eFormatInvalid),
+ m_command_options() {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
+
+ type_arg.push_back(type_style_arg);
+
+ m_arguments.push_back(type_arg);
+
+ SetHelpLong(
+ R"(
The following examples of 'type format add' refer to this code snippet for context:
typedef int Aint;
@@ -752,8 +651,10 @@ Adding default formatting:
(lldb) type format add -f hex AInt
(lldb) frame variable iy
-)" " Produces hexidecimal display of iy, because no formatter is available for Bint and \
-the one for Aint is used instead." R"(
+)"
+ " Produces hexadecimal display of iy, because no formatter is available for Bint and \
+the one for Aint is used instead."
+ R"(
To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains:
@@ -764,704 +665,574 @@ Similar reasoning applies to this:
(lldb) type format add -f hex -C no float -p
-)" " All float values and float references are now formatted as hexadecimal, but not \
-pointers to floats. Nor will it change the default display for Afloat and Bfloat objects."
- );
-
- // Add the "--format" to all options groups
- m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
- m_option_group.Append (&m_command_options);
- m_option_group.Finalize();
- }
+)"
+ " All float values and float references are now formatted as hexadecimal, but not \
+pointers to floats. Nor will it change the default display for Afloat and Bfloat objects.");
- ~CommandObjectTypeFormatAdd() override = default;
+ // Add the "--format" to all options groups
+ m_option_group.Append(&m_format_options,
+ OptionGroupFormat::OPTION_GROUP_FORMAT,
+ LLDB_OPT_SET_1);
+ m_option_group.Append(&m_command_options);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectTypeFormatAdd() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1)
- {
- result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- const Format format = m_format_options.GetFormat();
- if (format == eFormatInvalid && m_command_options.m_custom_type_name.empty())
- {
- result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- TypeFormatImplSP entry;
-
- if (m_command_options.m_custom_type_name.empty())
- entry.reset(new TypeFormatImpl_Format(format,
- TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
- SetSkipPointers(m_command_options.m_skip_pointers).
- SetSkipReferences(m_command_options.m_skip_references)));
- else
- entry.reset(new TypeFormatImpl_EnumType(ConstString(m_command_options.m_custom_type_name.c_str()),
- TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
- SetSkipPointers(m_command_options.m_skip_pointers).
- SetSkipReferences(m_command_options.m_skip_references)));
-
- // now I have a valid format, let's add it to every type
-
- TypeCategoryImplSP category_sp;
- DataVisualization::Categories::GetCategory(ConstString(m_command_options.m_category), category_sp);
- if (!category_sp)
- return false;
-
- WarnOnPotentialUnquotedUnsignedType(command, result);
-
- for (size_t i = 0; i < argc; i++)
- {
- const char* typeA = command.GetArgumentAtIndex(i);
- ConstString typeCS(typeA);
- if (typeCS)
- {
- if (m_command_options.m_regex)
- {
- RegularExpressionSP typeRX(new RegularExpression());
- if (!typeRX->Compile(typeCS.GetCString()))
- {
- result.AppendError("regex format error (maybe this is not really a regex?)");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS);
- category_sp->GetRegexTypeFormatsContainer()->Add(typeRX, entry);
- }
- else
- category_sp->GetTypeFormatsContainer()->Add(typeCS, entry);
- }
- else
- {
- result.AppendError("empty typenames not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1) {
+ result.AppendErrorWithFormat("%s takes one or more args.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const Format format = m_format_options.GetFormat();
+ if (format == eFormatInvalid &&
+ m_command_options.m_custom_type_name.empty()) {
+ result.AppendErrorWithFormat("%s needs a valid format.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ TypeFormatImplSP entry;
+
+ if (m_command_options.m_custom_type_name.empty())
+ entry.reset(new TypeFormatImpl_Format(
+ format, TypeFormatImpl::Flags()
+ .SetCascades(m_command_options.m_cascade)
+ .SetSkipPointers(m_command_options.m_skip_pointers)
+ .SetSkipReferences(m_command_options.m_skip_references)));
+ else
+ entry.reset(new TypeFormatImpl_EnumType(
+ ConstString(m_command_options.m_custom_type_name.c_str()),
+ TypeFormatImpl::Flags()
+ .SetCascades(m_command_options.m_cascade)
+ .SetSkipPointers(m_command_options.m_skip_pointers)
+ .SetSkipReferences(m_command_options.m_skip_references)));
+
+ // now I have a valid format, let's add it to every type
+
+ TypeCategoryImplSP category_sp;
+ DataVisualization::Categories::GetCategory(
+ ConstString(m_command_options.m_category), category_sp);
+ if (!category_sp)
+ return false;
+
+ WarnOnPotentialUnquotedUnsignedType(command, result);
+
+ for (auto &arg_entry : command.entries()) {
+ if (arg_entry.ref.empty()) {
+ result.AppendError("empty typenames not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ConstString typeCS(arg_entry.ref);
+ if (m_command_options.m_regex) {
+ RegularExpressionSP typeRX(new RegularExpression());
+ if (!typeRX->Compile(arg_entry.ref)) {
+ result.AppendError(
+ "regex format error (maybe this is not really a regex?)");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
+ category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS);
+ category_sp->GetRegexTypeFormatsContainer()->Add(typeRX, entry);
+ } else
+ category_sp->GetTypeFormatsContainer()->Add(typeCS, entry);
}
-};
-OptionDefinition
-CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
- { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions."},
- { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Format variables as if they were of this type."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
};
-uint32_t
-CommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions ()
-{
- return sizeof(g_option_table) / sizeof (OptionDefinition);
-}
+static OptionDefinition g_type_formatter_delete_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete from every category." },
+ { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Delete from given category." },
+ { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Delete from given language's category." }
+ // clang-format on
+};
-class CommandObjectTypeFormatterDelete : public CommandObjectParsed
-{
+class CommandObjectTypeFormatterDelete : public CommandObjectParsed {
protected:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'a':
- m_delete_all = true;
- break;
- case 'w':
- m_category = std::string(option_arg);
- break;
- case 'l':
- m_language = Language::GetLanguageTypeFromString(option_arg);
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_delete_all = false;
- m_category = "default";
- m_language = lldb::eLanguageTypeUnknown;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool m_delete_all;
- std::string m_category;
- lldb::LanguageType m_language;
- };
-
- CommandOptions m_options;
- uint32_t m_formatter_kind_mask;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'a':
+ m_delete_all = true;
+ break;
+ case 'w':
+ m_category = std::string(option_arg);
+ break;
+ case 'l':
+ m_language = Language::GetLanguageTypeFromString(option_arg);
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
-
-public:
- CommandObjectTypeFormatterDelete (CommandInterpreter &interpreter,
- uint32_t formatter_kind_mask,
- const char* name,
- const char* help) :
- CommandObjectParsed(interpreter,
- name,
- help,
- nullptr),
- m_options(interpreter),
- m_formatter_kind_mask(formatter_kind_mask)
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlain;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_delete_all = false;
+ m_category = "default";
+ m_language = lldb::eLanguageTypeUnknown;
}
- ~CommandObjectTypeFormatterDelete() override = default;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_type_formatter_delete_options);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ bool m_delete_all;
+ std::string m_category;
+ lldb::LanguageType m_language;
+ };
+
+ CommandOptions m_options;
+ uint32_t m_formatter_kind_mask;
+
+ Options *GetOptions() override { return &m_options; }
+
+public:
+ CommandObjectTypeFormatterDelete(CommandInterpreter &interpreter,
+ uint32_t formatter_kind_mask,
+ const char *name, const char *help)
+ : CommandObjectParsed(interpreter, name, help, nullptr), m_options(),
+ m_formatter_kind_mask(formatter_kind_mask) {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlain;
+
+ type_arg.push_back(type_style_arg);
+
+ m_arguments.push_back(type_arg);
+ }
+
+ ~CommandObjectTypeFormatterDelete() override = default;
protected:
- virtual bool
- FormatterSpecificDeletion (ConstString typeCS)
- {
- return false;
+ virtual bool FormatterSpecificDeletion(ConstString typeCS) { return false; }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc != 1) {
+ result.AppendErrorWithFormat("%s takes 1 arg.\n", m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- if (argc != 1)
- {
- result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- const char* typeA = command.GetArgumentAtIndex(0);
- ConstString typeCS(typeA);
-
- if (!typeCS)
- {
- result.AppendError("empty typenames not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (m_options.m_delete_all)
- {
- DataVisualization::Categories::ForEach( [this, typeCS] (const lldb::TypeCategoryImplSP& category_sp) -> bool {
- category_sp->Delete(typeCS, m_formatter_kind_mask);
- return true;
- });
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
- }
-
- bool delete_category = false;
- bool extra_deletion = false;
-
- if (m_options.m_language != lldb::eLanguageTypeUnknown)
- {
- lldb::TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(m_options.m_language, category);
- if (category)
- delete_category = category->Delete(typeCS, m_formatter_kind_mask);
- extra_deletion = FormatterSpecificDeletion(typeCS);
- }
- else
- {
- lldb::TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
- if (category)
- delete_category = category->Delete(typeCS, m_formatter_kind_mask);
- extra_deletion = FormatterSpecificDeletion(typeCS);
- }
-
- if (delete_category || extra_deletion)
- {
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
- }
- else
- {
- result.AppendErrorWithFormat ("no custom formatter for %s.\n", typeA);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+
+ const char *typeA = command.GetArgumentAtIndex(0);
+ ConstString typeCS(typeA);
+
+ if (!typeCS) {
+ result.AppendError("empty typenames not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ if (m_options.m_delete_all) {
+ DataVisualization::Categories::ForEach(
+ [this, typeCS](const lldb::TypeCategoryImplSP &category_sp) -> bool {
+ category_sp->Delete(typeCS, m_formatter_kind_mask);
+ return true;
+ });
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
+
+ bool delete_category = false;
+ bool extra_deletion = false;
+
+ if (m_options.m_language != lldb::eLanguageTypeUnknown) {
+ lldb::TypeCategoryImplSP category;
+ DataVisualization::Categories::GetCategory(m_options.m_language,
+ category);
+ if (category)
+ delete_category = category->Delete(typeCS, m_formatter_kind_mask);
+ extra_deletion = FormatterSpecificDeletion(typeCS);
+ } else {
+ lldb::TypeCategoryImplSP category;
+ DataVisualization::Categories::GetCategory(
+ ConstString(m_options.m_category.c_str()), category);
+ if (category)
+ delete_category = category->Delete(typeCS, m_formatter_kind_mask);
+ extra_deletion = FormatterSpecificDeletion(typeCS);
+ }
+
+ if (delete_category || extra_deletion) {
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ } else {
+ result.AppendErrorWithFormat("no custom formatter for %s.\n", typeA);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
};
-OptionDefinition
-CommandObjectTypeFormatterDelete::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete from every category."},
- { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Delete from given category."},
- { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Delete from given language's category."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+static OptionDefinition g_type_formatter_clear_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Clear every category." }
+ // clang-format on
};
-class CommandObjectTypeFormatterClear : public CommandObjectParsed
-{
+class CommandObjectTypeFormatterClear : public CommandObjectParsed {
private:
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'a':
- m_delete_all = true;
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_delete_all = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
- bool m_delete_all;
- };
-
- CommandOptions m_options;
- uint32_t m_formatter_kind_mask;
+ ~CommandOptions() override = default;
- Options *
- GetOptions () override
- {
- return &m_options;
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'a':
+ m_delete_all = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
-
-public:
- CommandObjectTypeFormatterClear (CommandInterpreter &interpreter,
- uint32_t formatter_kind_mask,
- const char* name,
- const char* help) :
- CommandObjectParsed(interpreter,
- name,
- help,
- nullptr),
- m_options(interpreter),
- m_formatter_kind_mask(formatter_kind_mask)
- {
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_delete_all = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_type_formatter_clear_options);
}
- ~CommandObjectTypeFormatterClear() override = default;
+ // Instance variables to hold the values for command options.
+ bool m_delete_all;
+ };
+
+ CommandOptions m_options;
+ uint32_t m_formatter_kind_mask;
+
+ Options *GetOptions() override { return &m_options; }
+
+public:
+ CommandObjectTypeFormatterClear(CommandInterpreter &interpreter,
+ uint32_t formatter_kind_mask,
+ const char *name, const char *help)
+ : CommandObjectParsed(interpreter, name, help, nullptr), m_options(),
+ m_formatter_kind_mask(formatter_kind_mask) {}
+
+ ~CommandObjectTypeFormatterClear() override = default;
protected:
- virtual void
- FormatterSpecificDeletion ()
- {
- }
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- if (m_options.m_delete_all)
- {
- DataVisualization::Categories::ForEach( [this] (const TypeCategoryImplSP& category_sp) -> bool {
- category_sp->Clear(m_formatter_kind_mask);
- return true;
- });
- }
- else
- {
- lldb::TypeCategoryImplSP category;
- if (command.GetArgumentCount() > 0)
- {
- const char* cat_name = command.GetArgumentAtIndex(0);
- ConstString cat_nameCS(cat_name);
- DataVisualization::Categories::GetCategory(cat_nameCS, category);
- }
- else
- {
- DataVisualization::Categories::GetCategory(ConstString(nullptr), category);
- }
- category->Clear(m_formatter_kind_mask);
- }
-
- FormatterSpecificDeletion();
-
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return result.Succeeded();
- }
-};
+ virtual void FormatterSpecificDeletion() {}
-OptionDefinition
-CommandObjectTypeFormatterClear::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Clear every category."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (m_options.m_delete_all) {
+ DataVisualization::Categories::ForEach(
+ [this](const TypeCategoryImplSP &category_sp) -> bool {
+ category_sp->Clear(m_formatter_kind_mask);
+ return true;
+ });
+ } else {
+ lldb::TypeCategoryImplSP category;
+ if (command.GetArgumentCount() > 0) {
+ const char *cat_name = command.GetArgumentAtIndex(0);
+ ConstString cat_nameCS(cat_name);
+ DataVisualization::Categories::GetCategory(cat_nameCS, category);
+ } else {
+ DataVisualization::Categories::GetCategory(ConstString(nullptr),
+ category);
+ }
+ category->Clear(m_formatter_kind_mask);
+ }
+
+ FormatterSpecificDeletion();
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectTypeFormatDelete
//-------------------------------------------------------------------------
-class CommandObjectTypeFormatDelete : public CommandObjectTypeFormatterDelete
-{
+class CommandObjectTypeFormatDelete : public CommandObjectTypeFormatterDelete {
public:
- CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterDelete (interpreter,
- eFormatCategoryItemValue | eFormatCategoryItemRegexValue,
- "type format delete",
- "Delete an existing formatting style for a type.")
- {
- }
-
- ~CommandObjectTypeFormatDelete() override = default;
+ CommandObjectTypeFormatDelete(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterDelete(
+ interpreter,
+ eFormatCategoryItemValue | eFormatCategoryItemRegexValue,
+ "type format delete",
+ "Delete an existing formatting style for a type.") {}
+
+ ~CommandObjectTypeFormatDelete() override = default;
};
//-------------------------------------------------------------------------
// CommandObjectTypeFormatClear
//-------------------------------------------------------------------------
-class CommandObjectTypeFormatClear : public CommandObjectTypeFormatterClear
-{
+class CommandObjectTypeFormatClear : public CommandObjectTypeFormatterClear {
public:
- CommandObjectTypeFormatClear (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterClear (interpreter,
- eFormatCategoryItemValue | eFormatCategoryItemRegexValue,
- "type format clear",
- "Delete all existing format styles.")
- {
- }
+ CommandObjectTypeFormatClear(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterClear(
+ interpreter,
+ eFormatCategoryItemValue | eFormatCategoryItemRegexValue,
+ "type format clear", "Delete all existing format styles.") {}
};
template <typename FormatterType>
-class CommandObjectTypeFormatterList : public CommandObjectParsed
-{
- typedef typename FormatterType::SharedPointer FormatterSharedPointer;
+class CommandObjectTypeFormatterList : public CommandObjectParsed {
+ typedef typename FormatterType::SharedPointer FormatterSharedPointer;
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_category_regex("", ""),
+ m_category_language(lldb::eLanguageTypeUnknown,
+ lldb::eLanguageTypeUnknown) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option) {
+ case 'w':
+ m_category_regex.SetCurrentValue(option_arg);
+ m_category_regex.SetOptionWasSet();
+ break;
+ case 'l':
+ error = m_category_language.SetValueFromString(option_arg);
+ if (error.Success())
+ m_category_language.SetOptionWasSet();
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_category_regex.Clear();
+ m_category_language.Clear();
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ static OptionDefinition g_option_table[] = {
+ // clang-format off
+ {LLDB_OPT_SET_1, false, "category-regex", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Only show categories matching this filter."},
+ {LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Only show the category for a specific language."}
+ // clang-format on
+ };
+ return llvm::ArrayRef<OptionDefinition>(g_option_table);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ OptionValueString m_category_regex;
+ OptionValueLanguage m_category_language;
+ };
+
+ CommandOptions m_options;
+
+ Options *GetOptions() override { return &m_options; }
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_category_regex("",""),
- m_category_language(lldb::eLanguageTypeUnknown, lldb::eLanguageTypeUnknown)
- {
- }
+public:
+ CommandObjectTypeFormatterList(CommandInterpreter &interpreter,
+ const char *name, const char *help)
+ : CommandObjectParsed(interpreter, name, help, nullptr), m_options() {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'w':
- m_category_regex.SetCurrentValue(option_arg);
- m_category_regex.SetOptionWasSet();
- break;
- case 'l':
- error = m_category_language.SetValueFromString(option_arg);
- if (error.Success())
- m_category_language.SetOptionWasSet();
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_category_regex.Clear();
- m_category_language.Clear();
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- static OptionDefinition g_option_table[] =
- {
- { LLDB_OPT_SET_1, false, "category-regex", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Only show categories matching this filter."},
- { LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Only show the category for a specific language."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
- };
-
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- OptionValueString m_category_regex;
- OptionValueLanguage m_category_language;
- };
-
- CommandOptions m_options;
-
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatOptional;
-public:
- CommandObjectTypeFormatterList (CommandInterpreter &interpreter,
- const char* name,
- const char* help) :
- CommandObjectParsed(interpreter,
- name,
- help,
- nullptr),
- m_options(interpreter)
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatOptional;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
- }
+ type_arg.push_back(type_style_arg);
- ~CommandObjectTypeFormatterList() override = default;
+ m_arguments.push_back(type_arg);
+ }
+
+ ~CommandObjectTypeFormatterList() override = default;
protected:
- virtual bool
- FormatterSpecificList (CommandReturnObject &result)
- {
+ virtual bool FormatterSpecificList(CommandReturnObject &result) {
+ return false;
+ }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+
+ std::unique_ptr<RegularExpression> category_regex;
+ std::unique_ptr<RegularExpression> formatter_regex;
+
+ if (m_options.m_category_regex.OptionWasSet()) {
+ category_regex.reset(new RegularExpression());
+ if (!category_regex->Compile(
+ m_options.m_category_regex.GetCurrentValueAsRef())) {
+ result.AppendErrorWithFormat(
+ "syntax error in category regular expression '%s'",
+ m_options.m_category_regex.GetCurrentValueAsRef().str().c_str());
+ result.SetStatus(eReturnStatusFailed);
return false;
+ }
}
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- std::unique_ptr<RegularExpression> category_regex;
- std::unique_ptr<RegularExpression> formatter_regex;
-
- if (m_options.m_category_regex.OptionWasSet())
- {
- category_regex.reset(new RegularExpression());
- if (!category_regex->Compile(m_options.m_category_regex.GetCurrentValue()))
- {
- result.AppendErrorWithFormat("syntax error in category regular expression '%s'", m_options.m_category_regex.GetCurrentValue());
- result.SetStatus(eReturnStatusFailed);
- return false;
+
+ if (argc == 1) {
+ const char *arg = command.GetArgumentAtIndex(0);
+ formatter_regex.reset(new RegularExpression());
+ if (!formatter_regex->Compile(llvm::StringRef::withNullAsEmpty(arg))) {
+ result.AppendErrorWithFormat("syntax error in regular expression '%s'",
+ arg);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ bool any_printed = false;
+
+ auto category_closure = [&result, &formatter_regex, &any_printed](
+ const lldb::TypeCategoryImplSP &category) -> void {
+ result.GetOutputStream().Printf(
+ "-----------------------\nCategory: %s%s\n-----------------------\n",
+ category->GetName(), category->IsEnabled() ? "" : " (disabled)");
+
+ TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
+ foreach
+ .SetExact([&result, &formatter_regex, &any_printed](
+ ConstString name,
+ const FormatterSharedPointer &format_sp) -> bool {
+ if (formatter_regex) {
+ bool escape = true;
+ if (name.GetStringRef() == formatter_regex->GetText()) {
+ escape = false;
+ } else if (formatter_regex->Execute(name.GetStringRef())) {
+ escape = false;
}
- }
-
- if (argc == 1)
- {
- const char* arg = command.GetArgumentAtIndex(0);
- formatter_regex.reset(new RegularExpression());
- if (!formatter_regex->Compile(arg))
- {
- result.AppendErrorWithFormat("syntax error in regular expression '%s'", arg);
- result.SetStatus(eReturnStatusFailed);
- return false;
+
+ if (escape)
+ return true;
+ }
+
+ any_printed = true;
+ result.GetOutputStream().Printf("%s: %s\n", name.AsCString(),
+ format_sp->GetDescription().c_str());
+ return true;
+ });
+
+ foreach
+ .SetWithRegex([&result, &formatter_regex, &any_printed](
+ RegularExpressionSP regex_sp,
+ const FormatterSharedPointer &format_sp) -> bool {
+ if (formatter_regex) {
+ bool escape = true;
+ if (regex_sp->GetText() == formatter_regex->GetText()) {
+ escape = false;
+ } else if (formatter_regex->Execute(regex_sp->GetText())) {
+ escape = false;
}
- }
-
- bool any_printed = false;
-
- auto category_closure = [&result, &formatter_regex, &any_printed] (const lldb::TypeCategoryImplSP& category) -> void {
- result.GetOutputStream().Printf("-----------------------\nCategory: %s%s\n-----------------------\n",
- category->GetName(),
- category->IsEnabled() ? "" : " (disabled)");
-
- TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
- foreach.SetExact([&result, &formatter_regex, &any_printed] (ConstString name, const FormatterSharedPointer& format_sp) -> bool {
- if (formatter_regex)
- {
- bool escape = true;
- if (0 == strcmp(name.AsCString(), formatter_regex->GetText()))
- {
- escape = false;
- }
- else if (formatter_regex->Execute(name.AsCString()))
- {
- escape = false;
- }
-
- if (escape)
- return true;
- }
- any_printed = true;
- result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), format_sp->GetDescription().c_str());
- return true;
- });
-
- foreach.SetWithRegex([&result, &formatter_regex, &any_printed] (RegularExpressionSP regex_sp, const FormatterSharedPointer& format_sp) -> bool {
- if (formatter_regex)
- {
- bool escape = true;
- if (0 == strcmp(regex_sp->GetText(), formatter_regex->GetText()))
- {
- escape = false;
- }
- else if (formatter_regex->Execute(regex_sp->GetText()))
- {
- escape = false;
- }
-
- if (escape)
- return true;
- }
-
- any_printed = true;
- result.GetOutputStream().Printf ("%s: %s\n", regex_sp->GetText(), format_sp->GetDescription().c_str());
- return true;
- });
-
- category->ForEach(foreach);
- };
-
- if (m_options.m_category_language.OptionWasSet())
- {
- lldb::TypeCategoryImplSP category_sp;
- DataVisualization::Categories::GetCategory(m_options.m_category_language.GetCurrentValue(), category_sp);
- if (category_sp)
- category_closure(category_sp);
- }
- else
- {
- DataVisualization::Categories::ForEach( [this, &command, &result, &category_regex, &formatter_regex, &category_closure] (const lldb::TypeCategoryImplSP& category) -> bool {
- if (category_regex)
- {
- bool escape = true;
- if (0 == strcmp(category->GetName(), category_regex->GetText()))
- {
- escape = false;
- }
- else if (category_regex->Execute(category->GetName()))
- {
- escape = false;
- }
-
- if (escape)
- return true;
- }
-
- category_closure(category);
-
+ if (escape)
+ return true;
+ }
+
+ any_printed = true;
+ result.GetOutputStream().Printf("%s: %s\n",
+ regex_sp->GetText().str().c_str(),
+ format_sp->GetDescription().c_str());
+ return true;
+ });
+
+ category->ForEach(foreach);
+ };
+
+ if (m_options.m_category_language.OptionWasSet()) {
+ lldb::TypeCategoryImplSP category_sp;
+ DataVisualization::Categories::GetCategory(
+ m_options.m_category_language.GetCurrentValue(), category_sp);
+ if (category_sp)
+ category_closure(category_sp);
+ } else {
+ DataVisualization::Categories::ForEach(
+ [this, &command, &result, &category_regex, &formatter_regex,
+ &category_closure](
+ const lldb::TypeCategoryImplSP &category) -> bool {
+ if (category_regex) {
+ bool escape = true;
+ if (category->GetName() == category_regex->GetText()) {
+ escape = false;
+ } else if (category_regex->Execute(
+ llvm::StringRef::withNullAsEmpty(
+ category->GetName()))) {
+ escape = false;
+ }
+
+ if (escape)
return true;
- });
-
- any_printed = FormatterSpecificList(result) | any_printed;
- }
-
- if (any_printed)
- result.SetStatus(eReturnStatusSuccessFinishResult);
- else
- {
- result.GetOutputStream().PutCString("no matching results found.\n");
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- return result.Succeeded();
+ }
+
+ category_closure(category);
+
+ return true;
+ });
+
+ any_printed = FormatterSpecificList(result) | any_printed;
+ }
+
+ if (any_printed)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ else {
+ result.GetOutputStream().PutCString("no matching results found.\n");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectTypeFormatList
//-------------------------------------------------------------------------
-class CommandObjectTypeFormatList : public CommandObjectTypeFormatterList<TypeFormatImpl>
-{
+class CommandObjectTypeFormatList
+ : public CommandObjectTypeFormatterList<TypeFormatImpl> {
public:
-
- CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterList(interpreter,
- "type format list",
- "Show a list of current formats.")
- {
- }
+ CommandObjectTypeFormatList(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterList(interpreter, "type format list",
+ "Show a list of current formats.") {}
};
#ifndef LLDB_DISABLE_PYTHON
@@ -1472,333 +1243,313 @@ public:
#endif // LLDB_DISABLE_PYTHON
-Error
-CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
-{
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
- bool success;
-
- switch (short_option)
- {
- case 'C':
- m_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success));
- if (!success)
- error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
- break;
- case 'e':
- m_flags.SetDontShowChildren(false);
- break;
- case 'h':
- m_flags.SetHideEmptyAggregates(true);
- break;
- case 'v':
- m_flags.SetDontShowValue(true);
- break;
- case 'c':
- m_flags.SetShowMembersOneLiner(true);
- break;
- case 's':
- m_format_string = std::string(option_arg);
- break;
- case 'p':
- m_flags.SetSkipPointers(true);
- break;
- case 'r':
- m_flags.SetSkipReferences(true);
- break;
- case 'x':
- m_regex = true;
- break;
- case 'n':
- m_name.SetCString(option_arg);
- break;
- case 'o':
- m_python_script = std::string(option_arg);
- m_is_add_script = true;
- break;
- case 'F':
- m_python_function = std::string(option_arg);
- m_is_add_script = true;
- break;
- case 'P':
- m_is_add_script = true;
- break;
- case 'w':
- m_category = std::string(option_arg);
- break;
- case 'O':
- m_flags.SetHideItemNames(true);
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
+Error CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ bool success;
+
+ switch (short_option) {
+ case 'C':
+ m_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success));
+ if (!success)
+ error.SetErrorStringWithFormat("invalid value for cascade: %s",
+ option_arg.str().c_str());
+ break;
+ case 'e':
+ m_flags.SetDontShowChildren(false);
+ break;
+ case 'h':
+ m_flags.SetHideEmptyAggregates(true);
+ break;
+ case 'v':
+ m_flags.SetDontShowValue(true);
+ break;
+ case 'c':
+ m_flags.SetShowMembersOneLiner(true);
+ break;
+ case 's':
+ m_format_string = std::string(option_arg);
+ break;
+ case 'p':
+ m_flags.SetSkipPointers(true);
+ break;
+ case 'r':
+ m_flags.SetSkipReferences(true);
+ break;
+ case 'x':
+ m_regex = true;
+ break;
+ case 'n':
+ m_name.SetString(option_arg);
+ break;
+ case 'o':
+ m_python_script = option_arg;
+ m_is_add_script = true;
+ break;
+ case 'F':
+ m_python_function = option_arg;
+ m_is_add_script = true;
+ break;
+ case 'P':
+ m_is_add_script = true;
+ break;
+ case 'w':
+ m_category = std::string(option_arg);
+ break;
+ case 'O':
+ m_flags.SetHideItemNames(true);
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
+ break;
+ }
+
+ return error;
}
-void
-CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting ()
-{
- m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
- m_flags.SetShowMembersOneLiner(false).SetSkipPointers(false).SetSkipReferences(false).SetHideItemNames(false);
-
- m_regex = false;
- m_name.Clear();
- m_python_script = "";
- m_python_function = "";
- m_format_string = "";
- m_is_add_script = false;
- m_category = "default";
+void CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting(
+ ExecutionContext *execution_context) {
+ m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
+ m_flags.SetShowMembersOneLiner(false)
+ .SetSkipPointers(false)
+ .SetSkipReferences(false)
+ .SetHideItemNames(false);
+
+ m_regex = false;
+ m_name.Clear();
+ m_python_script = "";
+ m_python_function = "";
+ m_format_string = "";
+ m_is_add_script = false;
+ m_category = "default";
}
#ifndef LLDB_DISABLE_PYTHON
-bool
-CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result)
-{
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1 && !m_options.m_name)
- {
- result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+bool CommandObjectTypeSummaryAdd::Execute_ScriptSummary(
+ Args &command, CommandReturnObject &result) {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1 && !m_options.m_name) {
+ result.AppendErrorWithFormat("%s takes one or more args.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ TypeSummaryImplSP script_format;
+
+ if (!m_options.m_python_function
+ .empty()) // we have a Python function ready to use
+ {
+ const char *funct_name = m_options.m_python_function.c_str();
+ if (!funct_name || !funct_name[0]) {
+ result.AppendError("function name empty.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ std::string code =
+ (" " + m_options.m_python_function + "(valobj,internal_dict)");
+
+ script_format.reset(
+ new ScriptSummaryFormat(m_options.m_flags, funct_name, code.c_str()));
+
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+
+ if (interpreter && !interpreter->CheckObjectExists(funct_name))
+ result.AppendWarningWithFormat(
+ "The provided function \"%s\" does not exist - "
+ "please define it before attempting to use this summary.\n",
+ funct_name);
+ } else if (!m_options.m_python_script
+ .empty()) // we have a quick 1-line script, just use it
+ {
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (!interpreter) {
+ result.AppendError("script interpreter missing - unable to generate "
+ "function wrapper.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ StringList funct_sl;
+ funct_sl << m_options.m_python_script.c_str();
+ std::string funct_name_str;
+ if (!interpreter->GenerateTypeScriptFunction(funct_sl, funct_name_str)) {
+ result.AppendError("unable to generate function wrapper.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ if (funct_name_str.empty()) {
+ result.AppendError(
+ "script interpreter failed to generate a valid function name.\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ std::string code = " " + m_options.m_python_script;
+
+ script_format.reset(new ScriptSummaryFormat(
+ m_options.m_flags, funct_name_str.c_str(), code.c_str()));
+ } else {
+ // Use an IOHandler to grab Python code from the user
+ ScriptAddOptions *options =
+ new ScriptAddOptions(m_options.m_flags, m_options.m_regex,
+ m_options.m_name, m_options.m_category);
+
+ for (auto &entry : command.entries()) {
+ if (entry.ref.empty()) {
+ result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
+ }
+
+ options->m_target_types << entry.ref;
}
-
- TypeSummaryImplSP script_format;
-
- if (!m_options.m_python_function.empty()) // we have a Python function ready to use
- {
- const char *funct_name = m_options.m_python_function.c_str();
- if (!funct_name || !funct_name[0])
- {
- result.AppendError ("function name empty.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- std::string code = (" " + m_options.m_python_function + "(valobj,internal_dict)");
-
- script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
- funct_name,
- code.c_str()));
-
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
-
- if (interpreter && !interpreter->CheckObjectExists(funct_name))
- result.AppendWarningWithFormat("The provided function \"%s\" does not exist - "
- "please define it before attempting to use this summary.\n",
- funct_name);
- }
- else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it
- {
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (!interpreter)
- {
- result.AppendError ("script interpreter missing - unable to generate function wrapper.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- StringList funct_sl;
- funct_sl << m_options.m_python_script.c_str();
- std::string funct_name_str;
- if (!interpreter->GenerateTypeScriptFunction (funct_sl,
- funct_name_str))
- {
- result.AppendError ("unable to generate function wrapper.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (funct_name_str.empty())
- {
- result.AppendError ("script interpreter failed to generate a valid function name.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- std::string code = " " + m_options.m_python_script;
-
- script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
- funct_name_str.c_str(),
- code.c_str()));
- }
- else
- {
- // Use an IOHandler to grab Python code from the user
- ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags,
- m_options.m_regex,
- m_options.m_name,
- m_options.m_category);
-
- for (size_t i = 0; i < argc; i++)
- {
- const char* typeA = command.GetArgumentAtIndex(i);
- if (typeA && *typeA)
- options->m_target_types << typeA;
- else
- {
- result.AppendError("empty typenames not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
-
- m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
- *this, // IOHandlerDelegate
- true, // Run IOHandler in async mode
- options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
-
- return result.Succeeded();
- }
-
- // if I am here, script_format must point to something good, so I can add that
- // as a script summary to all interested parties
-
- Error error;
-
- for (size_t i = 0; i < command.GetArgumentCount(); i++)
- {
- const char *type_name = command.GetArgumentAtIndex(i);
- CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
- script_format,
- (m_options.m_regex ? eRegexSummary : eRegularSummary),
- m_options.m_category,
- &error);
- if (error.Fail())
- {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+
+ m_interpreter.GetPythonCommandsFromIOHandler(
+ " ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ options); // Baton for the "io_handler" that will be passed back into
+ // our IOHandlerDelegate functions
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+
+ return result.Succeeded();
+ }
+
+ // if I am here, script_format must point to something good, so I can add that
+ // as a script summary to all interested parties
+
+ Error error;
+
+ for (auto &entry : command.entries()) {
+ CommandObjectTypeSummaryAdd::AddSummary(
+ ConstString(entry.ref), script_format,
+ (m_options.m_regex ? eRegexSummary : eRegularSummary),
+ m_options.m_category, &error);
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- if (m_options.m_name)
- {
- AddSummary(m_options.m_name, script_format, eNamedSummary, m_options.m_category, &error);
- if (error.Fail())
- {
- result.AppendError(error.AsCString());
- result.AppendError("added to types, but not given a name");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ }
+
+ if (m_options.m_name) {
+ AddSummary(m_options.m_name, script_format, eNamedSummary,
+ m_options.m_category, &error);
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.AppendError("added to types, but not given a name");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- return result.Succeeded();
+ }
+
+ return result.Succeeded();
}
#endif // LLDB_DISABLE_PYTHON
-bool
-CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result)
-{
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1 && !m_options.m_name)
- {
- result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (!m_options.m_flags.GetShowMembersOneLiner() && m_options.m_format_string.empty())
- {
- result.AppendError("empty summary strings not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- const char* format_cstr = (m_options.m_flags.GetShowMembersOneLiner() ? "" : m_options.m_format_string.c_str());
-
- // ${var%S} is an endless recursion, prevent it
- if (strcmp(format_cstr, "${var%S}") == 0)
- {
- result.AppendError("recursive summary not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- std::unique_ptr<StringSummaryFormat> string_format(new StringSummaryFormat(m_options.m_flags, format_cstr));
- if (!string_format)
- {
- result.AppendError("summary creation failed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- if (string_format->m_error.Fail())
- {
- result.AppendErrorWithFormat("syntax error: %s", string_format->m_error.AsCString("<unknown>"));
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- lldb::TypeSummaryImplSP entry(string_format.release());
-
- // now I have a valid format, let's add it to every type
- Error error;
- for (size_t i = 0; i < argc; i++)
- {
- const char* typeA = command.GetArgumentAtIndex(i);
- if (!typeA || typeA[0] == '\0')
- {
- result.AppendError("empty typenames not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- ConstString typeCS(typeA);
-
- AddSummary(typeCS,
- entry,
- (m_options.m_regex ? eRegexSummary : eRegularSummary),
- m_options.m_category,
- &error);
-
- if (error.Fail())
- {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
-
- if (m_options.m_name)
- {
- AddSummary(m_options.m_name, entry, eNamedSummary, m_options.m_category, &error);
- if (error.Fail())
- {
- result.AppendError(error.AsCString());
- result.AppendError("added to types, but not given a name");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
-
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
+bool CommandObjectTypeSummaryAdd::Execute_StringSummary(
+ Args &command, CommandReturnObject &result) {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1 && !m_options.m_name) {
+ result.AppendErrorWithFormat("%s takes one or more args.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (!m_options.m_flags.GetShowMembersOneLiner() &&
+ m_options.m_format_string.empty()) {
+ result.AppendError("empty summary strings not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const char *format_cstr = (m_options.m_flags.GetShowMembersOneLiner()
+ ? ""
+ : m_options.m_format_string.c_str());
+
+ // ${var%S} is an endless recursion, prevent it
+ if (strcmp(format_cstr, "${var%S}") == 0) {
+ result.AppendError("recursive summary not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ std::unique_ptr<StringSummaryFormat> string_format(
+ new StringSummaryFormat(m_options.m_flags, format_cstr));
+ if (!string_format) {
+ result.AppendError("summary creation failed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ if (string_format->m_error.Fail()) {
+ result.AppendErrorWithFormat("syntax error: %s",
+ string_format->m_error.AsCString("<unknown>"));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ lldb::TypeSummaryImplSP entry(string_format.release());
+
+ // now I have a valid format, let's add it to every type
+ Error error;
+ for (auto &arg_entry : command.entries()) {
+ if (arg_entry.ref.empty()) {
+ result.AppendError("empty typenames not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ ConstString typeCS(arg_entry.ref);
+
+ AddSummary(typeCS, entry,
+ (m_options.m_regex ? eRegexSummary : eRegularSummary),
+ m_options.m_category, &error);
+
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ if (m_options.m_name) {
+ AddSummary(m_options.m_name, entry, eNamedSummary, m_options.m_category,
+ &error);
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.AppendError("added to types, but not given a name");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
}
-CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "type summary add",
- "Add a new summary style for a type.",
- nullptr),
- IOHandlerDelegateMultiline ("DONE"),
- m_options (interpreter)
-{
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlus;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
-
- SetHelpLong(
-R"(
+CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "type summary add",
+ "Add a new summary style for a type.", nullptr),
+ IOHandlerDelegateMultiline("DONE"), m_options(interpreter) {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
+
+ type_arg.push_back(type_style_arg);
+
+ m_arguments.push_back(type_arg);
+
+ SetHelpLong(
+ R"(
The following examples of 'type summary add' refer to this code snippet for context:
struct JustADemo
@@ -1820,51 +1571,65 @@ The following examples of 'type summary add' refer to this code snippet for cont
Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14"
-)" "Alternatively, you could define formatting for all pointers to integers and \
-rely on that when formatting JustADemo to obtain the same result:" R"(
+)"
+ "Alternatively, you could define formatting for all pointers to integers and \
+rely on that when formatting JustADemo to obtain the same result:"
+ R"(
(lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *"
(lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo
-)" "Type summaries are automatically applied to derived typedefs, so the examples \
+)"
+ "Type summaries are automatically applied to derived typedefs, so the examples \
above apply to both JustADemo and NewDemo. The cascade option can be used to \
-suppress this behavior:" R"(
+suppress this behavior:"
+ R"(
(lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no
The summary will now be used for values of JustADemo but not NewDemo.
-)" "By default summaries are shown for pointers and references to values of the \
+)"
+ "By default summaries are shown for pointers and references to values of the \
specified type. To suppress formatting for pointers use the -p option, or apply \
-the corresponding -r option to suppress formatting for references:" R"(
+the corresponding -r option to suppress formatting for references:"
+ R"(
(lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo
-)" "One-line summaries including all fields in a type can be inferred without supplying an \
-explicit summary string by passing the -c option:" R"(
+)"
+ "One-line summaries including all fields in a type can be inferred without supplying an \
+explicit summary string by passing the -c option:"
+ R"(
(lldb) type summary add -c JustADemo
(lldb) frame variable demo_instance
(ptr=<address>, value=3.14)
-)" "Type summaries normally suppress the nested display of individual fields. To \
-supply a summary to supplement the default structure add the -e option:" R"(
+)"
+ "Type summaries normally suppress the nested display of individual fields. To \
+supply a summary to supplement the default structure add the -e option:"
+ R"(
(lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo
-)" "Now when displaying JustADemo values the int* is displayed, followed by the \
-standard LLDB sequence of children, one per line:" R"(
+)"
+ "Now when displaying JustADemo values the int* is displayed, followed by the \
+standard LLDB sequence of children, one per line:"
+ R"(
*ptr = 42 {
ptr = <address>
value = 3.14
}
-)" "You can also add summaries written in Python. These scripts use lldb public API to \
+)"
+ "You can also add summaries written in Python. These scripts use lldb public API to \
gather information from your variables and produce a meaningful summary. To start a \
multi-line script use the -P option. The function declaration will be displayed along with \
a comment describing the two arguments. End your script with the word 'DONE' on a line by \
-itself:" R"(
+itself:"
+ R"(
(lldb) type summary add JustADemo -P
def function (valobj,internal_dict):
@@ -1876,773 +1641,621 @@ internal_dict: an LLDB support object not to be used"""
Alternatively, the -o option can be used when providing a simple one-line Python script:
-(lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")"
- );
+(lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")");
}
-bool
-CommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &result)
-{
- WarnOnPotentialUnquotedUnsignedType(command, result);
+bool CommandObjectTypeSummaryAdd::DoExecute(Args &command,
+ CommandReturnObject &result) {
+ WarnOnPotentialUnquotedUnsignedType(command, result);
- if (m_options.m_is_add_script)
- {
+ if (m_options.m_is_add_script) {
#ifndef LLDB_DISABLE_PYTHON
- return Execute_ScriptSummary(command, result);
+ return Execute_ScriptSummary(command, result);
#else
- result.AppendError ("python is disabled");
- result.SetStatus(eReturnStatusFailed);
- return false;
+ result.AppendError("python is disabled");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
#endif // LLDB_DISABLE_PYTHON
- }
-
- return Execute_StringSummary(command, result);
-}
+ }
-static bool
-FixArrayTypeNameWithRegex (ConstString &type_name)
-{
- llvm::StringRef type_name_ref(type_name.GetStringRef());
-
- if (type_name_ref.endswith("[]"))
- {
- std::string type_name_str(type_name.GetCString());
- type_name_str.resize(type_name_str.length()-2);
- if (type_name_str.back() != ' ')
- type_name_str.append(" \\[[0-9]+\\]");
- else
- type_name_str.append("\\[[0-9]+\\]");
- type_name.SetCString(type_name_str.c_str());
- return true;
- }
- return false;
+ return Execute_StringSummary(command, result);
}
-bool
-CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
- TypeSummaryImplSP entry,
- SummaryFormatType type,
- std::string category_name,
- Error* error)
-{
- lldb::TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
-
- if (type == eRegularSummary)
- {
- if (FixArrayTypeNameWithRegex (type_name))
- type = eRegexSummary;
- }
-
- if (type == eRegexSummary)
- {
- RegularExpressionSP typeRX(new RegularExpression());
- if (!typeRX->Compile(type_name.GetCString()))
- {
- if (error)
- error->SetErrorString("regex format error (maybe this is not really a regex?)");
- return false;
- }
-
- category->GetRegexTypeSummariesContainer()->Delete(type_name);
- category->GetRegexTypeSummariesContainer()->Add(typeRX, entry);
-
- return true;
- }
- else if (type == eNamedSummary)
- {
- // system named summaries do not exist (yet?)
- DataVisualization::NamedSummaryFormats::Add(type_name,entry);
- return true;
- }
+static bool FixArrayTypeNameWithRegex(ConstString &type_name) {
+ llvm::StringRef type_name_ref(type_name.GetStringRef());
+
+ if (type_name_ref.endswith("[]")) {
+ std::string type_name_str(type_name.GetCString());
+ type_name_str.resize(type_name_str.length() - 2);
+ if (type_name_str.back() != ' ')
+ type_name_str.append(" \\[[0-9]+\\]");
else
- {
- category->GetTypeSummariesContainer()->Add(type_name, entry);
- return true;
- }
-}
-
-OptionDefinition
-CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
- { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."},
- { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions."},
- { LLDB_OPT_SET_1 , true, "inline-children", 'c', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If true, inline all child values into summary string."},
- { LLDB_OPT_SET_1 , false, "omit-names", 'O', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If true, omit value names in the summary display."},
- { LLDB_OPT_SET_2 , true, "summary-string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."},
- { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."},
- { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."},
- { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Input Python code to use for this type manually."},
- { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."},
- { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "hide-empty", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Do not expand aggregate data types with no children."},
- { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "A name for this summary string."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
-};
+ type_name_str.append("\\[[0-9]+\\]");
+ type_name.SetCString(type_name_str.c_str());
+ return true;
+ }
+ return false;
+}
+
+bool CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
+ TypeSummaryImplSP entry,
+ SummaryFormatType type,
+ std::string category_name,
+ Error *error) {
+ lldb::TypeCategoryImplSP category;
+ DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()),
+ category);
+
+ if (type == eRegularSummary) {
+ if (FixArrayTypeNameWithRegex(type_name))
+ type = eRegexSummary;
+ }
+
+ if (type == eRegexSummary) {
+ RegularExpressionSP typeRX(new RegularExpression());
+ if (!typeRX->Compile(type_name.GetStringRef())) {
+ if (error)
+ error->SetErrorString(
+ "regex format error (maybe this is not really a regex?)");
+ return false;
+ }
+
+ category->GetRegexTypeSummariesContainer()->Delete(type_name);
+ category->GetRegexTypeSummariesContainer()->Add(typeRX, entry);
+
+ return true;
+ } else if (type == eNamedSummary) {
+ // system named summaries do not exist (yet?)
+ DataVisualization::NamedSummaryFormats::Add(type_name, entry);
+ return true;
+ } else {
+ category->GetTypeSummariesContainer()->Add(type_name, entry);
+ return true;
+ }
+}
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryDelete
//-------------------------------------------------------------------------
-class CommandObjectTypeSummaryDelete : public CommandObjectTypeFormatterDelete
-{
+class CommandObjectTypeSummaryDelete : public CommandObjectTypeFormatterDelete {
public:
- CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterDelete (interpreter,
- eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary,
- "type summary delete",
- "Delete an existing summary for a type.")
- {
- }
+ CommandObjectTypeSummaryDelete(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterDelete(
+ interpreter,
+ eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary,
+ "type summary delete", "Delete an existing summary for a type.") {}
- ~CommandObjectTypeSummaryDelete() override = default;
+ ~CommandObjectTypeSummaryDelete() override = default;
protected:
- bool
- FormatterSpecificDeletion (ConstString typeCS) override
- {
- if (m_options.m_language != lldb::eLanguageTypeUnknown)
- return false;
- return DataVisualization::NamedSummaryFormats::Delete(typeCS);
- }
+ bool FormatterSpecificDeletion(ConstString typeCS) override {
+ if (m_options.m_language != lldb::eLanguageTypeUnknown)
+ return false;
+ return DataVisualization::NamedSummaryFormats::Delete(typeCS);
+ }
};
-class CommandObjectTypeSummaryClear : public CommandObjectTypeFormatterClear
-{
+class CommandObjectTypeSummaryClear : public CommandObjectTypeFormatterClear {
public:
- CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterClear (interpreter,
- eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary,
- "type summary clear",
- "Delete all existing summaries.")
- {
- }
-
+ CommandObjectTypeSummaryClear(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterClear(
+ interpreter,
+ eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary,
+ "type summary clear", "Delete all existing summaries.") {}
+
protected:
- void
- FormatterSpecificDeletion () override
- {
- DataVisualization::NamedSummaryFormats::Clear();
- }
+ void FormatterSpecificDeletion() override {
+ DataVisualization::NamedSummaryFormats::Clear();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryList
//-------------------------------------------------------------------------
-class CommandObjectTypeSummaryList : public CommandObjectTypeFormatterList<TypeSummaryImpl>
-{
+class CommandObjectTypeSummaryList
+ : public CommandObjectTypeFormatterList<TypeSummaryImpl> {
public:
- CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterList(interpreter,
- "type summary list",
- "Show a list of current summaries.")
- {
- }
-
+ CommandObjectTypeSummaryList(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterList(interpreter, "type summary list",
+ "Show a list of current summaries.") {}
+
protected:
- bool
- FormatterSpecificList (CommandReturnObject &result) override
- {
- if (DataVisualization::NamedSummaryFormats::GetCount() > 0)
- {
- result.GetOutputStream().Printf("Named summaries:\n");
- DataVisualization::NamedSummaryFormats::ForEach( [&result] (ConstString name, const TypeSummaryImplSP& summary_sp) -> bool {
- result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), summary_sp->GetDescription().c_str());
- return true;
- });
+ bool FormatterSpecificList(CommandReturnObject &result) override {
+ if (DataVisualization::NamedSummaryFormats::GetCount() > 0) {
+ result.GetOutputStream().Printf("Named summaries:\n");
+ DataVisualization::NamedSummaryFormats::ForEach(
+ [&result](ConstString name,
+ const TypeSummaryImplSP &summary_sp) -> bool {
+ result.GetOutputStream().Printf(
+ "%s: %s\n", name.AsCString(),
+ summary_sp->GetDescription().c_str());
return true;
- }
- return false;
+ });
+ return true;
}
+ return false;
+ }
};
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryDefine
//-------------------------------------------------------------------------
-class CommandObjectTypeCategoryDefine : public CommandObjectParsed
-{
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_define_enabled(false,false),
- m_cate_language(eLanguageTypeUnknown,eLanguageTypeUnknown)
- {
- }
+static OptionDefinition g_type_category_define_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "enabled", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If specified, this category will be created enabled." },
+ { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specify the language that this category is supported for." }
+ // clang-format on
+};
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'e':
- m_define_enabled.SetValueFromString("true");
- break;
- case 'l':
- error = m_cate_language.SetValueFromString(option_arg);
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_define_enabled.Clear();
- m_cate_language.Clear();
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- OptionValueBoolean m_define_enabled;
- OptionValueLanguage m_cate_language;
- };
-
- CommandOptions m_options;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+class CommandObjectTypeCategoryDefine : public CommandObjectParsed {
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_define_enabled(false, false),
+ m_cate_language(eLanguageTypeUnknown, eLanguageTypeUnknown) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'e':
+ m_define_enabled.SetValueFromString(llvm::StringRef("true"));
+ break;
+ case 'l':
+ error = m_cate_language.SetValueFromString(option_arg);
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_define_enabled.Clear();
+ m_cate_language.Clear();
}
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_type_category_define_options);
+ }
+
+ // Instance variables to hold the values for command options.
+
+ OptionValueBoolean m_define_enabled;
+ OptionValueLanguage m_cate_language;
+ };
+
+ CommandOptions m_options;
+
+ Options *GetOptions() override { return &m_options; }
+
public:
- CommandObjectTypeCategoryDefine (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "type category define",
+ CommandObjectTypeCategoryDefine(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "type category define",
"Define a new category as a source of formatters.",
nullptr),
- m_options(interpreter)
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlus;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
- }
+ m_options() {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
+
+ type_arg.push_back(type_style_arg);
+
+ m_arguments.push_back(type_arg);
+ }
- ~CommandObjectTypeCategoryDefine() override = default;
+ ~CommandObjectTypeCategoryDefine() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1)
- {
- result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- for (size_t i = 0; i < argc; i++)
- {
- const char* cateName = command.GetArgumentAtIndex(i);
- TypeCategoryImplSP category_sp;
- if (DataVisualization::Categories::GetCategory(ConstString(cateName), category_sp) && category_sp)
- {
- category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
- if (m_options.m_define_enabled.GetCurrentValue())
- DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default);
- }
- }
-
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1) {
+ result.AppendErrorWithFormat("%s takes 1 or more args.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-};
-OptionDefinition
-CommandObjectTypeCategoryDefine::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "enabled", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If specified, this category will be created enabled."},
- { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specify the language that this category is supported for."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ for (auto &entry : command.entries()) {
+ TypeCategoryImplSP category_sp;
+ if (DataVisualization::Categories::GetCategory(ConstString(entry.ref),
+ category_sp) &&
+ category_sp) {
+ category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
+ if (m_options.m_define_enabled.GetCurrentValue())
+ DataVisualization::Categories::Enable(category_sp,
+ TypeCategoryMap::Default);
+ }
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryEnable
//-------------------------------------------------------------------------
-class CommandObjectTypeCategoryEnable : public CommandObjectParsed
-{
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
+static OptionDefinition g_type_category_enable_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Enable the category for this language." },
+ // clang-format on
+};
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'l':
- if (option_arg)
- {
- m_language = Language::GetLanguageTypeFromString(option_arg);
- if (m_language == lldb::eLanguageTypeUnknown)
- error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
- }
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_language = lldb::eLanguageTypeUnknown;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
+class CommandObjectTypeCategoryEnable : public CommandObjectParsed {
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'l':
+ if (!option_arg.empty()) {
+ m_language = Language::GetLanguageTypeFromString(option_arg);
+ if (m_language == lldb::eLanguageTypeUnknown)
+ error.SetErrorStringWithFormat("unrecognized language '%s'",
+ option_arg.str().c_str());
}
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- lldb::LanguageType m_language;
-
- };
-
- CommandOptions m_options;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_language = lldb::eLanguageTypeUnknown;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_type_category_enable_options);
}
-
+
+ // Instance variables to hold the values for command options.
+
+ lldb::LanguageType m_language;
+ };
+
+ CommandOptions m_options;
+
+ Options *GetOptions() override { return &m_options; }
+
public:
- CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "type category enable",
+ CommandObjectTypeCategoryEnable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "type category enable",
"Enable a category as a source of formatters.",
nullptr),
- m_options(interpreter)
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlus;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
-
- }
+ m_options() {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
- ~CommandObjectTypeCategoryEnable() override = default;
+ type_arg.push_back(type_style_arg);
+
+ m_arguments.push_back(type_arg);
+ }
+
+ ~CommandObjectTypeCategoryEnable() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1 &&
- m_options.m_language == lldb::eLanguageTypeUnknown)
- {
- result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
+ result.AppendErrorWithFormat("%s takes arguments and/or a language",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
+ DataVisualization::Categories::EnableStar();
+ } else if (argc > 0) {
+ for (int i = argc - 1; i >= 0; i--) {
+ const char *typeA = command.GetArgumentAtIndex(i);
+ ConstString typeCS(typeA);
+
+ if (!typeCS) {
+ result.AppendError("empty category name not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
- {
- DataVisualization::Categories::EnableStar();
+ DataVisualization::Categories::Enable(typeCS);
+ lldb::TypeCategoryImplSP cate;
+ if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate) {
+ if (cate->GetCount() == 0) {
+ result.AppendWarning("empty category enabled (typo?)");
+ }
}
- else if (argc > 0)
- {
- for (int i = argc - 1; i >= 0; i--)
- {
- const char* typeA = command.GetArgumentAtIndex(i);
- ConstString typeCS(typeA);
-
- if (!typeCS)
- {
- result.AppendError("empty category name not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- DataVisualization::Categories::Enable(typeCS);
- lldb::TypeCategoryImplSP cate;
- if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate)
- {
- if (cate->GetCount() == 0)
- {
- result.AppendWarning("empty category enabled (typo?)");
- }
- }
- }
- }
-
- if (m_options.m_language != lldb::eLanguageTypeUnknown)
- DataVisualization::Categories::Enable(m_options.m_language);
-
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return result.Succeeded();
+ }
}
-};
-OptionDefinition
-CommandObjectTypeCategoryEnable::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Enable the category for this language."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ if (m_options.m_language != lldb::eLanguageTypeUnknown)
+ DataVisualization::Categories::Enable(m_options.m_language);
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryDelete
//-------------------------------------------------------------------------
-class CommandObjectTypeCategoryDelete : public CommandObjectParsed
-{
+class CommandObjectTypeCategoryDelete : public CommandObjectParsed {
public:
- CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "type category delete",
+ CommandObjectTypeCategoryDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "type category delete",
"Delete a category and all associated formatters.",
- nullptr)
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlus;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
- }
+ nullptr) {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
+
+ type_arg.push_back(type_style_arg);
+
+ m_arguments.push_back(type_arg);
+ }
- ~CommandObjectTypeCategoryDelete() override = default;
+ ~CommandObjectTypeCategoryDelete() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1)
- {
- result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- bool success = true;
-
- // the order is not relevant here
- for (int i = argc - 1; i >= 0; i--)
- {
- const char* typeA = command.GetArgumentAtIndex(i);
- ConstString typeCS(typeA);
-
- if (!typeCS)
- {
- result.AppendError("empty category name not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- if (!DataVisualization::Categories::Delete(typeCS))
- success = false; // keep deleting even if we hit an error
- }
- if (success)
- {
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return result.Succeeded();
- }
- else
- {
- result.AppendError("cannot delete one or more categories\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1) {
+ result.AppendErrorWithFormat("%s takes 1 or more arg.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+
+ bool success = true;
+
+ // the order is not relevant here
+ for (int i = argc - 1; i >= 0; i--) {
+ const char *typeA = command.GetArgumentAtIndex(i);
+ ConstString typeCS(typeA);
+
+ if (!typeCS) {
+ result.AppendError("empty category name not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ if (!DataVisualization::Categories::Delete(typeCS))
+ success = false; // keep deleting even if we hit an error
+ }
+ if (success) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ } else {
+ result.AppendError("cannot delete one or more categories\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
};
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryDisable
//-------------------------------------------------------------------------
-class CommandObjectTypeCategoryDisable : public CommandObjectParsed
-{
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
+OptionDefinition g_type_category_disable_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Enable the category for this language." }
+ // clang-format on
+};
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'l':
- if (option_arg)
- {
- m_language = Language::GetLanguageTypeFromString(option_arg);
- if (m_language == lldb::eLanguageTypeUnknown)
- error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
- }
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_language = lldb::eLanguageTypeUnknown;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
+class CommandObjectTypeCategoryDisable : public CommandObjectParsed {
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'l':
+ if (!option_arg.empty()) {
+ m_language = Language::GetLanguageTypeFromString(option_arg);
+ if (m_language == lldb::eLanguageTypeUnknown)
+ error.SetErrorStringWithFormat("unrecognized language '%s'",
+ option_arg.str().c_str());
}
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- lldb::LanguageType m_language;
- };
-
- CommandOptions m_options;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_language = lldb::eLanguageTypeUnknown;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_type_category_disable_options);
}
+ // Instance variables to hold the values for command options.
+
+ lldb::LanguageType m_language;
+ };
+
+ CommandOptions m_options;
+
+ Options *GetOptions() override { return &m_options; }
+
public:
- CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "type category disable",
+ CommandObjectTypeCategoryDisable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "type category disable",
"Disable a category as a source of formatters.",
nullptr),
- m_options(interpreter)
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlus;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
- }
+ m_options() {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
+
+ type_arg.push_back(type_style_arg);
- ~CommandObjectTypeCategoryDisable() override = default;
+ m_arguments.push_back(type_arg);
+ }
+
+ ~CommandObjectTypeCategoryDisable() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1 &&
- m_options.m_language == lldb::eLanguageTypeUnknown)
- {
- result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
- {
- DataVisualization::Categories::DisableStar();
- }
- else if (argc > 0)
- {
- // the order is not relevant here
- for (int i = argc - 1; i >= 0; i--)
- {
- const char* typeA = command.GetArgumentAtIndex(i);
- ConstString typeCS(typeA);
-
- if (!typeCS)
- {
- result.AppendError("empty category name not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- DataVisualization::Categories::Disable(typeCS);
- }
- }
-
- if (m_options.m_language != lldb::eLanguageTypeUnknown)
- DataVisualization::Categories::Disable(m_options.m_language);
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return result.Succeeded();
+ if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
+ result.AppendErrorWithFormat("%s takes arguments and/or a language",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-};
-OptionDefinition
-CommandObjectTypeCategoryDisable::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Enable the category for this language."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
+ DataVisualization::Categories::DisableStar();
+ } else if (argc > 0) {
+ // the order is not relevant here
+ for (int i = argc - 1; i >= 0; i--) {
+ const char *typeA = command.GetArgumentAtIndex(i);
+ ConstString typeCS(typeA);
+
+ if (!typeCS) {
+ result.AppendError("empty category name not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ DataVisualization::Categories::Disable(typeCS);
+ }
+ }
+
+ if (m_options.m_language != lldb::eLanguageTypeUnknown)
+ DataVisualization::Categories::Disable(m_options.m_language);
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryList
//-------------------------------------------------------------------------
-class CommandObjectTypeCategoryList : public CommandObjectParsed
-{
+class CommandObjectTypeCategoryList : public CommandObjectParsed {
public:
- CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "type category list",
+ CommandObjectTypeCategoryList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "type category list",
"Provide a list of all existing categories.",
- nullptr)
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatOptional;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
- }
+ nullptr) {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatOptional;
+
+ type_arg.push_back(type_style_arg);
- ~CommandObjectTypeCategoryList() override = default;
+ m_arguments.push_back(type_arg);
+ }
+
+ ~CommandObjectTypeCategoryList() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- std::unique_ptr<RegularExpression> regex;
-
- if (argc == 1)
- {
- regex.reset(new RegularExpression());
- const char* arg = command.GetArgumentAtIndex(0);
- if (!regex->Compile(arg))
- {
- result.AppendErrorWithFormat("syntax error in category regular expression '%s'", arg);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- else if (argc != 0)
- {
- result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- DataVisualization::Categories::ForEach( [&regex, &result] (const lldb::TypeCategoryImplSP& category_sp) -> bool {
- if (regex)
- {
- bool escape = true;
- if (0 == strcmp(category_sp->GetName(), regex->GetText()))
- {
- escape = false;
- }
- else if (regex->Execute(category_sp->GetName()))
- {
- escape = false;
- }
-
- if (escape)
- return true;
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+
+ std::unique_ptr<RegularExpression> regex;
+
+ if (argc == 1) {
+ regex.reset(new RegularExpression());
+ const char *arg = command.GetArgumentAtIndex(0);
+ if (!regex->Compile(llvm::StringRef::withNullAsEmpty(arg))) {
+ result.AppendErrorWithFormat(
+ "syntax error in category regular expression '%s'", arg);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else if (argc != 0) {
+ result.AppendErrorWithFormat("%s takes 0 or one arg.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ DataVisualization::Categories::ForEach(
+ [&regex, &result](const lldb::TypeCategoryImplSP &category_sp) -> bool {
+ if (regex) {
+ bool escape = true;
+ if (regex->GetText() == category_sp->GetName()) {
+ escape = false;
+ } else if (regex->Execute(llvm::StringRef::withNullAsEmpty(
+ category_sp->GetName()))) {
+ escape = false;
}
-
- result.GetOutputStream().Printf("Category: %s\n", category_sp->GetDescription().c_str());
-
- return true;
+
+ if (escape)
+ return true;
+ }
+
+ result.GetOutputStream().Printf(
+ "Category: %s\n", category_sp->GetDescription().c_str());
+
+ return true;
});
-
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return result.Succeeded();
- }
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectTypeFilterList
//-------------------------------------------------------------------------
-class CommandObjectTypeFilterList : public CommandObjectTypeFormatterList<TypeFilterImpl>
-{
+class CommandObjectTypeFilterList
+ : public CommandObjectTypeFormatterList<TypeFilterImpl> {
public:
- CommandObjectTypeFilterList (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterList(interpreter,
- "type filter list",
- "Show a list of current filters.")
- {
- }
+ CommandObjectTypeFilterList(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterList(interpreter, "type filter list",
+ "Show a list of current filters.") {}
};
#ifndef LLDB_DISABLE_PYTHON
@@ -2651,15 +2264,13 @@ public:
// CommandObjectTypeSynthList
//-------------------------------------------------------------------------
-class CommandObjectTypeSynthList : public CommandObjectTypeFormatterList<SyntheticChildren>
-{
+class CommandObjectTypeSynthList
+ : public CommandObjectTypeFormatterList<SyntheticChildren> {
public:
- CommandObjectTypeSynthList (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterList(interpreter,
- "type synthetic list",
- "Show a list of current synthetic providers.")
- {
- }
+ CommandObjectTypeSynthList(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterList(
+ interpreter, "type synthetic list",
+ "Show a list of current synthetic providers.") {}
};
#endif // LLDB_DISABLE_PYTHON
@@ -2668,18 +2279,15 @@ public:
// CommandObjectTypeFilterDelete
//-------------------------------------------------------------------------
-class CommandObjectTypeFilterDelete : public CommandObjectTypeFormatterDelete
-{
+class CommandObjectTypeFilterDelete : public CommandObjectTypeFormatterDelete {
public:
- CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterDelete (interpreter,
- eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
- "type filter delete",
- "Delete an existing filter for a type.")
- {
- }
+ CommandObjectTypeFilterDelete(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterDelete(
+ interpreter,
+ eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
+ "type filter delete", "Delete an existing filter for a type.") {}
- ~CommandObjectTypeFilterDelete() override = default;
+ ~CommandObjectTypeFilterDelete() override = default;
};
#ifndef LLDB_DISABLE_PYTHON
@@ -2688,18 +2296,16 @@ public:
// CommandObjectTypeSynthDelete
//-------------------------------------------------------------------------
-class CommandObjectTypeSynthDelete : public CommandObjectTypeFormatterDelete
-{
+class CommandObjectTypeSynthDelete : public CommandObjectTypeFormatterDelete {
public:
- CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterDelete (interpreter,
- eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
- "type synthetic delete",
- "Delete an existing synthetic provider for a type.")
- {
- }
-
- ~CommandObjectTypeSynthDelete() override = default;
+ CommandObjectTypeSynthDelete(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterDelete(
+ interpreter,
+ eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
+ "type synthetic delete",
+ "Delete an existing synthetic provider for a type.") {}
+
+ ~CommandObjectTypeSynthDelete() override = default;
};
#endif // LLDB_DISABLE_PYTHON
@@ -2708,16 +2314,13 @@ public:
// CommandObjectTypeFilterClear
//-------------------------------------------------------------------------
-class CommandObjectTypeFilterClear : public CommandObjectTypeFormatterClear
-{
+class CommandObjectTypeFilterClear : public CommandObjectTypeFormatterClear {
public:
- CommandObjectTypeFilterClear (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterClear (interpreter,
- eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
- "type filter clear",
- "Delete all existing filter.")
- {
- }
+ CommandObjectTypeFilterClear(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterClear(
+ interpreter,
+ eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
+ "type filter clear", "Delete all existing filter.") {}
};
#ifndef LLDB_DISABLE_PYTHON
@@ -2725,371 +2328,321 @@ public:
// CommandObjectTypeSynthClear
//-------------------------------------------------------------------------
-class CommandObjectTypeSynthClear : public CommandObjectTypeFormatterClear
-{
+class CommandObjectTypeSynthClear : public CommandObjectTypeFormatterClear {
public:
- CommandObjectTypeSynthClear (CommandInterpreter &interpreter) :
- CommandObjectTypeFormatterClear (interpreter,
- eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
- "type synthetic clear",
- "Delete all existing synthetic providers.")
- {
- }
+ CommandObjectTypeSynthClear(CommandInterpreter &interpreter)
+ : CommandObjectTypeFormatterClear(
+ interpreter,
+ eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
+ "type synthetic clear",
+ "Delete all existing synthetic providers.") {}
};
-bool
-CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result)
-{
- SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers,
- m_options.m_skip_references,
- m_options.m_cascade,
- m_options.m_regex,
- m_options.m_category);
-
- const size_t argc = command.GetArgumentCount();
-
- for (size_t i = 0; i < argc; i++)
- {
- const char* typeA = command.GetArgumentAtIndex(i);
- if (typeA && *typeA)
- options->m_target_types << typeA;
- else
- {
- result.AppendError("empty typenames not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
-
- m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
- *this, // IOHandlerDelegate
- true, // Run IOHandler in async mode
- options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
+bool CommandObjectTypeSynthAdd::Execute_HandwritePython(
+ Args &command, CommandReturnObject &result) {
+ SynthAddOptions *options = new SynthAddOptions(
+ m_options.m_skip_pointers, m_options.m_skip_references,
+ m_options.m_cascade, m_options.m_regex, m_options.m_category);
+
+ for (auto &entry : command.entries()) {
+ if (entry.ref.empty()) {
+ result.AppendError("empty typenames not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ options->m_target_types << entry.ref;
+ }
+
+ m_interpreter.GetPythonCommandsFromIOHandler(
+ " ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ options); // Baton for the "io_handler" that will be passed back into our
+ // IOHandlerDelegate functions
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
}
-bool
-CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result)
-{
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1)
- {
- result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (m_options.m_class_name.empty() && !m_options.m_input_python)
- {
- result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
+bool CommandObjectTypeSynthAdd::Execute_PythonClass(
+ Args &command, CommandReturnObject &result) {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1) {
+ result.AppendErrorWithFormat("%s takes one or more args.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_options.m_class_name.empty() && !m_options.m_input_python) {
+ result.AppendErrorWithFormat("%s needs either a Python class name or -P to "
+ "directly input Python code.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ SyntheticChildrenSP entry;
+
+ ScriptedSyntheticChildren *impl = new ScriptedSyntheticChildren(
+ SyntheticChildren::Flags()
+ .SetCascades(m_options.m_cascade)
+ .SetSkipPointers(m_options.m_skip_pointers)
+ .SetSkipReferences(m_options.m_skip_references),
+ m_options.m_class_name.c_str());
+
+ entry.reset(impl);
+
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+
+ if (interpreter &&
+ !interpreter->CheckObjectExists(impl->GetPythonClassName()))
+ result.AppendWarning("The provided class does not exist - please define it "
+ "before attempting to use this synthetic provider");
+
+ // now I have a valid provider, let's add it to every type
+
+ lldb::TypeCategoryImplSP category;
+ DataVisualization::Categories::GetCategory(
+ ConstString(m_options.m_category.c_str()), category);
+
+ Error error;
+
+ for (auto &arg_entry : command.entries()) {
+ if (arg_entry.ref.empty()) {
+ result.AppendError("empty typenames not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- SyntheticChildrenSP entry;
-
- ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags().
- SetCascades(m_options.m_cascade).
- SetSkipPointers(m_options.m_skip_pointers).
- SetSkipReferences(m_options.m_skip_references),
- m_options.m_class_name.c_str());
-
- entry.reset(impl);
-
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
-
- if (interpreter && !interpreter->CheckObjectExists(impl->GetPythonClassName()))
- result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider");
-
- // now I have a valid provider, let's add it to every type
-
- lldb::TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
-
- Error error;
-
- for (size_t i = 0; i < argc; i++)
- {
- const char* typeA = command.GetArgumentAtIndex(i);
- ConstString typeCS(typeA);
- if (typeCS)
- {
- if (!AddSynth(typeCS,
- entry,
- m_options.m_regex ? eRegexSynth : eRegularSynth,
- m_options.m_category,
- &error))
- {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- result.AppendError("empty typenames not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+
+ ConstString typeCS(arg_entry.ref);
+ if (!AddSynth(typeCS, entry,
+ m_options.m_regex ? eRegexSynth : eRegularSynth,
+ m_options.m_category, &error)) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
}
-
-CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "type synthetic add",
- "Add a new synthetic provider for a type.",
- nullptr),
- IOHandlerDelegateMultiline ("DONE"),
- m_options (interpreter)
-{
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlus;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
+
+CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd(
+ CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "type synthetic add",
+ "Add a new synthetic provider for a type.", nullptr),
+ IOHandlerDelegateMultiline("DONE"), m_options() {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
+
+ type_arg.push_back(type_style_arg);
+
+ m_arguments.push_back(type_arg);
}
-bool
-CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
- SyntheticChildrenSP entry,
- SynthFormatType type,
- std::string category_name,
- Error* error)
-{
- lldb::TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
-
- if (type == eRegularSynth)
- {
- if (FixArrayTypeNameWithRegex (type_name))
- type = eRegexSynth;
- }
-
- if (category->AnyMatches(type_name,
- eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
- false))
- {
- if (error)
- error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString());
- return false;
- }
-
- if (type == eRegexSynth)
- {
- RegularExpressionSP typeRX(new RegularExpression());
- if (!typeRX->Compile(type_name.GetCString()))
- {
- if (error)
- error->SetErrorString("regex format error (maybe this is not really a regex?)");
- return false;
- }
-
- category->GetRegexTypeSyntheticsContainer()->Delete(type_name);
- category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry);
-
- return true;
- }
- else
- {
- category->GetTypeSyntheticsContainer()->Add(type_name, entry);
- return true;
+bool CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
+ SyntheticChildrenSP entry,
+ SynthFormatType type,
+ std::string category_name,
+ Error *error) {
+ lldb::TypeCategoryImplSP category;
+ DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()),
+ category);
+
+ if (type == eRegularSynth) {
+ if (FixArrayTypeNameWithRegex(type_name))
+ type = eRegexSynth;
+ }
+
+ if (category->AnyMatches(type_name, eFormatCategoryItemFilter |
+ eFormatCategoryItemRegexFilter,
+ false)) {
+ if (error)
+ error->SetErrorStringWithFormat("cannot add synthetic for type %s when "
+ "filter is defined in same category!",
+ type_name.AsCString());
+ return false;
+ }
+
+ if (type == eRegexSynth) {
+ RegularExpressionSP typeRX(new RegularExpression());
+ if (!typeRX->Compile(type_name.GetStringRef())) {
+ if (error)
+ error->SetErrorString(
+ "regex format error (maybe this is not really a regex?)");
+ return false;
}
-}
-OptionDefinition
-CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
- { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."},
- { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."},
- { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
-};
+ category->GetRegexTypeSyntheticsContainer()->Delete(type_name);
+ category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry);
+
+ return true;
+ } else {
+ category->GetTypeSyntheticsContainer()->Add(type_name, entry);
+ return true;
+ }
+}
#endif // LLDB_DISABLE_PYTHON
-class CommandObjectTypeFilterAdd : public CommandObjectParsed
-{
+static OptionDefinition g_type_filter_add_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains." },
+ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." },
+ { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects." },
+ { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one." },
+ { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view." },
+ { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions." }
+ // clang-format on
+};
+
+class CommandObjectTypeFilterAdd : public CommandObjectParsed {
private:
- class CommandOptions : public Options
- {
- typedef std::vector<std::string> option_vector;
+ class CommandOptions : public Options {
+ typedef std::vector<std::string> option_vector;
+
+ public:
+ CommandOptions() : Options() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ bool success;
+
+ switch (short_option) {
+ case 'C':
+ m_cascade = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid value for cascade: %s",
+ option_arg.str().c_str());
+ break;
+ case 'c':
+ m_expr_paths.push_back(option_arg);
+ has_child_list = true;
+ break;
+ case 'p':
+ m_skip_pointers = true;
+ break;
+ case 'r':
+ m_skip_references = true;
+ break;
+ case 'w':
+ m_category = std::string(option_arg);
+ break;
+ case 'x':
+ m_regex = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_cascade = true;
+ m_skip_pointers = false;
+ m_skip_references = false;
+ m_category = "default";
+ m_expr_paths.clear();
+ has_child_list = false;
+ m_regex = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_type_filter_add_options);
+ }
+
+ // Instance variables to hold the values for command options.
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
+ bool m_cascade;
+ bool m_skip_references;
+ bool m_skip_pointers;
+ bool m_input_python;
+ option_vector m_expr_paths;
+ std::string m_category;
+ bool has_child_list;
+ bool m_regex;
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
- bool success;
-
- switch (short_option)
- {
- case 'C':
- m_cascade = Args::StringToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
- break;
- case 'c':
- m_expr_paths.push_back(option_arg);
- has_child_list = true;
- break;
- case 'p':
- m_skip_pointers = true;
- break;
- case 'r':
- m_skip_references = true;
- break;
- case 'w':
- m_category = std::string(option_arg);
- break;
- case 'x':
- m_regex = true;
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_cascade = true;
- m_skip_pointers = false;
- m_skip_references = false;
- m_category = "default";
- m_expr_paths.clear();
- has_child_list = false;
- m_regex = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool m_cascade;
- bool m_skip_references;
- bool m_skip_pointers;
- bool m_input_python;
- option_vector m_expr_paths;
- std::string m_category;
- bool has_child_list;
- bool m_regex;
-
- typedef option_vector::iterator ExpressionPathsIterator;
- };
-
- CommandOptions m_options;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ typedef option_vector::iterator ExpressionPathsIterator;
+ };
+
+ CommandOptions m_options;
+
+ Options *GetOptions() override { return &m_options; }
+
+ enum FilterFormatType { eRegularFilter, eRegexFilter };
+
+ bool AddFilter(ConstString type_name, TypeFilterImplSP entry,
+ FilterFormatType type, std::string category_name,
+ Error *error) {
+ lldb::TypeCategoryImplSP category;
+ DataVisualization::Categories::GetCategory(
+ ConstString(category_name.c_str()), category);
+
+ if (type == eRegularFilter) {
+ if (FixArrayTypeNameWithRegex(type_name))
+ type = eRegexFilter;
}
-
- enum FilterFormatType
- {
- eRegularFilter,
- eRegexFilter
- };
-
- bool
- AddFilter(ConstString type_name,
- TypeFilterImplSP entry,
- FilterFormatType type,
- std::string category_name,
- Error* error)
- {
- lldb::TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
-
- if (type == eRegularFilter)
- {
- if (FixArrayTypeNameWithRegex (type_name))
- type = eRegexFilter;
- }
-
- if (category->AnyMatches(type_name,
- eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
- false))
- {
- if (error)
- error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString());
- return false;
- }
-
- if (type == eRegexFilter)
- {
- RegularExpressionSP typeRX(new RegularExpression());
- if (!typeRX->Compile(type_name.GetCString()))
- {
- if (error)
- error->SetErrorString("regex format error (maybe this is not really a regex?)");
- return false;
- }
-
- category->GetRegexTypeFiltersContainer()->Delete(type_name);
- category->GetRegexTypeFiltersContainer()->Add(typeRX, entry);
-
- return true;
- }
- else
- {
- category->GetTypeFiltersContainer()->Add(type_name, entry);
- return true;
- }
+
+ if (category->AnyMatches(type_name, eFormatCategoryItemSynth |
+ eFormatCategoryItemRegexSynth,
+ false)) {
+ if (error)
+ error->SetErrorStringWithFormat("cannot add filter for type %s when "
+ "synthetic is defined in same "
+ "category!",
+ type_name.AsCString());
+ return false;
}
+ if (type == eRegexFilter) {
+ RegularExpressionSP typeRX(new RegularExpression());
+ if (!typeRX->Compile(type_name.GetStringRef())) {
+ if (error)
+ error->SetErrorString(
+ "regex format error (maybe this is not really a regex?)");
+ return false;
+ }
+
+ category->GetRegexTypeFiltersContainer()->Delete(type_name);
+ category->GetRegexTypeFiltersContainer()->Add(typeRX, entry);
+
+ return true;
+ } else {
+ category->GetTypeFiltersContainer()->Add(type_name, entry);
+ return true;
+ }
+ }
+
public:
- CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "type filter add",
- "Add a new filter for a type.",
- nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlus;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
-
- SetHelpLong(
-R"(
+ CommandObjectTypeFilterAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "type filter add",
+ "Add a new filter for a type.", nullptr),
+ m_options() {
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
+
+ type_arg.push_back(type_style_arg);
+
+ m_arguments.push_back(type_arg);
+
+ SetHelpLong(
+ R"(
The following examples of 'type filter add' refer to this code snippet for context:
class Foo {
@@ -3110,563 +2663,540 @@ Adding a simple filter:
(lldb) type filter add --child a --child g Foo
(lldb) frame variable my_foo
-)" "Produces output where only a and g are displayed. Other children of my_foo \
-(b, c, d, e, f, h and i) are available by asking for them explicitly:" R"(
+)"
+ "Produces output where only a and g are displayed. Other children of my_foo \
+(b, c, d, e, f, h and i) are available by asking for them explicitly:"
+ R"(
(lldb) frame variable my_foo.b my_foo.c my_foo.i
-)" "The formatting option --raw on frame variable bypasses the filter, showing \
-all children of my_foo as if no filter was defined:" R"(
+)"
+ "The formatting option --raw on frame variable bypasses the filter, showing \
+all children of my_foo as if no filter was defined:"
+ R"(
-(lldb) frame variable my_foo --raw)"
- );
- }
+(lldb) frame variable my_foo --raw)");
+ }
- ~CommandObjectTypeFilterAdd() override = default;
+ ~CommandObjectTypeFilterAdd() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1)
- {
- result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (m_options.m_expr_paths.empty())
- {
- result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- TypeFilterImplSP entry(new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade).
- SetSkipPointers(m_options.m_skip_pointers).
- SetSkipReferences(m_options.m_skip_references)));
-
- // go through the expression paths
- CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
-
- for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
- entry->AddExpressionPath(*begin);
-
-
- // now I have a valid provider, let's add it to every type
-
- lldb::TypeCategoryImplSP category;
- DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
-
- Error error;
-
- WarnOnPotentialUnquotedUnsignedType(command, result);
-
- for (size_t i = 0; i < argc; i++)
- {
- const char* typeA = command.GetArgumentAtIndex(i);
- ConstString typeCS(typeA);
- if (typeCS)
- {
- if (!AddFilter(typeCS,
- entry,
- m_options.m_regex ? eRegexFilter : eRegularFilter,
- m_options.m_category,
- &error))
- {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- else
- {
- result.AppendError("empty typenames not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
-
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1) {
+ result.AppendErrorWithFormat("%s takes one or more args.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_options.m_expr_paths.empty()) {
+ result.AppendErrorWithFormat("%s needs one or more children.\n",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ TypeFilterImplSP entry(new TypeFilterImpl(
+ SyntheticChildren::Flags()
+ .SetCascades(m_options.m_cascade)
+ .SetSkipPointers(m_options.m_skip_pointers)
+ .SetSkipReferences(m_options.m_skip_references)));
+
+ // go through the expression paths
+ CommandOptions::ExpressionPathsIterator begin,
+ end = m_options.m_expr_paths.end();
+
+ for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
+ entry->AddExpressionPath(*begin);
+
+ // now I have a valid provider, let's add it to every type
+
+ lldb::TypeCategoryImplSP category;
+ DataVisualization::Categories::GetCategory(
+ ConstString(m_options.m_category.c_str()), category);
+
+ Error error;
+
+ WarnOnPotentialUnquotedUnsignedType(command, result);
+
+ for (auto &arg_entry : command.entries()) {
+ if (arg_entry.ref.empty()) {
+ result.AppendError("empty typenames not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ConstString typeCS(arg_entry.ref);
+ if (!AddFilter(typeCS, entry,
+ m_options.m_regex ? eRegexFilter : eRegularFilter,
+ m_options.m_category, &error)) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
-};
-OptionDefinition
-CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
- { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."},
- { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions."},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
};
//----------------------------------------------------------------------
// "type lookup"
//----------------------------------------------------------------------
-class CommandObjectTypeLookup : public CommandObjectRaw
-{
+static OptionDefinition g_type_lookup_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "show-help", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display available help for types" },
+ { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Which language's types should the search scope be" }
+ // clang-format on
+};
+
+class CommandObjectTypeLookup : public CommandObjectRaw {
protected:
- // this function is allowed to do a more aggressive job at guessing languages than the expression parser
- // is comfortable with - so leave the original call alone and add one that is specific to type lookup
- lldb::LanguageType
- GuessLanguage (StackFrame *frame)
- {
- lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
-
- if (!frame)
- return lang_type;
-
- lang_type = frame->GuessLanguage();
- if (lang_type != lldb::eLanguageTypeUnknown)
- return lang_type;
-
- Symbol *s = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
- if (s)
- lang_type = s->GetMangled().GuessLanguage();
-
- return lang_type;
- }
-
- class CommandOptions : public OptionGroup
- {
- public:
- CommandOptions () :
- OptionGroup(),
- m_show_help(false),
- m_language(eLanguageTypeUnknown)
- {}
-
- ~CommandOptions() override = default;
-
- uint32_t
- GetNumDefinitions () override
- {
- return 3;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- Error
- SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_value) override
- {
- Error error;
-
- const int short_option = g_option_table[option_idx].short_option;
-
- switch (short_option)
- {
- case 'h':
- m_show_help = true;
- break;
-
- case 'l':
- m_language = Language::GetLanguageTypeFromString(option_value);
- break;
-
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting (CommandInterpreter &interpreter) override
- {
- m_show_help = false;
- m_language = eLanguageTypeUnknown;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
- bool m_show_help;
- lldb::LanguageType m_language;
- };
-
- OptionGroupOptions m_option_group;
- CommandOptions m_command_options;
-
-public:
- CommandObjectTypeLookup (CommandInterpreter &interpreter) :
- CommandObjectRaw (interpreter,
- "type lookup",
- "Lookup types and declarations in the current target, following language-specific naming conventions.",
- "type lookup <type-specifier>",
- eCommandRequiresTarget),
- m_option_group(interpreter),
- m_command_options()
- {
- m_option_group.Append(&m_command_options);
- m_option_group.Finalize();
+ // this function is allowed to do a more aggressive job at guessing languages
+ // than the expression parser
+ // is comfortable with - so leave the original call alone and add one that is
+ // specific to type lookup
+ lldb::LanguageType GuessLanguage(StackFrame *frame) {
+ lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
+
+ if (!frame)
+ return lang_type;
+
+ lang_type = frame->GuessLanguage();
+ if (lang_type != lldb::eLanguageTypeUnknown)
+ return lang_type;
+
+ Symbol *s = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
+ if (s)
+ lang_type = s->GetMangled().GuessLanguage();
+
+ return lang_type;
+ }
+
+ class CommandOptions : public OptionGroup {
+ public:
+ CommandOptions()
+ : OptionGroup(), m_show_help(false), m_language(eLanguageTypeUnknown) {}
+
+ ~CommandOptions() override = default;
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_type_lookup_options);
}
- ~CommandObjectTypeLookup() override = default;
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
+ ExecutionContext *execution_context) override {
+ Error error;
- Options *
- GetOptions () override
- {
- return &m_option_group;
+ const int short_option = g_type_lookup_options[option_idx].short_option;
+
+ switch (short_option) {
+ case 'h':
+ m_show_help = true;
+ break;
+
+ case 'l':
+ m_language = Language::GetLanguageTypeFromString(option_value);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
-
- const char*
- GetHelpLong () override
- {
- if (m_cmd_help_long.empty())
- {
- StreamString stream;
- // FIXME: hardcoding languages is not good
- lldb::LanguageType languages[] = {eLanguageTypeObjC,eLanguageTypeC_plus_plus};
-
- for(const auto lang_type : languages)
- {
- if (auto language = Language::FindPlugin(lang_type))
- {
- if (const char* help = language->GetLanguageSpecificTypeLookupHelp())
- {
- stream.Printf("%s\n", help);
- }
- }
- }
-
- if (stream.GetData())
- m_cmd_help_long.assign(stream.GetString());
- }
- return this->CommandObject::GetHelpLong();
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_show_help = false;
+ m_language = eLanguageTypeUnknown;
}
-
- bool
- DoExecute (const char *raw_command_line, CommandReturnObject &result) override
- {
- if (!raw_command_line || !raw_command_line[0])
- {
- result.SetError("type lookup cannot be invoked without a type name as argument");
- return false;
- }
-
- m_option_group.NotifyOptionParsingStarting();
-
- const char * name_of_type = nullptr;
-
- if (raw_command_line[0] == '-')
- {
- // We have some options and these options MUST end with --.
- const char *end_options = nullptr;
- const char *s = raw_command_line;
- while (s && s[0])
- {
- end_options = ::strstr (s, "--");
- if (end_options)
- {
- end_options += 2; // Get past the "--"
- if (::isspace (end_options[0]))
- {
- name_of_type = end_options;
- while (::isspace (*name_of_type))
- ++name_of_type;
- break;
- }
- }
- s = end_options;
- }
-
- if (end_options)
- {
- Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
- if (!ParseOptions (args, result))
- return false;
-
- Error error (m_option_group.NotifyOptionParsingFinished());
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
- if (nullptr == name_of_type)
- name_of_type = raw_command_line;
-
- TargetSP target_sp(GetCommandInterpreter().GetDebugger().GetSelectedTarget());
- const bool fill_all_in = true;
- ExecutionContext exe_ctx(target_sp.get(), fill_all_in);
- ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
-
- bool any_found = false;
-
- std::vector<Language*> languages;
-
- bool is_global_search = false;
-
- if ( (is_global_search = (m_command_options.m_language == eLanguageTypeUnknown)) )
- {
- // FIXME: hardcoding languages is not good
- languages.push_back(Language::FindPlugin(eLanguageTypeObjC));
- languages.push_back(Language::FindPlugin(eLanguageTypeC_plus_plus));
- }
- else
- {
- languages.push_back(Language::FindPlugin(m_command_options.m_language));
- }
-
- // This is not the most efficient way to do this, but we support very few languages
- // so the cost of the sort is going to be dwarfed by the actual lookup anyway
- if (StackFrame* frame = m_exe_ctx.GetFramePtr())
- {
- LanguageType lang = GuessLanguage(frame);
- if (lang != eLanguageTypeUnknown)
- {
- std::sort(languages.begin(),
- languages.end(),
- [lang] (Language* lang1,
- Language* lang2) -> bool {
- if (!lang1 || !lang2) return false;
- LanguageType lt1 = lang1->GetLanguageType();
- LanguageType lt2 = lang2->GetLanguageType();
- if (lt1 == lang) return true; // make the selected frame's language come first
- if (lt2 == lang) return false; // make the selected frame's language come first
- return (lt1 < lt2); // normal comparison otherwise
- });
- }
- }
-
- for (Language* language : languages)
- {
- if (!language)
- continue;
-
- if (auto scavenger = language->GetTypeScavenger())
- {
- Language::TypeScavenger::ResultSet search_results;
- if (scavenger->Find(best_scope, name_of_type, search_results) > 0)
- {
- for (const auto& search_result : search_results)
- {
- if (search_result && search_result->IsValid())
- {
- any_found = true;
- search_result->DumpToStream(result.GetOutputStream(), this->m_command_options.m_show_help);
- }
- }
- }
- // this is "type lookup SomeName" and we did find a match, so get out
- if (any_found && is_global_search)
- break;
- }
- }
-
- if (!any_found)
- result.AppendMessageWithFormat("no type was found matching '%s'\n", name_of_type);
-
- result.SetStatus (any_found ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusSuccessFinishNoResult);
- return true;
+
+ // Options table: Required for subclasses of Options.
+
+ bool m_show_help;
+ lldb::LanguageType m_language;
+ };
+
+ OptionGroupOptions m_option_group;
+ CommandOptions m_command_options;
+
+public:
+ CommandObjectTypeLookup(CommandInterpreter &interpreter)
+ : CommandObjectRaw(interpreter, "type lookup",
+ "Lookup types and declarations in the current target, "
+ "following language-specific naming conventions.",
+ "type lookup <type-specifier>",
+ eCommandRequiresTarget),
+ m_option_group(), m_command_options() {
+ m_option_group.Append(&m_command_options);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectTypeLookup() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
+
+ llvm::StringRef GetHelpLong() override {
+ if (!m_cmd_help_long.empty())
+ return m_cmd_help_long;
+
+ StreamString stream;
+ // FIXME: hardcoding languages is not good
+ lldb::LanguageType languages[] = {eLanguageTypeObjC,
+ eLanguageTypeC_plus_plus};
+
+ for (const auto lang_type : languages) {
+ if (auto language = Language::FindPlugin(lang_type)) {
+ if (const char *help = language->GetLanguageSpecificTypeLookupHelp()) {
+ stream.Printf("%s\n", help);
+ }
+ }
+ }
+
+ m_cmd_help_long = stream.GetString();
+ return m_cmd_help_long;
+ }
+
+ bool DoExecute(const char *raw_command_line,
+ CommandReturnObject &result) override {
+ if (!raw_command_line || !raw_command_line[0]) {
+ result.SetError(
+ "type lookup cannot be invoked without a type name as argument");
+ return false;
+ }
+
+ auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
+ m_option_group.NotifyOptionParsingStarting(&exe_ctx);
+
+ const char *name_of_type = nullptr;
+
+ if (raw_command_line[0] == '-') {
+ // We have some options and these options MUST end with --.
+ const char *end_options = nullptr;
+ const char *s = raw_command_line;
+ while (s && s[0]) {
+ end_options = ::strstr(s, "--");
+ if (end_options) {
+ end_options += 2; // Get past the "--"
+ if (::isspace(end_options[0])) {
+ name_of_type = end_options;
+ while (::isspace(*name_of_type))
+ ++name_of_type;
+ break;
+ }
+ }
+ s = end_options;
+ }
+
+ if (end_options) {
+ Args args(
+ llvm::StringRef(raw_command_line, end_options - raw_command_line));
+ if (!ParseOptions(args, result))
+ return false;
+
+ Error error(m_option_group.NotifyOptionParsingFinished(&exe_ctx));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ }
+ if (nullptr == name_of_type)
+ name_of_type = raw_command_line;
+
+ // TargetSP
+ // target_sp(GetCommandInterpreter().GetDebugger().GetSelectedTarget());
+ // const bool fill_all_in = true;
+ // ExecutionContext exe_ctx(target_sp.get(), fill_all_in);
+ ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
+
+ bool any_found = false;
+
+ std::vector<Language *> languages;
+
+ bool is_global_search = false;
+ LanguageType guessed_language = lldb::eLanguageTypeUnknown;
+
+ if ((is_global_search =
+ (m_command_options.m_language == eLanguageTypeUnknown))) {
+ // FIXME: hardcoding languages is not good
+ languages.push_back(Language::FindPlugin(eLanguageTypeObjC));
+ languages.push_back(Language::FindPlugin(eLanguageTypeC_plus_plus));
+ } else {
+ languages.push_back(Language::FindPlugin(m_command_options.m_language));
+ }
+
+ // This is not the most efficient way to do this, but we support very few
+ // languages
+ // so the cost of the sort is going to be dwarfed by the actual lookup
+ // anyway
+ if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
+ guessed_language = GuessLanguage(frame);
+ if (guessed_language != eLanguageTypeUnknown) {
+ std::sort(
+ languages.begin(), languages.end(),
+ [guessed_language](Language *lang1, Language *lang2) -> bool {
+ if (!lang1 || !lang2)
+ return false;
+ LanguageType lt1 = lang1->GetLanguageType();
+ LanguageType lt2 = lang2->GetLanguageType();
+ if (lt1 == guessed_language)
+ return true; // make the selected frame's language come first
+ if (lt2 == guessed_language)
+ return false; // make the selected frame's language come first
+ return (lt1 < lt2); // normal comparison otherwise
+ });
+ }
}
-};
-OptionDefinition
-CommandObjectTypeLookup::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, false, "show-help", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display available help for types"},
- { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Which language's types should the search scope be"},
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+ bool is_first_language = true;
+
+ for (Language *language : languages) {
+ if (!language)
+ continue;
+
+ if (auto scavenger = language->GetTypeScavenger()) {
+ Language::TypeScavenger::ResultSet search_results;
+ if (scavenger->Find(best_scope, name_of_type, search_results) > 0) {
+ for (const auto &search_result : search_results) {
+ if (search_result && search_result->IsValid()) {
+ any_found = true;
+ search_result->DumpToStream(result.GetOutputStream(),
+ this->m_command_options.m_show_help);
+ }
+ }
+ }
+ }
+ // this is "type lookup SomeName" and we did find a match, so get out
+ if (any_found && is_global_search)
+ break;
+ else if (is_first_language && is_global_search &&
+ guessed_language != lldb::eLanguageTypeUnknown) {
+ is_first_language = false;
+ result.GetOutputStream().Printf(
+ "no type was found in the current language %s matching '%s'; "
+ "performing a global search across all languages\n",
+ Language::GetNameForLanguageType(guessed_language), name_of_type);
+ }
+ }
+
+ if (!any_found)
+ result.AppendMessageWithFormat("no type was found matching '%s'\n",
+ name_of_type);
+
+ result.SetStatus(any_found ? lldb::eReturnStatusSuccessFinishResult
+ : lldb::eReturnStatusSuccessFinishNoResult);
+ return true;
+ }
};
template <typename FormatterType>
-class CommandObjectFormatterInfo : public CommandObjectRaw
-{
+class CommandObjectFormatterInfo : public CommandObjectRaw {
public:
- typedef std::function<typename FormatterType::SharedPointer(ValueObject&)> DiscoveryFunction;
- CommandObjectFormatterInfo (CommandInterpreter &interpreter,
- const char* formatter_name,
- DiscoveryFunction discovery_func) :
- CommandObjectRaw(interpreter,
- nullptr,
- nullptr,
- nullptr,
- eCommandRequiresFrame),
- m_formatter_name(formatter_name ? formatter_name : ""),
- m_discovery_function(discovery_func)
- {
- StreamString name;
- name.Printf("type %s info", formatter_name);
- SetCommandName(name.GetData());
- StreamString help;
- help.Printf("This command evaluates the provided expression and shows which %s is applied to the resulting value (if any).", formatter_name);
- SetHelp(help.GetData());
- StreamString syntax;
- syntax.Printf("type %s info <expr>", formatter_name);
- SetSyntax(syntax.GetData());
- }
-
- ~CommandObjectFormatterInfo() override = default;
+ typedef std::function<typename FormatterType::SharedPointer(ValueObject &)>
+ DiscoveryFunction;
+ CommandObjectFormatterInfo(CommandInterpreter &interpreter,
+ const char *formatter_name,
+ DiscoveryFunction discovery_func)
+ : CommandObjectRaw(interpreter, "", "", "",
+ eCommandRequiresFrame),
+ m_formatter_name(formatter_name ? formatter_name : ""),
+ m_discovery_function(discovery_func) {
+ StreamString name;
+ name.Printf("type %s info", formatter_name);
+ SetCommandName(name.GetString());
+ StreamString help;
+ help.Printf("This command evaluates the provided expression and shows "
+ "which %s is applied to the resulting value (if any).",
+ formatter_name);
+ SetHelp(help.GetString());
+ StreamString syntax;
+ syntax.Printf("type %s info <expr>", formatter_name);
+ SetSyntax(syntax.GetString());
+ }
+
+ ~CommandObjectFormatterInfo() override = default;
protected:
- bool
- DoExecute (const char *command, CommandReturnObject &result) override
- {
- TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
- Thread *thread = GetDefaultThread();
- if (!thread)
- {
- result.AppendError("no default thread");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
-
- StackFrameSP frame_sp = thread->GetSelectedFrame();
- ValueObjectSP result_valobj_sp;
- EvaluateExpressionOptions options;
- lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(command, frame_sp.get(), result_valobj_sp, options);
- if (expr_result == eExpressionCompleted && result_valobj_sp)
- {
- result_valobj_sp = result_valobj_sp->GetQualifiedRepresentationIfAvailable(target_sp->GetPreferDynamicValue(), target_sp->GetEnableSyntheticValue());
- typename FormatterType::SharedPointer formatter_sp = m_discovery_function(*result_valobj_sp);
- if (formatter_sp)
- {
- std::string description(formatter_sp->GetDescription());
- result.AppendMessageWithFormat("%s applied to (%s) %s is: %s\n",
- m_formatter_name.c_str(),
- result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
- command,
- description.c_str());
- result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendMessageWithFormat("no %s applies to (%s) %s\n",
- m_formatter_name.c_str(),
- result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
- command);
- result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
- }
- return true;
- }
- else
- {
- result.AppendError("failed to evaluate expression");
- result.SetStatus(lldb::eReturnStatusFailed);
- return false;
- }
- }
+ bool DoExecute(const char *command, CommandReturnObject &result) override {
+ TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
+ Thread *thread = GetDefaultThread();
+ if (!thread) {
+ result.AppendError("no default thread");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+
+ StackFrameSP frame_sp = thread->GetSelectedFrame();
+ ValueObjectSP result_valobj_sp;
+ EvaluateExpressionOptions options;
+ lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(
+ command, frame_sp.get(), result_valobj_sp, options);
+ if (expr_result == eExpressionCompleted && result_valobj_sp) {
+ result_valobj_sp =
+ result_valobj_sp->GetQualifiedRepresentationIfAvailable(
+ target_sp->GetPreferDynamicValue(),
+ target_sp->GetEnableSyntheticValue());
+ typename FormatterType::SharedPointer formatter_sp =
+ m_discovery_function(*result_valobj_sp);
+ if (formatter_sp) {
+ std::string description(formatter_sp->GetDescription());
+ result.AppendMessageWithFormat(
+ "%s applied to (%s) %s is: %s\n", m_formatter_name.c_str(),
+ result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
+ command, description.c_str());
+ result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendMessageWithFormat(
+ "no %s applies to (%s) %s\n", m_formatter_name.c_str(),
+ result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
+ command);
+ result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
+ }
+ return true;
+ } else {
+ result.AppendError("failed to evaluate expression");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+ }
private:
- std::string m_formatter_name;
- DiscoveryFunction m_discovery_function;
+ std::string m_formatter_name;
+ DiscoveryFunction m_discovery_function;
};
-class CommandObjectTypeFormat : public CommandObjectMultiword
-{
+class CommandObjectTypeFormat : public CommandObjectMultiword {
public:
- CommandObjectTypeFormat(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "type format", "Commands for customizing value display formats.",
- "type format [<sub-command-options>] ")
- {
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter)));
- LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFormatList (interpreter)));
- LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<TypeFormatImpl>(interpreter,
- "format",
- [](ValueObject& valobj) -> TypeFormatImpl::SharedPointer {
- return valobj.GetValueFormat();
- })));
- }
-
- ~CommandObjectTypeFormat() override = default;
+ CommandObjectTypeFormat(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "type format",
+ "Commands for customizing value display formats.",
+ "type format [<sub-command-options>] ") {
+ LoadSubCommand(
+ "add", CommandObjectSP(new CommandObjectTypeFormatAdd(interpreter)));
+ LoadSubCommand("clear", CommandObjectSP(
+ new CommandObjectTypeFormatClear(interpreter)));
+ LoadSubCommand("delete", CommandObjectSP(new CommandObjectTypeFormatDelete(
+ interpreter)));
+ LoadSubCommand(
+ "list", CommandObjectSP(new CommandObjectTypeFormatList(interpreter)));
+ LoadSubCommand(
+ "info", CommandObjectSP(new CommandObjectFormatterInfo<TypeFormatImpl>(
+ interpreter, "format",
+ [](ValueObject &valobj) -> TypeFormatImpl::SharedPointer {
+ return valobj.GetValueFormat();
+ })));
+ }
+
+ ~CommandObjectTypeFormat() override = default;
};
#ifndef LLDB_DISABLE_PYTHON
-class CommandObjectTypeSynth : public CommandObjectMultiword
-{
+class CommandObjectTypeSynth : public CommandObjectMultiword {
public:
- CommandObjectTypeSynth(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "type synthetic",
- "Commands for operating on synthetic type representations.",
- "type synthetic [<sub-command-options>] ")
- {
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter)));
- LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSynthClear (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSynthList (interpreter)));
- LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<SyntheticChildren>(interpreter,
- "synthetic",
- [](ValueObject& valobj) -> SyntheticChildren::SharedPointer {
- return valobj.GetSyntheticChildren();
- })));
- }
-
- ~CommandObjectTypeSynth() override = default;
+ CommandObjectTypeSynth(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "type synthetic",
+ "Commands for operating on synthetic type representations.",
+ "type synthetic [<sub-command-options>] ") {
+ LoadSubCommand("add",
+ CommandObjectSP(new CommandObjectTypeSynthAdd(interpreter)));
+ LoadSubCommand(
+ "clear", CommandObjectSP(new CommandObjectTypeSynthClear(interpreter)));
+ LoadSubCommand("delete", CommandObjectSP(new CommandObjectTypeSynthDelete(
+ interpreter)));
+ LoadSubCommand(
+ "list", CommandObjectSP(new CommandObjectTypeSynthList(interpreter)));
+ LoadSubCommand(
+ "info",
+ CommandObjectSP(new CommandObjectFormatterInfo<SyntheticChildren>(
+ interpreter, "synthetic",
+ [](ValueObject &valobj) -> SyntheticChildren::SharedPointer {
+ return valobj.GetSyntheticChildren();
+ })));
+ }
+
+ ~CommandObjectTypeSynth() override = default;
};
#endif // LLDB_DISABLE_PYTHON
-class CommandObjectTypeFilter : public CommandObjectMultiword
-{
+class CommandObjectTypeFilter : public CommandObjectMultiword {
public:
- CommandObjectTypeFilter(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "type filter", "Commands for operating on type filters.",
- "type synthetic [<sub-command-options>] ")
- {
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter)));
- LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFilterClear (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFilterList (interpreter)));
- }
-
- ~CommandObjectTypeFilter() override = default;
+ CommandObjectTypeFilter(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "type filter",
+ "Commands for operating on type filters.",
+ "type synthetic [<sub-command-options>] ") {
+ LoadSubCommand(
+ "add", CommandObjectSP(new CommandObjectTypeFilterAdd(interpreter)));
+ LoadSubCommand("clear", CommandObjectSP(
+ new CommandObjectTypeFilterClear(interpreter)));
+ LoadSubCommand("delete", CommandObjectSP(new CommandObjectTypeFilterDelete(
+ interpreter)));
+ LoadSubCommand(
+ "list", CommandObjectSP(new CommandObjectTypeFilterList(interpreter)));
+ }
+
+ ~CommandObjectTypeFilter() override = default;
};
-class CommandObjectTypeCategory : public CommandObjectMultiword
-{
+class CommandObjectTypeCategory : public CommandObjectMultiword {
public:
- CommandObjectTypeCategory(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "type category", "Commands for operating on type categories.",
- "type category [<sub-command-options>] ")
- {
- LoadSubCommand ("define", CommandObjectSP (new CommandObjectTypeCategoryDefine (interpreter)));
- LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter)));
- LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeCategoryList (interpreter)));
- }
-
- ~CommandObjectTypeCategory() override = default;
+ CommandObjectTypeCategory(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "type category",
+ "Commands for operating on type categories.",
+ "type category [<sub-command-options>] ") {
+ LoadSubCommand(
+ "define",
+ CommandObjectSP(new CommandObjectTypeCategoryDefine(interpreter)));
+ LoadSubCommand(
+ "enable",
+ CommandObjectSP(new CommandObjectTypeCategoryEnable(interpreter)));
+ LoadSubCommand(
+ "disable",
+ CommandObjectSP(new CommandObjectTypeCategoryDisable(interpreter)));
+ LoadSubCommand(
+ "delete",
+ CommandObjectSP(new CommandObjectTypeCategoryDelete(interpreter)));
+ LoadSubCommand("list", CommandObjectSP(
+ new CommandObjectTypeCategoryList(interpreter)));
+ }
+
+ ~CommandObjectTypeCategory() override = default;
};
-class CommandObjectTypeSummary : public CommandObjectMultiword
-{
+class CommandObjectTypeSummary : public CommandObjectMultiword {
public:
- CommandObjectTypeSummary(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "type summary", "Commands for editing variable summary display options.",
- "type summary [<sub-command-options>] ")
- {
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter)));
- LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter)));
- LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<TypeSummaryImpl>(interpreter,
- "summary",
- [](ValueObject& valobj) -> TypeSummaryImpl::SharedPointer {
- return valobj.GetSummaryFormat();
- })));
- }
-
- ~CommandObjectTypeSummary() override = default;
+ CommandObjectTypeSummary(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "type summary",
+ "Commands for editing variable summary display options.",
+ "type summary [<sub-command-options>] ") {
+ LoadSubCommand(
+ "add", CommandObjectSP(new CommandObjectTypeSummaryAdd(interpreter)));
+ LoadSubCommand("clear", CommandObjectSP(new CommandObjectTypeSummaryClear(
+ interpreter)));
+ LoadSubCommand("delete", CommandObjectSP(new CommandObjectTypeSummaryDelete(
+ interpreter)));
+ LoadSubCommand(
+ "list", CommandObjectSP(new CommandObjectTypeSummaryList(interpreter)));
+ LoadSubCommand(
+ "info", CommandObjectSP(new CommandObjectFormatterInfo<TypeSummaryImpl>(
+ interpreter, "summary",
+ [](ValueObject &valobj) -> TypeSummaryImpl::SharedPointer {
+ return valobj.GetSummaryFormat();
+ })));
+ }
+
+ ~CommandObjectTypeSummary() override = default;
};
//-------------------------------------------------------------------------
@@ -3674,17 +3204,23 @@ public:
//-------------------------------------------------------------------------
CommandObjectType::CommandObjectType(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "type", "Commands for operating on the type system.",
- "type [<sub-command-options>]")
-{
- LoadSubCommand ("category", CommandObjectSP (new CommandObjectTypeCategory (interpreter)));
- LoadSubCommand ("filter", CommandObjectSP (new CommandObjectTypeFilter (interpreter)));
- LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
- LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
+ : CommandObjectMultiword(interpreter, "type",
+ "Commands for operating on the type system.",
+ "type [<sub-command-options>]") {
+ LoadSubCommand("category",
+ CommandObjectSP(new CommandObjectTypeCategory(interpreter)));
+ LoadSubCommand("filter",
+ CommandObjectSP(new CommandObjectTypeFilter(interpreter)));
+ LoadSubCommand("format",
+ CommandObjectSP(new CommandObjectTypeFormat(interpreter)));
+ LoadSubCommand("summary",
+ CommandObjectSP(new CommandObjectTypeSummary(interpreter)));
#ifndef LLDB_DISABLE_PYTHON
- LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter)));
+ LoadSubCommand("synthetic",
+ CommandObjectSP(new CommandObjectTypeSynth(interpreter)));
#endif // LLDB_DISABLE_PYTHON
- LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTypeLookup (interpreter)));
+ LoadSubCommand("lookup",
+ CommandObjectSP(new CommandObjectTypeLookup(interpreter)));
}
CommandObjectType::~CommandObjectType() = default;
diff --git a/source/Commands/CommandObjectType.h b/source/Commands/CommandObjectType.h
index 54f4a33c6f65..f2f9ce7c1b61 100644
--- a/source/Commands/CommandObjectType.h
+++ b/source/Commands/CommandObjectType.h
@@ -16,18 +16,17 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-types.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/Options.h"
+#include "lldb/lldb-types.h"
namespace lldb_private {
-class CommandObjectType : public CommandObjectMultiword
-{
+class CommandObjectType : public CommandObjectMultiword {
public:
- CommandObjectType (CommandInterpreter &interpreter);
+ CommandObjectType(CommandInterpreter &interpreter);
- ~CommandObjectType() override;
+ ~CommandObjectType() override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectVersion.cpp b/source/Commands/CommandObjectVersion.cpp
index 06962f8648ad..8b1f25bfc521 100644
--- a/source/Commands/CommandObjectVersion.cpp
+++ b/source/Commands/CommandObjectVersion.cpp
@@ -13,9 +13,9 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
@@ -25,27 +25,18 @@ using namespace lldb_private;
//-------------------------------------------------------------------------
CommandObjectVersion::CommandObjectVersion(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "version", "Show the LLDB debugger version.", "version")
-{
-}
-
-CommandObjectVersion::~CommandObjectVersion ()
-{
+ : CommandObjectParsed(interpreter, "version",
+ "Show the LLDB debugger version.", "version") {}
+
+CommandObjectVersion::~CommandObjectVersion() {}
+
+bool CommandObjectVersion::DoExecute(Args &args, CommandReturnObject &result) {
+ if (args.GetArgumentCount() == 0) {
+ result.AppendMessageWithFormat("%s\n", lldb_private::GetVersion());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendError("the version command takes no arguments.");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return true;
}
-
-bool
-CommandObjectVersion::DoExecute (Args& args, CommandReturnObject &result)
-{
- if (args.GetArgumentCount() == 0)
- {
- result.AppendMessageWithFormat ("%s\n", lldb_private::GetVersion());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError("the version command takes no arguments.");
- result.SetStatus (eReturnStatusFailed);
- }
- return true;
-}
-
diff --git a/source/Commands/CommandObjectVersion.h b/source/Commands/CommandObjectVersion.h
index 30ba9d1235d9..5f661cc341c0 100644
--- a/source/Commands/CommandObjectVersion.h
+++ b/source/Commands/CommandObjectVersion.h
@@ -22,18 +22,14 @@ namespace lldb_private {
// CommandObjectVersion
//-------------------------------------------------------------------------
-class CommandObjectVersion : public CommandObjectParsed
-{
+class CommandObjectVersion : public CommandObjectParsed {
public:
+ CommandObjectVersion(CommandInterpreter &interpreter);
- CommandObjectVersion (CommandInterpreter &interpreter);
-
- ~CommandObjectVersion() override;
+ ~CommandObjectVersion() override;
protected:
- bool
- DoExecute(Args& args,
- CommandReturnObject &result) override;
+ bool DoExecute(Args &args, CommandReturnObject &result) override;
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp
index 977b6bb37437..baa9f4163a63 100644
--- a/source/Commands/CommandObjectWatchpoint.cpp
+++ b/source/Commands/CommandObjectWatchpoint.cpp
@@ -24,9 +24,9 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/StackFrame.h"
@@ -35,308 +35,271 @@
using namespace lldb;
using namespace lldb_private;
-static void
-AddWatchpointDescription(Stream *s, Watchpoint *wp, lldb::DescriptionLevel level)
-{
- s->IndentMore();
- wp->GetDescription(s, level);
- s->IndentLess();
- s->EOL();
+static void AddWatchpointDescription(Stream *s, Watchpoint *wp,
+ lldb::DescriptionLevel level) {
+ s->IndentMore();
+ wp->GetDescription(s, level);
+ s->IndentLess();
+ s->EOL();
}
-static bool
-CheckTargetForWatchpointOperations(Target *target, CommandReturnObject &result)
-{
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No existing target or watchpoints.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- bool process_is_valid = target->GetProcessSP() && target->GetProcessSP()->IsAlive();
- if (!process_is_valid)
- {
- result.AppendError ("Thre's no process or it is not alive.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- // Target passes our checks, return true.
- return true;
+static bool CheckTargetForWatchpointOperations(Target *target,
+ CommandReturnObject &result) {
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No existing target or watchpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ bool process_is_valid =
+ target->GetProcessSP() && target->GetProcessSP()->IsAlive();
+ if (!process_is_valid) {
+ result.AppendError("Thre's no process or it is not alive.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ // Target passes our checks, return true.
+ return true;
}
// Equivalent class: {"-", "to", "To", "TO"} of range specifier array.
-static const char* RSA[4] = { "-", "to", "To", "TO" };
+static const char *RSA[4] = {"-", "to", "To", "TO"};
// Return the index to RSA if found; otherwise -1 is returned.
-static int32_t
-WithRSAIndex(llvm::StringRef &Arg)
-{
-
- uint32_t i;
- for (i = 0; i < 4; ++i)
- if (Arg.find(RSA[i]) != llvm::StringRef::npos)
- return i;
- return -1;
+static int32_t WithRSAIndex(llvm::StringRef Arg) {
+
+ uint32_t i;
+ for (i = 0; i < 4; ++i)
+ if (Arg.find(RSA[i]) != llvm::StringRef::npos)
+ return i;
+ return -1;
}
// Return true if wp_ids is successfully populated with the watch ids.
// False otherwise.
-bool
-CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(Target *target, Args &args, std::vector<uint32_t> &wp_ids)
-{
- // Pre-condition: args.GetArgumentCount() > 0.
- if (args.GetArgumentCount() == 0)
- {
- if (target == nullptr)
- return false;
- WatchpointSP watch_sp = target->GetLastCreatedWatchpoint();
- if (watch_sp)
- {
- wp_ids.push_back(watch_sp->GetID());
- return true;
- }
- else
- return false;
- }
-
- llvm::StringRef Minus("-");
- std::vector<llvm::StringRef> StrRefArgs;
- std::pair<llvm::StringRef, llvm::StringRef> Pair;
- size_t i;
- int32_t idx;
- // Go through the arguments and make a canonical form of arg list containing
- // only numbers with possible "-" in between.
- for (i = 0; i < args.GetArgumentCount(); ++i) {
- llvm::StringRef Arg(args.GetArgumentAtIndex(i));
- if ((idx = WithRSAIndex(Arg)) == -1) {
- StrRefArgs.push_back(Arg);
- continue;
- }
- // The Arg contains the range specifier, split it, then.
- Pair = Arg.split(RSA[idx]);
- if (!Pair.first.empty())
- StrRefArgs.push_back(Pair.first);
- StrRefArgs.push_back(Minus);
- if (!Pair.second.empty())
- StrRefArgs.push_back(Pair.second);
+bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
+ Target *target, Args &args, std::vector<uint32_t> &wp_ids) {
+ // Pre-condition: args.GetArgumentCount() > 0.
+ if (args.GetArgumentCount() == 0) {
+ if (target == nullptr)
+ return false;
+ WatchpointSP watch_sp = target->GetLastCreatedWatchpoint();
+ if (watch_sp) {
+ wp_ids.push_back(watch_sp->GetID());
+ return true;
+ } else
+ return false;
+ }
+
+ llvm::StringRef Minus("-");
+ std::vector<llvm::StringRef> StrRefArgs;
+ llvm::StringRef first;
+ llvm::StringRef second;
+ size_t i;
+ int32_t idx;
+ // Go through the arguments and make a canonical form of arg list containing
+ // only numbers with possible "-" in between.
+ for (auto &entry : args.entries()) {
+ if ((idx = WithRSAIndex(entry.ref)) == -1) {
+ StrRefArgs.push_back(entry.ref);
+ continue;
}
- // Now process the canonical list and fill in the vector of uint32_t's.
- // If there is any error, return false and the client should ignore wp_ids.
- uint32_t beg, end, id;
- size_t size = StrRefArgs.size();
- bool in_range = false;
- for (i = 0; i < size; ++i) {
- llvm::StringRef Arg = StrRefArgs[i];
- if (in_range) {
- // Look for the 'end' of the range. Note StringRef::getAsInteger()
- // returns true to signify error while parsing.
- if (Arg.getAsInteger(0, end))
- return false;
- // Found a range! Now append the elements.
- for (id = beg; id <= end; ++id)
- wp_ids.push_back(id);
- in_range = false;
- continue;
- }
- if (i < (size - 1) && StrRefArgs[i+1] == Minus) {
- if (Arg.getAsInteger(0, beg))
- return false;
- // Turn on the in_range flag, we are looking for end of range next.
- ++i; in_range = true;
- continue;
- }
- // Otherwise, we have a simple ID. Just append it.
- if (Arg.getAsInteger(0, beg))
- return false;
- wp_ids.push_back(beg);
+ // The Arg contains the range specifier, split it, then.
+ std::tie(first, second) = entry.ref.split(RSA[idx]);
+ if (!first.empty())
+ StrRefArgs.push_back(first);
+ StrRefArgs.push_back(Minus);
+ if (!second.empty())
+ StrRefArgs.push_back(second);
+ }
+ // Now process the canonical list and fill in the vector of uint32_t's.
+ // If there is any error, return false and the client should ignore wp_ids.
+ uint32_t beg, end, id;
+ size_t size = StrRefArgs.size();
+ bool in_range = false;
+ for (i = 0; i < size; ++i) {
+ llvm::StringRef Arg = StrRefArgs[i];
+ if (in_range) {
+ // Look for the 'end' of the range. Note StringRef::getAsInteger()
+ // returns true to signify error while parsing.
+ if (Arg.getAsInteger(0, end))
+ return false;
+ // Found a range! Now append the elements.
+ for (id = beg; id <= end; ++id)
+ wp_ids.push_back(id);
+ in_range = false;
+ continue;
}
- // It is an error if after the loop, we're still in_range.
- if (in_range)
+ if (i < (size - 1) && StrRefArgs[i + 1] == Minus) {
+ if (Arg.getAsInteger(0, beg))
return false;
-
- return true; // Success!
+ // Turn on the in_range flag, we are looking for end of range next.
+ ++i;
+ in_range = true;
+ continue;
+ }
+ // Otherwise, we have a simple ID. Just append it.
+ if (Arg.getAsInteger(0, beg))
+ return false;
+ wp_ids.push_back(beg);
+ }
+ // It is an error if after the loop, we're still in_range.
+ if (in_range)
+ return false;
+
+ return true; // Success!
}
//-------------------------------------------------------------------------
// CommandObjectWatchpointList
//-------------------------------------------------------------------------
+
+//-------------------------------------------------------------------------
+// CommandObjectWatchpointList::Options
+//-------------------------------------------------------------------------
+#pragma mark List::CommandOptions
+
+static OptionDefinition g_watchpoint_list_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a brief description of the watchpoint (no location info)." },
+ { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a full description of the watchpoint and its locations." },
+ { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Explain everything we know about the watchpoint (for debugging debugger bugs)." }
+ // clang-format on
+};
+
#pragma mark List
-class CommandObjectWatchpointList : public CommandObjectParsed
-{
+class CommandObjectWatchpointList : public CommandObjectParsed {
public:
- CommandObjectWatchpointList (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "watchpoint list",
- "List all watchpoints at configurable levels of detail.",
- nullptr),
- m_options(interpreter)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back(arg);
+ CommandObjectWatchpointList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "watchpoint list",
+ "List all watchpoints at configurable levels of detail.", nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
+ eArgTypeWatchpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectWatchpointList() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(),
+ m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to
+ // brief descriptions
+ {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'b':
+ m_level = lldb::eDescriptionLevelBrief;
+ break;
+ case 'f':
+ m_level = lldb::eDescriptionLevelFull;
+ break;
+ case 'v':
+ m_level = lldb::eDescriptionLevelVerbose;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectWatchpointList() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_level = lldb::eDescriptionLevelFull;
}
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter),
- m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to brief descriptions
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'b':
- m_level = lldb::eDescriptionLevelBrief;
- break;
- case 'f':
- m_level = lldb::eDescriptionLevelFull;
- break;
- case 'v':
- m_level = lldb::eDescriptionLevelVerbose;
- break;
- default:
- error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_level = lldb::eDescriptionLevelFull;
- }
-
- const OptionDefinition *
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_watchpoint_list_options);
+ }
- // Instance variables to hold the values for command options.
+ // Instance variables to hold the values for command options.
- lldb::DescriptionLevel m_level;
- };
+ lldb::DescriptionLevel m_level;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == nullptr)
- {
- result.AppendError ("Invalid target. No current target or watchpoints.");
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- return true;
- }
-
- if (target->GetProcessSP() && target->GetProcessSP()->IsAlive())
- {
- uint32_t num_supported_hardware_watchpoints;
- Error error = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints);
- if (error.Success())
- result.AppendMessageWithFormat("Number of supported hardware watchpoints: %u\n",
- num_supported_hardware_watchpoints);
- }
-
- const WatchpointList &watchpoints = target->GetWatchpointList();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == nullptr) {
+ result.AppendError("Invalid target. No current target or watchpoints.");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
+ }
- std::unique_lock<std::recursive_mutex> lock;
- target->GetWatchpointList().GetListMutex(lock);
+ if (target->GetProcessSP() && target->GetProcessSP()->IsAlive()) {
+ uint32_t num_supported_hardware_watchpoints;
+ Error error = target->GetProcessSP()->GetWatchpointSupportInfo(
+ num_supported_hardware_watchpoints);
+ if (error.Success())
+ result.AppendMessageWithFormat(
+ "Number of supported hardware watchpoints: %u\n",
+ num_supported_hardware_watchpoints);
+ }
- size_t num_watchpoints = watchpoints.GetSize();
+ const WatchpointList &watchpoints = target->GetWatchpointList();
- if (num_watchpoints == 0)
- {
- result.AppendMessage("No watchpoints currently set.");
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return true;
- }
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
- Stream &output_stream = result.GetOutputStream();
-
- if (command.GetArgumentCount() == 0)
- {
- // No watchpoint selected; show info about all currently set watchpoints.
- result.AppendMessage ("Current watchpoints:");
- for (size_t i = 0; i < num_watchpoints; ++i)
- {
- Watchpoint *wp = watchpoints.GetByIndex(i).get();
- AddWatchpointDescription(&output_stream, wp, m_options.m_level);
- }
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular watchpoints selected; enable them.
- std::vector<uint32_t> wp_ids;
- if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
- {
- result.AppendError("Invalid watchpoints specification.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- const size_t size = wp_ids.size();
- for (size_t i = 0; i < size; ++i)
- {
- Watchpoint *wp = watchpoints.FindByID(wp_ids[i]).get();
- if (wp)
- AddWatchpointDescription(&output_stream, wp, m_options.m_level);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- }
+ size_t num_watchpoints = watchpoints.GetSize();
- return result.Succeeded();
+ if (num_watchpoints == 0) {
+ result.AppendMessage("No watchpoints currently set.");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return true;
}
-private:
- CommandOptions m_options;
-};
-
-//-------------------------------------------------------------------------
-// CommandObjectWatchpointList::Options
-//-------------------------------------------------------------------------
-#pragma mark List::CommandOptions
-
-OptionDefinition
-CommandObjectWatchpointList::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Give a brief description of the watchpoint (no location info)."},
+ Stream &output_stream = result.GetOutputStream();
+
+ if (command.GetArgumentCount() == 0) {
+ // No watchpoint selected; show info about all currently set watchpoints.
+ result.AppendMessage("Current watchpoints:");
+ for (size_t i = 0; i < num_watchpoints; ++i) {
+ Watchpoint *wp = watchpoints.GetByIndex(i).get();
+ AddWatchpointDescription(&output_stream, wp, m_options.m_level);
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular watchpoints selected; enable them.
+ std::vector<uint32_t> wp_ids;
+ if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
+ target, command, wp_ids)) {
+ result.AppendError("Invalid watchpoints specification.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Give a full description of the watchpoint and its locations."},
+ const size_t size = wp_ids.size();
+ for (size_t i = 0; i < size; ++i) {
+ Watchpoint *wp = watchpoints.FindByID(wp_ids[i]).get();
+ if (wp)
+ AddWatchpointDescription(&output_stream, wp, m_options.m_level);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+ }
- { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
- "Explain everything we know about the watchpoint (for debugging debugger bugs)." },
+ return result.Succeeded();
+ }
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -344,75 +307,70 @@ CommandObjectWatchpointList::CommandOptions::g_option_table[] =
//-------------------------------------------------------------------------
#pragma mark Enable
-class CommandObjectWatchpointEnable : public CommandObjectParsed
-{
+class CommandObjectWatchpointEnable : public CommandObjectParsed {
public:
- CommandObjectWatchpointEnable (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "enable",
- "Enable the specified disabled watchpoint(s). If no watchpoints are specified, enable all of them.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back(arg);
- }
-
- ~CommandObjectWatchpointEnable() override = default;
+ CommandObjectWatchpointEnable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "enable",
+ "Enable the specified disabled watchpoint(s). If "
+ "no watchpoints are specified, enable all of them.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
+ eArgTypeWatchpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectWatchpointEnable() override = default;
protected:
- bool
- DoExecute (Args& command,
- CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (!CheckTargetForWatchpointOperations(target, result))
- return false;
-
- std::unique_lock<std::recursive_mutex> lock;
- target->GetWatchpointList().GetListMutex(lock);
-
- const WatchpointList &watchpoints = target->GetWatchpointList();
-
- size_t num_watchpoints = watchpoints.GetSize();
-
- if (num_watchpoints == 0)
- {
- result.AppendError("No watchpoints exist to be enabled.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (!CheckTargetForWatchpointOperations(target, result))
+ return false;
- if (command.GetArgumentCount() == 0)
- {
- // No watchpoint selected; enable all currently set watchpoints.
- target->EnableAllWatchpoints();
- result.AppendMessageWithFormat("All watchpoints enabled. (%" PRIu64 " watchpoints)\n", (uint64_t)num_watchpoints);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular watchpoints selected; enable them.
- std::vector<uint32_t> wp_ids;
- if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
- {
- result.AppendError("Invalid watchpoints specification.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- int count = 0;
- const size_t size = wp_ids.size();
- for (size_t i = 0; i < size; ++i)
- if (target->EnableWatchpointByID(wp_ids[i]))
- ++count;
- result.AppendMessageWithFormat("%d watchpoints enabled.\n", count);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
+
+ const WatchpointList &watchpoints = target->GetWatchpointList();
- return result.Succeeded();
+ size_t num_watchpoints = watchpoints.GetSize();
+
+ if (num_watchpoints == 0) {
+ result.AppendError("No watchpoints exist to be enabled.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (command.GetArgumentCount() == 0) {
+ // No watchpoint selected; enable all currently set watchpoints.
+ target->EnableAllWatchpoints();
+ result.AppendMessageWithFormat("All watchpoints enabled. (%" PRIu64
+ " watchpoints)\n",
+ (uint64_t)num_watchpoints);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular watchpoints selected; enable them.
+ std::vector<uint32_t> wp_ids;
+ if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
+ target, command, wp_ids)) {
+ result.AppendError("Invalid watchpoints specification.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ int count = 0;
+ const size_t size = wp_ids.size();
+ for (size_t i = 0; i < size; ++i)
+ if (target->EnableWatchpointByID(wp_ids[i]))
+ ++count;
+ result.AppendMessageWithFormat("%d watchpoints enabled.\n", count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
@@ -420,80 +378,74 @@ protected:
//-------------------------------------------------------------------------
#pragma mark Disable
-class CommandObjectWatchpointDisable : public CommandObjectParsed
-{
+class CommandObjectWatchpointDisable : public CommandObjectParsed {
public:
- CommandObjectWatchpointDisable (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "watchpoint disable",
- "Disable the specified watchpoint(s) without removing it/them. If no watchpoints are specified, disable them all.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back(arg);
- }
-
- ~CommandObjectWatchpointDisable() override = default;
+ CommandObjectWatchpointDisable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "watchpoint disable",
+ "Disable the specified watchpoint(s) without "
+ "removing it/them. If no watchpoints are "
+ "specified, disable them all.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
+ eArgTypeWatchpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectWatchpointDisable() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (!CheckTargetForWatchpointOperations(target, result))
- return false;
-
- std::unique_lock<std::recursive_mutex> lock;
- target->GetWatchpointList().GetListMutex(lock);
-
- const WatchpointList &watchpoints = target->GetWatchpointList();
- size_t num_watchpoints = watchpoints.GetSize();
-
- if (num_watchpoints == 0)
- {
- result.AppendError("No watchpoints exist to be disabled.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (!CheckTargetForWatchpointOperations(target, result))
+ return false;
- if (command.GetArgumentCount() == 0)
- {
- // No watchpoint selected; disable all currently set watchpoints.
- if (target->DisableAllWatchpoints())
- {
- result.AppendMessageWithFormat("All watchpoints disabled. (%" PRIu64 " watchpoints)\n", (uint64_t)num_watchpoints);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError("Disable all watchpoints failed\n");
- result.SetStatus(eReturnStatusFailed);
- }
- }
- else
- {
- // Particular watchpoints selected; disable them.
- std::vector<uint32_t> wp_ids;
- if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
- {
- result.AppendError("Invalid watchpoints specification.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- int count = 0;
- const size_t size = wp_ids.size();
- for (size_t i = 0; i < size; ++i)
- if (target->DisableWatchpointByID(wp_ids[i]))
- ++count;
- result.AppendMessageWithFormat("%d watchpoints disabled.\n", count);
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
+
+ const WatchpointList &watchpoints = target->GetWatchpointList();
+ size_t num_watchpoints = watchpoints.GetSize();
+
+ if (num_watchpoints == 0) {
+ result.AppendError("No watchpoints exist to be disabled.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- return result.Succeeded();
+ if (command.GetArgumentCount() == 0) {
+ // No watchpoint selected; disable all currently set watchpoints.
+ if (target->DisableAllWatchpoints()) {
+ result.AppendMessageWithFormat("All watchpoints disabled. (%" PRIu64
+ " watchpoints)\n",
+ (uint64_t)num_watchpoints);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ result.AppendError("Disable all watchpoints failed\n");
+ result.SetStatus(eReturnStatusFailed);
+ }
+ } else {
+ // Particular watchpoints selected; disable them.
+ std::vector<uint32_t> wp_ids;
+ if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
+ target, command, wp_ids)) {
+ result.AppendError("Invalid watchpoints specification.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ int count = 0;
+ const size_t size = wp_ids.size();
+ for (size_t i = 0; i < size; ++i)
+ if (target->DisableWatchpointByID(wp_ids[i]))
+ ++count;
+ result.AppendMessageWithFormat("%d watchpoints disabled.\n", count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
@@ -501,385 +453,327 @@ protected:
//-------------------------------------------------------------------------
#pragma mark Delete
-class CommandObjectWatchpointDelete : public CommandObjectParsed
-{
+class CommandObjectWatchpointDelete : public CommandObjectParsed {
public:
- CommandObjectWatchpointDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "watchpoint delete",
- "Delete the specified watchpoint(s). If no watchpoints are specified, delete them all.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back(arg);
- }
-
- ~CommandObjectWatchpointDelete() override = default;
+ CommandObjectWatchpointDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "watchpoint delete",
+ "Delete the specified watchpoint(s). If no "
+ "watchpoints are specified, delete them all.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
+ eArgTypeWatchpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectWatchpointDelete() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (!CheckTargetForWatchpointOperations(target, result))
- return false;
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (!CheckTargetForWatchpointOperations(target, result))
+ return false;
- std::unique_lock<std::recursive_mutex> lock;
- target->GetWatchpointList().GetListMutex(lock);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
- const WatchpointList &watchpoints = target->GetWatchpointList();
+ const WatchpointList &watchpoints = target->GetWatchpointList();
- size_t num_watchpoints = watchpoints.GetSize();
+ size_t num_watchpoints = watchpoints.GetSize();
- if (num_watchpoints == 0)
- {
- result.AppendError("No watchpoints exist to be deleted.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (command.GetArgumentCount() == 0)
- {
- if (!m_interpreter.Confirm("About to delete all watchpoints, do you want to do that?", true))
- {
- result.AppendMessage("Operation cancelled...");
- }
- else
- {
- target->RemoveAllWatchpoints();
- result.AppendMessageWithFormat("All watchpoints removed. (%" PRIu64 " watchpoints)\n", (uint64_t)num_watchpoints);
- }
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular watchpoints selected; delete them.
- std::vector<uint32_t> wp_ids;
- if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
- {
- result.AppendError("Invalid watchpoints specification.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- int count = 0;
- const size_t size = wp_ids.size();
- for (size_t i = 0; i < size; ++i)
- if (target->RemoveWatchpointByID(wp_ids[i]))
- ++count;
- result.AppendMessageWithFormat("%d watchpoints deleted.\n",count);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
+ if (num_watchpoints == 0) {
+ result.AppendError("No watchpoints exist to be deleted.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- return result.Succeeded();
+ if (command.GetArgumentCount() == 0) {
+ if (!m_interpreter.Confirm(
+ "About to delete all watchpoints, do you want to do that?",
+ true)) {
+ result.AppendMessage("Operation cancelled...");
+ } else {
+ target->RemoveAllWatchpoints();
+ result.AppendMessageWithFormat("All watchpoints removed. (%" PRIu64
+ " watchpoints)\n",
+ (uint64_t)num_watchpoints);
+ }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular watchpoints selected; delete them.
+ std::vector<uint32_t> wp_ids;
+ if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
+ target, command, wp_ids)) {
+ result.AppendError("Invalid watchpoints specification.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ int count = 0;
+ const size_t size = wp_ids.size();
+ for (size_t i = 0; i < size; ++i)
+ if (target->RemoveWatchpointByID(wp_ids[i]))
+ ++count;
+ result.AppendMessageWithFormat("%d watchpoints deleted.\n", count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectWatchpointIgnore
//-------------------------------------------------------------------------
-class CommandObjectWatchpointIgnore : public CommandObjectParsed
-{
+#pragma mark Ignore::CommandOptions
+static OptionDefinition g_watchpoint_ignore_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." }
+ // clang-format on
+};
+
+class CommandObjectWatchpointIgnore : public CommandObjectParsed {
public:
- CommandObjectWatchpointIgnore (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "watchpoint ignore",
- "Set ignore count on the specified watchpoint(s). If no watchpoints are specified, set them all.",
+ CommandObjectWatchpointIgnore(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "watchpoint ignore",
+ "Set ignore count on the specified watchpoint(s). "
+ "If no watchpoints are specified, set them all.",
nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back(arg);
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
+ eArgTypeWatchpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectWatchpointIgnore() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_ignore_count(0) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'i':
+ if (option_arg.getAsInteger(0, m_ignore_count))
+ error.SetErrorStringWithFormat("invalid ignore count '%s'",
+ option_arg.str().c_str());
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectWatchpointIgnore() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_ignore_count = 0;
}
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_ignore_count (0)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'i':
- m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
- if (m_ignore_count == UINT32_MAX)
- error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_ignore_count = 0;
- }
-
- const OptionDefinition *
- GetDefinitions () override
- {
- return g_option_table;
- }
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_watchpoint_ignore_options);
+ }
- // Options table: Required for subclasses of Options.
+ // Instance variables to hold the values for command options.
- static OptionDefinition g_option_table[];
+ uint32_t m_ignore_count;
+ };
- // Instance variables to hold the values for command options.
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (!CheckTargetForWatchpointOperations(target, result))
+ return false;
- uint32_t m_ignore_count;
- };
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
-protected:
- bool
- DoExecute (Args& command,
- CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (!CheckTargetForWatchpointOperations(target, result))
- return false;
-
- std::unique_lock<std::recursive_mutex> lock;
- target->GetWatchpointList().GetListMutex(lock);
-
- const WatchpointList &watchpoints = target->GetWatchpointList();
-
- size_t num_watchpoints = watchpoints.GetSize();
-
- if (num_watchpoints == 0)
- {
- result.AppendError("No watchpoints exist to be ignored.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ const WatchpointList &watchpoints = target->GetWatchpointList();
- if (command.GetArgumentCount() == 0)
- {
- target->IgnoreAllWatchpoints(m_options.m_ignore_count);
- result.AppendMessageWithFormat("All watchpoints ignored. (%" PRIu64 " watchpoints)\n", (uint64_t)num_watchpoints);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular watchpoints selected; ignore them.
- std::vector<uint32_t> wp_ids;
- if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
- {
- result.AppendError("Invalid watchpoints specification.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- int count = 0;
- const size_t size = wp_ids.size();
- for (size_t i = 0; i < size; ++i)
- if (target->IgnoreWatchpointByID(wp_ids[i], m_options.m_ignore_count))
- ++count;
- result.AppendMessageWithFormat("%d watchpoints ignored.\n",count);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
+ size_t num_watchpoints = watchpoints.GetSize();
- return result.Succeeded();
+ if (num_watchpoints == 0) {
+ result.AppendError("No watchpoints exist to be ignored.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-private:
- CommandOptions m_options;
-};
+ if (command.GetArgumentCount() == 0) {
+ target->IgnoreAllWatchpoints(m_options.m_ignore_count);
+ result.AppendMessageWithFormat("All watchpoints ignored. (%" PRIu64
+ " watchpoints)\n",
+ (uint64_t)num_watchpoints);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular watchpoints selected; ignore them.
+ std::vector<uint32_t> wp_ids;
+ if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
+ target, command, wp_ids)) {
+ result.AppendError("Invalid watchpoints specification.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ int count = 0;
+ const size_t size = wp_ids.size();
+ for (size_t i = 0; i < size; ++i)
+ if (target->IgnoreWatchpointByID(wp_ids[i], m_options.m_ignore_count))
+ ++count;
+ result.AppendMessageWithFormat("%d watchpoints ignored.\n", count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
-#pragma mark Ignore::CommandOptions
+ return result.Succeeded();
+ }
-OptionDefinition
-CommandObjectWatchpointIgnore::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." },
- { 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectWatchpointModify
//-------------------------------------------------------------------------
+
+#pragma mark Modify::CommandOptions
+
+static OptionDefinition g_watchpoint_modify_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true." }
+ // clang-format on
+};
+
#pragma mark Modify
-class CommandObjectWatchpointModify : public CommandObjectParsed
-{
+class CommandObjectWatchpointModify : public CommandObjectParsed {
public:
- CommandObjectWatchpointModify (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "watchpoint modify",
- "Modify the options on a watchpoint or set of watchpoints in the executable. "
- "If no watchpoint is specified, act on the last created watchpoint. "
- "Passing an empty argument clears the modification.",
- nullptr),
- m_options (interpreter)
- {
- CommandArgumentEntry arg;
- CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
- // Add the entry for the first argument for this command to the object's arguments vector.
- m_arguments.push_back (arg);
+ CommandObjectWatchpointModify(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "watchpoint modify",
+ "Modify the options on a watchpoint or set of watchpoints in the "
+ "executable. "
+ "If no watchpoint is specified, act on the last created "
+ "watchpoint. "
+ "Passing an empty argument clears the modification.",
+ nullptr),
+ m_options() {
+ CommandArgumentEntry arg;
+ CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID,
+ eArgTypeWatchpointIDRange);
+ // Add the entry for the first argument for this command to the object's
+ // arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectWatchpointModify() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), m_condition(), m_condition_passed(false) {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c':
+ m_condition = option_arg;
+ m_condition_passed = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("unrecognized option '%c'",
+ short_option);
+ break;
+ }
+
+ return error;
}
- ~CommandObjectWatchpointModify() override = default;
-
- Options *
- GetOptions () override
- {
- return &m_options;
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_condition.clear();
+ m_condition_passed = false;
}
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_condition (),
- m_condition_passed (false)
- {
- }
-
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'c':
- if (option_arg != nullptr)
- m_condition.assign (option_arg);
- else
- m_condition.clear();
- m_condition_passed = true;
- break;
- default:
- error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
- break;
- }
-
- return error;
- }
-
- void
- OptionParsingStarting () override
- {
- m_condition.clear();
- m_condition_passed = false;
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_watchpoint_modify_options);
+ }
- // Instance variables to hold the values for command options.
+ // Instance variables to hold the values for command options.
- std::string m_condition;
- bool m_condition_passed;
- };
+ std::string m_condition;
+ bool m_condition_passed;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (!CheckTargetForWatchpointOperations(target, result))
- return false;
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (!CheckTargetForWatchpointOperations(target, result))
+ return false;
- std::unique_lock<std::recursive_mutex> lock;
- target->GetWatchpointList().GetListMutex(lock);
+ std::unique_lock<std::recursive_mutex> lock;
+ target->GetWatchpointList().GetListMutex(lock);
- const WatchpointList &watchpoints = target->GetWatchpointList();
+ const WatchpointList &watchpoints = target->GetWatchpointList();
- size_t num_watchpoints = watchpoints.GetSize();
+ size_t num_watchpoints = watchpoints.GetSize();
- if (num_watchpoints == 0)
- {
- result.AppendError("No watchpoints exist to be modified.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ if (num_watchpoints == 0) {
+ result.AppendError("No watchpoints exist to be modified.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- WatchpointSP wp_sp = target->GetLastCreatedWatchpoint();
- wp_sp->SetCondition(m_options.m_condition.c_str());
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- // Particular watchpoints selected; set condition on them.
- std::vector<uint32_t> wp_ids;
- if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
- {
- result.AppendError("Invalid watchpoints specification.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- int count = 0;
- const size_t size = wp_ids.size();
- for (size_t i = 0; i < size; ++i)
- {
- WatchpointSP wp_sp = watchpoints.FindByID(wp_ids[i]);
- if (wp_sp)
- {
- wp_sp->SetCondition(m_options.m_condition.c_str());
- ++count;
- }
- }
- result.AppendMessageWithFormat("%d watchpoints modified.\n",count);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ if (command.GetArgumentCount() == 0) {
+ WatchpointSP wp_sp = target->GetLastCreatedWatchpoint();
+ wp_sp->SetCondition(m_options.m_condition.c_str());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else {
+ // Particular watchpoints selected; set condition on them.
+ std::vector<uint32_t> wp_ids;
+ if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
+ target, command, wp_ids)) {
+ result.AppendError("Invalid watchpoints specification.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ int count = 0;
+ const size_t size = wp_ids.size();
+ for (size_t i = 0; i < size; ++i) {
+ WatchpointSP wp_sp = watchpoints.FindByID(wp_ids[i]);
+ if (wp_sp) {
+ wp_sp->SetCondition(m_options.m_condition.c_str());
+ ++count;
}
-
- return result.Succeeded();
+ }
+ result.AppendMessageWithFormat("%d watchpoints modified.\n", count);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
}
-private:
- CommandOptions m_options;
-};
+ return result.Succeeded();
+ }
-#pragma mark Modify::CommandOptions
-
-OptionDefinition
-CommandObjectWatchpointModify::CommandOptions::g_option_table[] =
-{
-{ LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true."},
-{ 0, false, nullptr, 0 , 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
@@ -887,208 +781,189 @@ CommandObjectWatchpointModify::CommandOptions::g_option_table[] =
//-------------------------------------------------------------------------
#pragma mark SetVariable
-class CommandObjectWatchpointSetVariable : public CommandObjectParsed
-{
+class CommandObjectWatchpointSetVariable : public CommandObjectParsed {
public:
- CommandObjectWatchpointSetVariable (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "watchpoint set variable",
- "Set a watchpoint on a variable. "
- "Use the '-w' option to specify the type of watchpoint and "
- "the '-s' option to specify the byte size to watch for. "
- "If no '-w' option is specified, it defaults to write. "
- "If no '-s' option is specified, it defaults to the variable's "
- "byte size. "
- "Note that there are limited hardware resources for watchpoints. "
- "If watchpoint setting fails, consider disable/delete existing ones "
- "to free up resources.",
- nullptr,
- eCommandRequiresFrame |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_option_group (interpreter),
- m_option_watchpoint ()
- {
- SetHelpLong(
-R"(
+ CommandObjectWatchpointSetVariable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(
+ interpreter, "watchpoint set variable",
+ "Set a watchpoint on a variable. "
+ "Use the '-w' option to specify the type of watchpoint and "
+ "the '-s' option to specify the byte size to watch for. "
+ "If no '-w' option is specified, it defaults to write. "
+ "If no '-s' option is specified, it defaults to the variable's "
+ "byte size. "
+ "Note that there are limited hardware resources for watchpoints. "
+ "If watchpoint setting fails, consider disable/delete existing "
+ "ones "
+ "to free up resources.",
+ nullptr,
+ eCommandRequiresFrame | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_option_group(), m_option_watchpoint() {
+ SetHelpLong(
+ R"(
Examples:
(lldb) watchpoint set variable -w read_write my_global_var
-)" " Watches my_global_var for read/write access, with the region to watch \
-corresponding to the byte size of the data type."
- );
-
- CommandArgumentEntry arg;
- CommandArgumentData var_name_arg;
-
- // Define the only variant of this arg.
- var_name_arg.arg_type = eArgTypeVarName;
- var_name_arg.arg_repetition = eArgRepeatPlain;
-
- // Push the variant into the argument entry.
- arg.push_back (var_name_arg);
-
- // Push the data for the only argument into the m_arguments vector.
- m_arguments.push_back (arg);
-
- // Absorb the '-w' and '-s' options into our option group.
- m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
+)"
+ " Watches my_global_var for read/write access, with the region to watch \
+corresponding to the byte size of the data type.");
- ~CommandObjectWatchpointSetVariable() override = default;
+ CommandArgumentEntry arg;
+ CommandArgumentData var_name_arg;
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
+ // Define the only variant of this arg.
+ var_name_arg.arg_type = eArgTypeVarName;
+ var_name_arg.arg_repetition = eArgRepeatPlain;
+
+ // Push the variant into the argument entry.
+ arg.push_back(var_name_arg);
+
+ // Push the data for the only argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+
+ // Absorb the '-w' and '-s' options into our option group.
+ m_option_group.Append(&m_option_watchpoint, LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectWatchpointSetVariable() override = default;
+
+ Options *GetOptions() override { return &m_option_group; }
protected:
- static size_t GetVariableCallback (void *baton,
- const char *name,
- VariableList &variable_list)
- {
- Target *target = static_cast<Target *>(baton);
- if (target)
- {
- return target->GetImages().FindGlobalVariables (ConstString(name),
- true,
- UINT32_MAX,
- variable_list);
- }
- return 0;
+ static size_t GetVariableCallback(void *baton, const char *name,
+ VariableList &variable_list) {
+ Target *target = static_cast<Target *>(baton);
+ if (target) {
+ return target->GetImages().FindGlobalVariables(ConstString(name), true,
+ UINT32_MAX, variable_list);
+ }
+ return 0;
+ }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
+
+ // If no argument is present, issue an error message. There's no way to set
+ // a watchpoint.
+ if (command.GetArgumentCount() <= 0) {
+ result.GetErrorStream().Printf("error: required argument missing; "
+ "specify your program variable to watch "
+ "for\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- StackFrame *frame = m_exe_ctx.GetFramePtr();
-
- // If no argument is present, issue an error message. There's no way to set a watchpoint.
- if (command.GetArgumentCount() <= 0)
- {
- result.GetErrorStream().Printf("error: required argument missing; specify your program variable to watch for\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- // If no '-w' is specified, default to '-w write'.
- if (!m_option_watchpoint.watch_type_specified)
- {
- m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
- }
+ // If no '-w' is specified, default to '-w write'.
+ if (!m_option_watchpoint.watch_type_specified) {
+ m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
+ }
- // We passed the sanity check for the command.
- // Proceed to set the watchpoint now.
- lldb::addr_t addr = 0;
- size_t size = 0;
-
- VariableSP var_sp;
- ValueObjectSP valobj_sp;
- Stream &output_stream = result.GetOutputStream();
-
- // A simple watch variable gesture allows only one argument.
- if (command.GetArgumentCount() != 1)
- {
- result.GetErrorStream().Printf("error: specify exactly one variable to watch for\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ // We passed the sanity check for the command.
+ // Proceed to set the watchpoint now.
+ lldb::addr_t addr = 0;
+ size_t size = 0;
+
+ VariableSP var_sp;
+ ValueObjectSP valobj_sp;
+ Stream &output_stream = result.GetOutputStream();
+
+ // A simple watch variable gesture allows only one argument.
+ if (command.GetArgumentCount() != 1) {
+ result.GetErrorStream().Printf(
+ "error: specify exactly one variable to watch for\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- // Things have checked out ok...
- Error error;
- uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
- StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
- valobj_sp = frame->GetValueForVariableExpressionPath (command.GetArgumentAtIndex(0),
- eNoDynamicValues,
- expr_path_options,
- var_sp,
- error);
-
- if (!valobj_sp)
- {
- // Not in the frame; let's check the globals.
-
- VariableList variable_list;
- ValueObjectList valobj_list;
-
- Error error (Variable::GetValuesForVariableExpressionPath (command.GetArgumentAtIndex(0),
- m_exe_ctx.GetBestExecutionContextScope(),
- GetVariableCallback,
- target,
- variable_list,
- valobj_list));
-
- if (valobj_list.GetSize())
- valobj_sp = valobj_list.GetValueObjectAtIndex(0);
- }
-
- CompilerType compiler_type;
-
- if (valobj_sp)
- {
- AddressType addr_type;
- addr = valobj_sp->GetAddressOf(false, &addr_type);
- if (addr_type == eAddressTypeLoad)
- {
- // We're in business.
- // Find out the size of this variable.
- size = m_option_watchpoint.watch_size == 0 ? valobj_sp->GetByteSize()
- : m_option_watchpoint.watch_size;
- }
- compiler_type = valobj_sp->GetCompilerType();
- }
- else
- {
- const char *error_cstr = error.AsCString(nullptr);
- if (error_cstr)
- result.GetErrorStream().Printf("error: %s\n", error_cstr);
- else
- result.GetErrorStream().Printf ("error: unable to find any variable expression path that matches '%s'\n",
- command.GetArgumentAtIndex(0));
- return false;
- }
+ // Things have checked out ok...
+ Error error;
+ uint32_t expr_path_options =
+ StackFrame::eExpressionPathOptionCheckPtrVsMember |
+ StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
+ valobj_sp = frame->GetValueForVariableExpressionPath(
+ command.GetArgumentAtIndex(0), eNoDynamicValues, expr_path_options,
+ var_sp, error);
- // Now it's time to create the watchpoint.
- uint32_t watch_type = m_option_watchpoint.watch_type;
-
- error.Clear();
- Watchpoint *wp = target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error).get();
- if (wp)
- {
- wp->SetWatchSpec(command.GetArgumentAtIndex(0));
- wp->SetWatchVariable(true);
- if (var_sp && var_sp->GetDeclaration().GetFile())
- {
- StreamString ss;
- // True to show fullpath for declaration file.
- var_sp->GetDeclaration().DumpStopContext(&ss, true);
- wp->SetDeclInfo(ss.GetString());
- }
- output_stream.Printf("Watchpoint created: ");
- wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
- output_stream.EOL();
- result.SetStatus(eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64 ", variable expression='%s').\n",
- addr, (uint64_t)size, command.GetArgumentAtIndex(0));
- if (error.AsCString(nullptr))
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
- }
+ if (!valobj_sp) {
+ // Not in the frame; let's check the globals.
+
+ VariableList variable_list;
+ ValueObjectList valobj_list;
+
+ Error error(Variable::GetValuesForVariableExpressionPath(
+ command.GetArgumentAtIndex(0),
+ m_exe_ctx.GetBestExecutionContextScope(), GetVariableCallback, target,
+ variable_list, valobj_list));
+
+ if (valobj_list.GetSize())
+ valobj_sp = valobj_list.GetValueObjectAtIndex(0);
+ }
+
+ CompilerType compiler_type;
+
+ if (valobj_sp) {
+ AddressType addr_type;
+ addr = valobj_sp->GetAddressOf(false, &addr_type);
+ if (addr_type == eAddressTypeLoad) {
+ // We're in business.
+ // Find out the size of this variable.
+ size = m_option_watchpoint.watch_size == 0
+ ? valobj_sp->GetByteSize()
+ : m_option_watchpoint.watch_size;
+ }
+ compiler_type = valobj_sp->GetCompilerType();
+ } else {
+ const char *error_cstr = error.AsCString(nullptr);
+ if (error_cstr)
+ result.GetErrorStream().Printf("error: %s\n", error_cstr);
+ else
+ result.GetErrorStream().Printf("error: unable to find any variable "
+ "expression path that matches '%s'\n",
+ command.GetArgumentAtIndex(0));
+ return false;
+ }
- return result.Succeeded();
+ // Now it's time to create the watchpoint.
+ uint32_t watch_type = m_option_watchpoint.watch_type;
+
+ error.Clear();
+ Watchpoint *wp =
+ target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error)
+ .get();
+ if (wp) {
+ wp->SetWatchSpec(command.GetArgumentAtIndex(0));
+ wp->SetWatchVariable(true);
+ if (var_sp && var_sp->GetDeclaration().GetFile()) {
+ StreamString ss;
+ // True to show fullpath for declaration file.
+ var_sp->GetDeclaration().DumpStopContext(&ss, true);
+ wp->SetDeclInfo(ss.GetString());
+ }
+ output_stream.Printf("Watchpoint created: ");
+ wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
+ output_stream.EOL();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat(
+ "Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64
+ ", variable expression='%s').\n",
+ addr, (uint64_t)size, command.GetArgumentAtIndex(0));
+ if (error.AsCString(nullptr))
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
}
+ return result.Succeeded();
+ }
+
private:
- OptionGroupOptions m_option_group;
- OptionGroupWatchpoint m_option_watchpoint;
+ OptionGroupOptions m_option_group;
+ OptionGroupWatchpoint m_option_watchpoint;
};
//-------------------------------------------------------------------------
@@ -1096,208 +971,195 @@ private:
//-------------------------------------------------------------------------
#pragma mark Set
-class CommandObjectWatchpointSetExpression : public CommandObjectRaw
-{
+class CommandObjectWatchpointSetExpression : public CommandObjectRaw {
public:
- CommandObjectWatchpointSetExpression (CommandInterpreter &interpreter) :
- CommandObjectRaw(interpreter,
- "watchpoint set expression",
- "Set a watchpoint on an address by supplying an expression. "
- "Use the '-w' option to specify the type of watchpoint and "
- "the '-s' option to specify the byte size to watch for. "
- "If no '-w' option is specified, it defaults to write. "
- "If no '-s' option is specified, it defaults to the target's "
- "pointer byte size. "
- "Note that there are limited hardware resources for watchpoints. "
- "If watchpoint setting fails, consider disable/delete existing ones "
- "to free up resources.",
- nullptr,
- eCommandRequiresFrame |
- eCommandTryTargetAPILock |
- eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused ),
- m_option_group (interpreter),
- m_option_watchpoint ()
- {
- SetHelpLong(
-R"(
+ CommandObjectWatchpointSetExpression(CommandInterpreter &interpreter)
+ : CommandObjectRaw(
+ interpreter, "watchpoint set expression",
+ "Set a watchpoint on an address by supplying an expression. "
+ "Use the '-w' option to specify the type of watchpoint and "
+ "the '-s' option to specify the byte size to watch for. "
+ "If no '-w' option is specified, it defaults to write. "
+ "If no '-s' option is specified, it defaults to the target's "
+ "pointer byte size. "
+ "Note that there are limited hardware resources for watchpoints. "
+ "If watchpoint setting fails, consider disable/delete existing "
+ "ones "
+ "to free up resources.",
+ "",
+ eCommandRequiresFrame | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_option_group(), m_option_watchpoint() {
+ SetHelpLong(
+ R"(
Examples:
(lldb) watchpoint set expression -w write -s 1 -- foo + 32
- Watches write access for the 1-byte region pointed to by the address 'foo + 32')"
- );
-
- CommandArgumentEntry arg;
- CommandArgumentData expression_arg;
-
- // Define the only variant of this arg.
- expression_arg.arg_type = eArgTypeExpression;
- expression_arg.arg_repetition = eArgRepeatPlain;
-
- // Push the only variant into the argument entry.
- arg.push_back (expression_arg);
-
- // Push the data for the only argument into the m_arguments vector.
- m_arguments.push_back (arg);
-
- // Absorb the '-w' and '-s' options into our option group.
- m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
+ Watches write access for the 1-byte region pointed to by the address 'foo + 32')");
- ~CommandObjectWatchpointSetExpression() override = default;
+ CommandArgumentEntry arg;
+ CommandArgumentData expression_arg;
- // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
- bool
- WantsCompletion() override { return true; }
+ // Define the only variant of this arg.
+ expression_arg.arg_type = eArgTypeExpression;
+ expression_arg.arg_repetition = eArgRepeatPlain;
- Options *
- GetOptions () override
- {
- return &m_option_group;
- }
+ // Push the only variant into the argument entry.
+ arg.push_back(expression_arg);
-protected:
- bool
- DoExecute (const char *raw_command, CommandReturnObject &result) override
- {
- m_option_group.NotifyOptionParsingStarting(); // This is a raw command, so notify the option group
-
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- StackFrame *frame = m_exe_ctx.GetFramePtr();
-
- Args command(raw_command);
- const char *expr = nullptr;
- if (raw_command[0] == '-')
- {
- // We have some options and these options MUST end with --.
- const char *end_options = nullptr;
- const char *s = raw_command;
- while (s && s[0])
- {
- end_options = ::strstr (s, "--");
- if (end_options)
- {
- end_options += 2; // Get past the "--"
- if (::isspace (end_options[0]))
- {
- expr = end_options;
- while (::isspace (*expr))
- ++expr;
- break;
- }
- }
- s = end_options;
- }
-
- if (end_options)
- {
- Args args (llvm::StringRef(raw_command, end_options - raw_command));
- if (!ParseOptions (args, result))
- return false;
-
- Error error (m_option_group.NotifyOptionParsingFinished());
- if (error.Fail())
- {
- result.AppendError (error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- }
+ // Push the data for the only argument into the m_arguments vector.
+ m_arguments.push_back(arg);
- if (expr == nullptr)
- expr = raw_command;
+ // Absorb the '-w' and '-s' options into our option group.
+ m_option_group.Append(&m_option_watchpoint, LLDB_OPT_SET_ALL,
+ LLDB_OPT_SET_1);
+ m_option_group.Finalize();
+ }
- // If no argument is present, issue an error message. There's no way to set a watchpoint.
- if (command.GetArgumentCount() == 0)
- {
- result.GetErrorStream().Printf("error: required argument missing; specify an expression to evaulate into the address to watch for\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ ~CommandObjectWatchpointSetExpression() override = default;
- // If no '-w' is specified, default to '-w write'.
- if (!m_option_watchpoint.watch_type_specified)
- {
- m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
- }
+ // Overrides base class's behavior where WantsCompletion =
+ // !WantsRawCommandString.
+ bool WantsCompletion() override { return true; }
- // We passed the sanity check for the command.
- // Proceed to set the watchpoint now.
- lldb::addr_t addr = 0;
- size_t size = 0;
-
- ValueObjectSP valobj_sp;
-
- // Use expression evaluation to arrive at the address to watch.
- EvaluateExpressionOptions options;
- options.SetCoerceToId(false);
- options.SetUnwindOnError(true);
- options.SetKeepInMemory(false);
- options.SetTryAllThreads(true);
- options.SetTimeoutUsec(0);
-
- ExpressionResults expr_result = target->EvaluateExpression (expr,
- frame,
- valobj_sp,
- options);
- if (expr_result != eExpressionCompleted)
- {
- result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n");
- result.GetErrorStream().Printf("expression evaluated: %s\n", expr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ Options *GetOptions() override { return &m_option_group; }
- // Get the address to watch.
- bool success = false;
- addr = valobj_sp->GetValueAsUnsigned(0, &success);
- if (!success)
- {
- result.GetErrorStream().Printf("error: expression did not evaluate to an address\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- if (m_option_watchpoint.watch_size != 0)
- size = m_option_watchpoint.watch_size;
- else
- size = target->GetArchitecture().GetAddressByteSize();
-
- // Now it's time to create the watchpoint.
- uint32_t watch_type = m_option_watchpoint.watch_type;
-
- // Fetch the type from the value object, the type of the watched object is the pointee type
- /// of the expression, so convert to that if we found a valid type.
- CompilerType compiler_type(valobj_sp->GetCompilerType());
-
- Error error;
- Watchpoint *wp = target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error).get();
- if (wp)
- {
- Stream &output_stream = result.GetOutputStream();
- output_stream.Printf("Watchpoint created: ");
- wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
- output_stream.EOL();
- result.SetStatus(eReturnStatusSuccessFinishResult);
+protected:
+ bool DoExecute(const char *raw_command,
+ CommandReturnObject &result) override {
+ auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
+ m_option_group.NotifyOptionParsingStarting(
+ &exe_ctx); // This is a raw command, so notify the option group
+
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
+
+ Args command(raw_command);
+ const char *expr = nullptr;
+ if (raw_command[0] == '-') {
+ // We have some options and these options MUST end with --.
+ const char *end_options = nullptr;
+ const char *s = raw_command;
+ while (s && s[0]) {
+ end_options = ::strstr(s, "--");
+ if (end_options) {
+ end_options += 2; // Get past the "--"
+ if (::isspace(end_options[0])) {
+ expr = end_options;
+ while (::isspace(*expr))
+ ++expr;
+ break;
+ }
}
- else
- {
- result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64 ").\n",
- addr, (uint64_t)size);
- if (error.AsCString(nullptr))
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
+ s = end_options;
+ }
+
+ if (end_options) {
+ Args args(llvm::StringRef(raw_command, end_options - raw_command));
+ if (!ParseOptions(args, result))
+ return false;
+
+ Error error(m_option_group.NotifyOptionParsingFinished(&exe_ctx));
+ if (error.Fail()) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ }
+ }
- return result.Succeeded();
+ if (expr == nullptr)
+ expr = raw_command;
+
+ // If no argument is present, issue an error message. There's no way to set
+ // a watchpoint.
+ if (command.GetArgumentCount() == 0) {
+ result.GetErrorStream().Printf("error: required argument missing; "
+ "specify an expression to evaulate into "
+ "the address to watch for\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
+ // If no '-w' is specified, default to '-w write'.
+ if (!m_option_watchpoint.watch_type_specified) {
+ m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
+ }
+
+ // We passed the sanity check for the command.
+ // Proceed to set the watchpoint now.
+ lldb::addr_t addr = 0;
+ size_t size = 0;
+
+ ValueObjectSP valobj_sp;
+
+ // Use expression evaluation to arrive at the address to watch.
+ EvaluateExpressionOptions options;
+ options.SetCoerceToId(false);
+ options.SetUnwindOnError(true);
+ options.SetKeepInMemory(false);
+ options.SetTryAllThreads(true);
+ options.SetTimeout(llvm::None);
+
+ ExpressionResults expr_result =
+ target->EvaluateExpression(expr, frame, valobj_sp, options);
+ if (expr_result != eExpressionCompleted) {
+ result.GetErrorStream().Printf(
+ "error: expression evaluation of address to watch failed\n");
+ result.GetErrorStream().Printf("expression evaluated: %s\n", expr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Get the address to watch.
+ bool success = false;
+ addr = valobj_sp->GetValueAsUnsigned(0, &success);
+ if (!success) {
+ result.GetErrorStream().Printf(
+ "error: expression did not evaluate to an address\n");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (m_option_watchpoint.watch_size != 0)
+ size = m_option_watchpoint.watch_size;
+ else
+ size = target->GetArchitecture().GetAddressByteSize();
+
+ // Now it's time to create the watchpoint.
+ uint32_t watch_type = m_option_watchpoint.watch_type;
+
+ // Fetch the type from the value object, the type of the watched object is
+ // the pointee type
+ /// of the expression, so convert to that if we found a valid type.
+ CompilerType compiler_type(valobj_sp->GetCompilerType());
+
+ Error error;
+ Watchpoint *wp =
+ target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error)
+ .get();
+ if (wp) {
+ Stream &output_stream = result.GetOutputStream();
+ output_stream.Printf("Watchpoint created: ");
+ wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
+ output_stream.EOL();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64
+ ", size=%" PRIu64 ").\n",
+ addr, (uint64_t)size);
+ if (error.AsCString(nullptr))
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+
+ return result.Succeeded();
+ }
+
private:
- OptionGroupOptions m_option_group;
- OptionGroupWatchpoint m_option_watchpoint;
+ OptionGroupOptions m_option_group;
+ OptionGroupWatchpoint m_option_watchpoint;
};
//-------------------------------------------------------------------------
@@ -1305,19 +1167,22 @@ private:
//-------------------------------------------------------------------------
#pragma mark Set
-class CommandObjectWatchpointSet : public CommandObjectMultiword
-{
+class CommandObjectWatchpointSet : public CommandObjectMultiword {
public:
- CommandObjectWatchpointSet(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "watchpoint set", "Commands for setting a watchpoint.",
- "watchpoint set <subcommand> [<subcommand-options>]")
- {
-
- LoadSubCommand ("variable", CommandObjectSP (new CommandObjectWatchpointSetVariable (interpreter)));
- LoadSubCommand ("expression", CommandObjectSP (new CommandObjectWatchpointSetExpression (interpreter)));
- }
-
- ~CommandObjectWatchpointSet() override = default;
+ CommandObjectWatchpointSet(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "watchpoint set", "Commands for setting a watchpoint.",
+ "watchpoint set <subcommand> [<subcommand-options>]") {
+
+ LoadSubCommand(
+ "variable",
+ CommandObjectSP(new CommandObjectWatchpointSetVariable(interpreter)));
+ LoadSubCommand(
+ "expression",
+ CommandObjectSP(new CommandObjectWatchpointSetExpression(interpreter)));
+ }
+
+ ~CommandObjectWatchpointSet() override = default;
};
//-------------------------------------------------------------------------
@@ -1325,36 +1190,45 @@ public:
//-------------------------------------------------------------------------
#pragma mark MultiwordWatchpoint
-CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "watchpoint", "Commands for operating on watchpoints.",
- "watchpoint <subcommand> [<command-options>]")
-{
- CommandObjectSP list_command_object (new CommandObjectWatchpointList (interpreter));
- CommandObjectSP enable_command_object (new CommandObjectWatchpointEnable (interpreter));
- CommandObjectSP disable_command_object (new CommandObjectWatchpointDisable (interpreter));
- CommandObjectSP delete_command_object (new CommandObjectWatchpointDelete (interpreter));
- CommandObjectSP ignore_command_object (new CommandObjectWatchpointIgnore (interpreter));
- CommandObjectSP command_command_object (new CommandObjectWatchpointCommand (interpreter));
- CommandObjectSP modify_command_object (new CommandObjectWatchpointModify (interpreter));
- CommandObjectSP set_command_object (new CommandObjectWatchpointSet (interpreter));
-
- list_command_object->SetCommandName ("watchpoint list");
- enable_command_object->SetCommandName("watchpoint enable");
- disable_command_object->SetCommandName("watchpoint disable");
- delete_command_object->SetCommandName("watchpoint delete");
- ignore_command_object->SetCommandName("watchpoint ignore");
- command_command_object->SetCommandName ("watchpoint command");
- modify_command_object->SetCommandName("watchpoint modify");
- set_command_object->SetCommandName("watchpoint set");
-
- LoadSubCommand ("list", list_command_object);
- LoadSubCommand ("enable", enable_command_object);
- LoadSubCommand ("disable", disable_command_object);
- LoadSubCommand ("delete", delete_command_object);
- LoadSubCommand ("ignore", ignore_command_object);
- LoadSubCommand ("command", command_command_object);
- LoadSubCommand ("modify", modify_command_object);
- LoadSubCommand ("set", set_command_object);
+CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "watchpoint",
+ "Commands for operating on watchpoints.",
+ "watchpoint <subcommand> [<command-options>]") {
+ CommandObjectSP list_command_object(
+ new CommandObjectWatchpointList(interpreter));
+ CommandObjectSP enable_command_object(
+ new CommandObjectWatchpointEnable(interpreter));
+ CommandObjectSP disable_command_object(
+ new CommandObjectWatchpointDisable(interpreter));
+ CommandObjectSP delete_command_object(
+ new CommandObjectWatchpointDelete(interpreter));
+ CommandObjectSP ignore_command_object(
+ new CommandObjectWatchpointIgnore(interpreter));
+ CommandObjectSP command_command_object(
+ new CommandObjectWatchpointCommand(interpreter));
+ CommandObjectSP modify_command_object(
+ new CommandObjectWatchpointModify(interpreter));
+ CommandObjectSP set_command_object(
+ new CommandObjectWatchpointSet(interpreter));
+
+ list_command_object->SetCommandName("watchpoint list");
+ enable_command_object->SetCommandName("watchpoint enable");
+ disable_command_object->SetCommandName("watchpoint disable");
+ delete_command_object->SetCommandName("watchpoint delete");
+ ignore_command_object->SetCommandName("watchpoint ignore");
+ command_command_object->SetCommandName("watchpoint command");
+ modify_command_object->SetCommandName("watchpoint modify");
+ set_command_object->SetCommandName("watchpoint set");
+
+ LoadSubCommand("list", list_command_object);
+ LoadSubCommand("enable", enable_command_object);
+ LoadSubCommand("disable", disable_command_object);
+ LoadSubCommand("delete", delete_command_object);
+ LoadSubCommand("ignore", ignore_command_object);
+ LoadSubCommand("command", command_command_object);
+ LoadSubCommand("modify", modify_command_object);
+ LoadSubCommand("set", set_command_object);
}
CommandObjectMultiwordWatchpoint::~CommandObjectMultiwordWatchpoint() = default;
diff --git a/source/Commands/CommandObjectWatchpoint.h b/source/Commands/CommandObjectWatchpoint.h
index b1926dc2ad7d..adc0a81fa69c 100644
--- a/source/Commands/CommandObjectWatchpoint.h
+++ b/source/Commands/CommandObjectWatchpoint.h
@@ -16,8 +16,8 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/CommandObjectMultiword.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionGroupWatchpoint.h"
+#include "lldb/Interpreter/Options.h"
namespace lldb_private {
@@ -25,15 +25,14 @@ namespace lldb_private {
// CommandObjectMultiwordWatchpoint
//-------------------------------------------------------------------------
-class CommandObjectMultiwordWatchpoint : public CommandObjectMultiword
-{
+class CommandObjectMultiwordWatchpoint : public CommandObjectMultiword {
public:
- CommandObjectMultiwordWatchpoint (CommandInterpreter &interpreter);
+ CommandObjectMultiwordWatchpoint(CommandInterpreter &interpreter);
- ~CommandObjectMultiwordWatchpoint() override;
+ ~CommandObjectMultiwordWatchpoint() override;
- static bool
- VerifyWatchpointIDs(Target *target, Args &args, std::vector<uint32_t> &wp_ids);
+ static bool VerifyWatchpointIDs(Target *target, Args &args,
+ std::vector<uint32_t> &wp_ids);
};
} // namespace lldb_private
diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp
index 0ae1850b5e28..1860d4cca9fe 100644
--- a/source/Commands/CommandObjectWatchpointCommand.cpp
+++ b/source/Commands/CommandObjectWatchpointCommand.cpp
@@ -13,16 +13,16 @@
// Other libraries and framework includes
// Project includes
-#include "CommandObjectWatchpointCommand.h"
#include "CommandObjectWatchpoint.h"
+#include "CommandObjectWatchpointCommand.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/IOHandler.h"
+#include "lldb/Core/State.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Core/State.h"
using namespace lldb;
using namespace lldb_private;
@@ -31,43 +31,72 @@ using namespace lldb_private;
// CommandObjectWatchpointCommandAdd
//-------------------------------------------------------------------------
-class CommandObjectWatchpointCommandAdd :
- public CommandObjectParsed,
- public IOHandlerDelegateMultiline
-{
+// FIXME: "script-type" needs to have its contents determined dynamically, so
+// somebody can add a new scripting
+// language to lldb and have it pickable here without having to change this
+// enumeration by hand and rebuild lldb proper.
+
+static OptionEnumValueElement g_script_option_enumeration[4] = {
+ {eScriptLanguageNone, "command",
+ "Commands are in the lldb command interpreter language"},
+ {eScriptLanguagePython, "python", "Commands are in the Python language."},
+ {eSortOrderByName, "default-script",
+ "Commands are in the default scripting language."},
+ {0, nullptr, nullptr}};
+
+static OptionDefinition g_watchpoint_command_add_options[] = {
+ // clang-format off
+ { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner, "Specify a one-line watchpoint command inline. Be sure to surround it with quotes." },
+ { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Specify whether watchpoint command execution should terminate on error." },
+ { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." },
+ { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this watchpoint. Be sure to give a module name if appropriate." }
+ // clang-format on
+};
+
+class CommandObjectWatchpointCommandAdd : public CommandObjectParsed,
+ public IOHandlerDelegateMultiline {
public:
- CommandObjectWatchpointCommandAdd(CommandInterpreter &interpreter)
- : CommandObjectParsed(
- interpreter, "add",
- "Add a set of LLDB commands to a watchpoint, to be executed whenever the watchpoint is hit.", nullptr),
- IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand),
- m_options(interpreter)
- {
- SetHelpLong (
-R"(
+ CommandObjectWatchpointCommandAdd(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "add",
+ "Add a set of LLDB commands to a watchpoint, to be "
+ "executed whenever the watchpoint is hit.",
+ nullptr),
+ IOHandlerDelegateMultiline("DONE",
+ IOHandlerDelegate::Completion::LLDBCommand),
+ m_options() {
+ SetHelpLong(
+ R"(
General information about entering watchpoint commands
------------------------------------------------------
-)" "This command will prompt for commands to be executed when the specified \
+)"
+ "This command will prompt for commands to be executed when the specified \
watchpoint is hit. Each command is typed on its own line following the '> ' \
-prompt until 'DONE' is entered." R"(
+prompt until 'DONE' is entered."
+ R"(
-)" "Syntactic errors may not be detected when initially entered, and many \
+)"
+ "Syntactic errors may not be detected when initially entered, and many \
malformed commands can silently fail when executed. If your watchpoint commands \
-do not appear to be executing, double-check the command syntax." R"(
+do not appear to be executing, double-check the command syntax."
+ R"(
-)" "Note: You may enter any debugger command exactly as you would at the debugger \
+)"
+ "Note: You may enter any debugger command exactly as you would at the debugger \
prompt. There is no limit to the number of commands supplied, but do NOT enter \
-more than one command per line." R"(
+more than one command per line."
+ R"(
Special information about PYTHON watchpoint commands
----------------------------------------------------
-)" "You may enter either one or more lines of Python, including function \
+)"
+ "You may enter either one or more lines of Python, including function \
definitions or calls to functions that will have been imported by the time \
the code executes. Single line watchpoint commands will be interpreted 'as is' \
when the watchpoint is hit. Multiple lines of Python will be wrapped in a \
-generated function, and a call to the function will be attached to the watchpoint." R"(
+generated function, and a call to the function will be attached to the watchpoint."
+ R"(
This auto-generated function is passed in three arguments:
@@ -75,8 +104,10 @@ This auto-generated function is passed in three arguments:
wp: the watchpoint that was hit.
-)" "When specifying a python function with the --python-function option, you need \
-to supply the function name prepended by the module name:" R"(
+)"
+ "When specifying a python function with the --python-function option, you need \
+to supply the function name prepended by the module name:"
+ R"(
--python-function myutils.watchpoint_callback
@@ -85,16 +116,20 @@ The function itself must have the following prototype:
def watchpoint_callback(frame, wp):
# Your code goes here
-)" "The arguments are the same as the arguments passed to generated functions as \
+)"
+ "The arguments are the same as the arguments passed to generated functions as \
described above. Note that the global variable 'lldb.frame' will NOT be updated when \
this function is called, so be sure to use the 'frame' argument. The 'frame' argument \
can get you to the thread via frame.GetThread(), the thread can get you to the \
process via thread.GetProcess(), and the process can get you back to the target \
-via process.GetTarget()." R"(
+via process.GetTarget()."
+ R"(
-)" "Important Note: As Python code gets collected into functions, access to global \
+)"
+ "Important Note: As Python code gets collected into functions, access to global \
variables requires explicit scoping using the 'global' keyword. Be sure to use correct \
-Python syntax, including indentation, when entering Python watchpoint commands." R"(
+Python syntax, including indentation, when entering Python watchpoint commands."
+ R"(
Example Python one-line watchpoint command:
@@ -139,590 +174,516 @@ Enter your Python command(s). Type 'DONE' to end.
> print "Hit this watchpoint " + repr(wp_count) + " times!"
> DONE
-)" "In this case, since there is a reference to a global variable, \
+)"
+ "In this case, since there is a reference to a global variable, \
'wp_count', you will also need to make sure 'wp_count' exists and is \
-initialized:" R"(
+initialized:"
+ R"(
(lldb) script
>>> wp_count = 0
>>> quit()
-)" "Final Note: A warning that no watchpoint command was generated when there \
-are no syntax errors may indicate that a function was declared but never called."
- );
+)"
+ "Final Note: A warning that no watchpoint command was generated when there \
+are no syntax errors may indicate that a function was declared but never called.");
- CommandArgumentEntry arg;
- CommandArgumentData wp_id_arg;
+ CommandArgumentEntry arg;
+ CommandArgumentData wp_id_arg;
- // Define the first (and only) variant of this arg.
- wp_id_arg.arg_type = eArgTypeWatchpointID;
- wp_id_arg.arg_repetition = eArgRepeatPlain;
+ // Define the first (and only) variant of this arg.
+ wp_id_arg.arg_type = eArgTypeWatchpointID;
+ wp_id_arg.arg_repetition = eArgRepeatPlain;
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (wp_id_arg);
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(wp_id_arg);
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
- ~CommandObjectWatchpointCommandAdd() override = default;
+ ~CommandObjectWatchpointCommandAdd() override = default;
- Options *
- GetOptions () override
- {
- return &m_options;
- }
+ Options *GetOptions() override { return &m_options; }
- void
- IOHandlerActivated (IOHandler &io_handler) override
- {
- StreamFileSP output_sp(io_handler.GetOutputStreamFile());
- if (output_sp)
- {
- output_sp->PutCString("Enter your debugger command(s). Type 'DONE' to end.\n");
- output_sp->Flush();
- }
+ void IOHandlerActivated(IOHandler &io_handler) override {
+ StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+ if (output_sp) {
+ output_sp->PutCString(
+ "Enter your debugger command(s). Type 'DONE' to end.\n");
+ output_sp->Flush();
}
-
- void
- IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override
- {
- io_handler.SetIsDone(true);
-
- // The WatchpointOptions object is owned by the watchpoint or watchpoint location
- WatchpointOptions *wp_options = (WatchpointOptions *) io_handler.GetUserData();
- if (wp_options)
- {
- std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
- if (data_ap)
- {
- data_ap->user_source.SplitIntoLines(line);
- BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
- wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
- }
- }
+ }
+
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &line) override {
+ io_handler.SetIsDone(true);
+
+ // The WatchpointOptions object is owned by the watchpoint or watchpoint
+ // location
+ WatchpointOptions *wp_options =
+ (WatchpointOptions *)io_handler.GetUserData();
+ if (wp_options) {
+ std::unique_ptr<WatchpointOptions::CommandData> data_ap(
+ new WatchpointOptions::CommandData());
+ if (data_ap) {
+ data_ap->user_source.SplitIntoLines(line);
+ auto baton_sp = std::make_shared<WatchpointOptions::CommandBaton>(
+ std::move(data_ap));
+ wp_options->SetCallback(WatchpointOptionsCallbackFunction, baton_sp);
+ }
}
-
- void
- CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
- CommandReturnObject &result)
- {
- m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt
- *this, // IOHandlerDelegate
- true, // Run IOHandler in async mode
- wp_options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
+ }
+
+ void CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
+ CommandReturnObject &result) {
+ m_interpreter.GetLLDBCommandsFromIOHandler(
+ "> ", // Prompt
+ *this, // IOHandlerDelegate
+ true, // Run IOHandler in async mode
+ wp_options); // Baton for the "io_handler" that will be passed back into
+ // our IOHandlerDelegate functions
+ }
+
+ /// Set a one-liner as the callback for the watchpoint.
+ void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
+ const char *oneliner) {
+ std::unique_ptr<WatchpointOptions::CommandData> data_ap(
+ new WatchpointOptions::CommandData());
+
+ // It's necessary to set both user_source and script_source to the oneliner.
+ // The former is used to generate callback description (as in watchpoint
+ // command list)
+ // while the latter is used for Python to interpret during the actual
+ // callback.
+ data_ap->user_source.AppendString(oneliner);
+ data_ap->script_source.assign(oneliner);
+ data_ap->stop_on_error = m_options.m_stop_on_error;
+
+ auto baton_sp =
+ std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_ap));
+ wp_options->SetCallback(WatchpointOptionsCallbackFunction, baton_sp);
+ }
+
+ static bool
+ WatchpointOptionsCallbackFunction(void *baton,
+ StoppointCallbackContext *context,
+ lldb::user_id_t watch_id) {
+ bool ret_value = true;
+ if (baton == nullptr)
+ return true;
+
+ WatchpointOptions::CommandData *data =
+ (WatchpointOptions::CommandData *)baton;
+ StringList &commands = data->user_source;
+
+ if (commands.GetSize() > 0) {
+ ExecutionContext exe_ctx(context->exe_ctx_ref);
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ CommandReturnObject result;
+ Debugger &debugger = target->GetDebugger();
+ // Rig up the results secondary output stream to the debugger's, so the
+ // output will come out synchronously
+ // if the debugger is set up that way.
+
+ StreamSP output_stream(debugger.GetAsyncOutputStream());
+ StreamSP error_stream(debugger.GetAsyncErrorStream());
+ result.SetImmediateOutputStream(output_stream);
+ result.SetImmediateErrorStream(error_stream);
+
+ CommandInterpreterRunOptions options;
+ options.SetStopOnContinue(true);
+ options.SetStopOnError(data->stop_on_error);
+ options.SetEchoCommands(false);
+ options.SetPrintResults(true);
+ options.SetAddToHistory(false);
+
+ debugger.GetCommandInterpreter().HandleCommands(commands, &exe_ctx,
+ options, result);
+ result.GetImmediateOutputStream()->Flush();
+ result.GetImmediateErrorStream()->Flush();
+ }
}
-
- /// Set a one-liner as the callback for the watchpoint.
- void
- SetWatchpointCommandCallback (WatchpointOptions *wp_options,
- const char *oneliner)
- {
- std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
-
- // It's necessary to set both user_source and script_source to the oneliner.
- // The former is used to generate callback description (as in watchpoint command list)
- // while the latter is used for Python to interpret during the actual callback.
- data_ap->user_source.AppendString (oneliner);
- data_ap->script_source.assign (oneliner);
- data_ap->stop_on_error = m_options.m_stop_on_error;
-
- BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
- wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
+ return ret_value;
+ }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_use_commands(false), m_use_script_language(false),
+ m_script_language(eScriptLanguageNone), m_use_one_liner(false),
+ m_one_liner(), m_function_name() {}
+
+ ~CommandOptions() override = default;
+
+ Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'o':
+ m_use_one_liner = true;
+ m_one_liner = option_arg;
+ break;
+
+ case 's':
+ m_script_language = (lldb::ScriptLanguage)Args::StringToOptionEnum(
+ option_arg, GetDefinitions()[option_idx].enum_values,
+ eScriptLanguageNone, error);
+
+ m_use_script_language = (m_script_language == eScriptLanguagePython ||
+ m_script_language == eScriptLanguageDefault);
+ break;
+
+ case 'e': {
+ bool success = false;
+ m_stop_on_error = Args::StringToBoolean(option_arg, false, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "invalid value for stop-on-error: \"%s\"",
+ option_arg.str().c_str());
+ } break;
+
+ case 'F':
+ m_use_one_liner = false;
+ m_use_script_language = true;
+ m_function_name.assign(option_arg);
+ break;
+
+ default:
+ break;
+ }
+ return error;
}
-
- static bool
- WatchpointOptionsCallbackFunction (void *baton,
- StoppointCallbackContext *context,
- lldb::user_id_t watch_id)
- {
- bool ret_value = true;
- if (baton == nullptr)
- return true;
-
- WatchpointOptions::CommandData *data = (WatchpointOptions::CommandData *) baton;
- StringList &commands = data->user_source;
-
- if (commands.GetSize() > 0)
- {
- ExecutionContext exe_ctx (context->exe_ctx_ref);
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- CommandReturnObject result;
- Debugger &debugger = target->GetDebugger();
- // Rig up the results secondary output stream to the debugger's, so the output will come out synchronously
- // if the debugger is set up that way.
-
- StreamSP output_stream (debugger.GetAsyncOutputStream());
- StreamSP error_stream (debugger.GetAsyncErrorStream());
- result.SetImmediateOutputStream (output_stream);
- result.SetImmediateErrorStream (error_stream);
-
- CommandInterpreterRunOptions options;
- options.SetStopOnContinue (true);
- options.SetStopOnError (data->stop_on_error);
- options.SetEchoCommands (false);
- options.SetPrintResults (true);
- options.SetAddToHistory (false);
-
- debugger.GetCommandInterpreter().HandleCommands (commands,
- &exe_ctx,
- options,
- result);
- result.GetImmediateOutputStream()->Flush();
- result.GetImmediateErrorStream()->Flush();
- }
- }
- return ret_value;
- }
-
- class CommandOptions : public Options
- {
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter),
- m_use_commands (false),
- m_use_script_language (false),
- m_script_language (eScriptLanguageNone),
- m_use_one_liner (false),
- m_one_liner(),
- m_function_name()
- {
- }
- ~CommandOptions() override = default;
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg) override
- {
- Error error;
- const int short_option = m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- case 'o':
- m_use_one_liner = true;
- m_one_liner = option_arg;
- break;
-
- case 's':
- m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg,
- g_option_table[option_idx].enum_values,
- eScriptLanguageNone,
- error);
-
- m_use_script_language =
- (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault);
- break;
-
- case 'e':
- {
- bool success = false;
- m_stop_on_error = Args::StringToBoolean(option_arg, false, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid value for stop-on-error: \"%s\"", option_arg);
- }
- break;
-
- case 'F':
- m_use_one_liner = false;
- m_use_script_language = true;
- m_function_name.assign(option_arg);
- break;
-
- default:
- break;
- }
- return error;
- }
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_use_commands = true;
+ m_use_script_language = false;
+ m_script_language = eScriptLanguageNone;
- void
- OptionParsingStarting () override
- {
- m_use_commands = true;
- m_use_script_language = false;
- m_script_language = eScriptLanguageNone;
-
- m_use_one_liner = false;
- m_stop_on_error = true;
- m_one_liner.clear();
- m_function_name.clear();
- }
-
- const OptionDefinition*
- GetDefinitions () override
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
+ m_use_one_liner = false;
+ m_stop_on_error = true;
+ m_one_liner.clear();
+ m_function_name.clear();
+ }
- static OptionDefinition g_option_table[];
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_watchpoint_command_add_options);
+ }
- // Instance variables to hold the values for command options.
+ // Instance variables to hold the values for command options.
- bool m_use_commands;
- bool m_use_script_language;
- lldb::ScriptLanguage m_script_language;
+ bool m_use_commands;
+ bool m_use_script_language;
+ lldb::ScriptLanguage m_script_language;
- // Instance variables to hold the values for one_liner options.
- bool m_use_one_liner;
- std::string m_one_liner;
- bool m_stop_on_error;
- std::string m_function_name;
- };
+ // Instance variables to hold the values for one_liner options.
+ bool m_use_one_liner;
+ std::string m_one_liner;
+ bool m_stop_on_error;
+ std::string m_function_name;
+ };
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
-
- if (target == nullptr)
- {
- result.AppendError ("There is not a current executable; there are no watchpoints to which to add commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- const WatchpointList &watchpoints = target->GetWatchpointList();
- size_t num_watchpoints = watchpoints.GetSize();
-
- if (num_watchpoints == 0)
- {
- result.AppendError ("No watchpoints exist to have commands added");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- if (!m_options.m_use_script_language && !m_options.m_function_name.empty())
- {
- result.AppendError ("need to enable scripting to have a function run as a watchpoint command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- std::vector<uint32_t> valid_wp_ids;
- if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, valid_wp_ids))
- {
- result.AppendError("Invalid watchpoints specification.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- const size_t count = valid_wp_ids.size();
- for (size_t i = 0; i < count; ++i)
- {
- uint32_t cur_wp_id = valid_wp_ids.at (i);
- if (cur_wp_id != LLDB_INVALID_WATCH_ID)
- {
- Watchpoint *wp = target->GetWatchpointList().FindByID (cur_wp_id).get();
- // Sanity check wp first.
- if (wp == nullptr) continue;
-
- WatchpointOptions *wp_options = wp->GetOptions();
- // Skip this watchpoint if wp_options is not good.
- if (wp_options == nullptr) continue;
-
- // If we are using script language, get the script interpreter
- // in order to set or collect command callback. Otherwise, call
- // the methods associated with this object.
- if (m_options.m_use_script_language)
- {
- // Special handling for one-liner specified inline.
- if (m_options.m_use_one_liner)
- {
- m_interpreter.GetScriptInterpreter()->SetWatchpointCommandCallback (wp_options,
- m_options.m_one_liner.c_str());
- }
- // Special handling for using a Python function by name
- // instead of extending the watchpoint callback data structures, we just automatize
- // what the user would do manually: make their watchpoint command be a function call
- else if (!m_options.m_function_name.empty())
- {
- std::string oneliner(m_options.m_function_name);
- oneliner += "(frame, wp, internal_dict)";
- m_interpreter.GetScriptInterpreter()->SetWatchpointCommandCallback (wp_options,
- oneliner.c_str());
- }
- else
- {
- m_interpreter.GetScriptInterpreter()->CollectDataForWatchpointCommandCallback (wp_options,
- result);
- }
- }
- else
- {
- // Special handling for one-liner specified inline.
- if (m_options.m_use_one_liner)
- SetWatchpointCommandCallback (wp_options,
- m_options.m_one_liner.c_str());
- else
- CollectDataForWatchpointCommandCallback (wp_options,
- result);
- }
- }
- }
-
- return result.Succeeded();
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+
+ if (target == nullptr) {
+ result.AppendError("There is not a current executable; there are no "
+ "watchpoints to which to add commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-private:
- CommandOptions m_options;
-};
+ const WatchpointList &watchpoints = target->GetWatchpointList();
+ size_t num_watchpoints = watchpoints.GetSize();
-// FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting
-// language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper.
+ if (num_watchpoints == 0) {
+ result.AppendError("No watchpoints exist to have commands added");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
-static OptionEnumValueElement
-g_script_option_enumeration[4] =
-{
- { eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"},
- { eScriptLanguagePython, "python", "Commands are in the Python language."},
- { eSortOrderByName, "default-script", "Commands are in the default scripting language."},
- { 0, nullptr, nullptr }
-};
+ if (!m_options.m_use_script_language &&
+ !m_options.m_function_name.empty()) {
+ result.AppendError("need to enable scripting to have a function run as a "
+ "watchpoint command");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
-OptionDefinition
-CommandObjectWatchpointCommandAdd::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
- "Specify a one-line watchpoint command inline. Be sure to surround it with quotes." },
+ std::vector<uint32_t> valid_wp_ids;
+ if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command,
+ valid_wp_ids)) {
+ result.AppendError("Invalid watchpoints specification.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
- "Specify whether watchpoint command execution should terminate on error." },
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ const size_t count = valid_wp_ids.size();
+ for (size_t i = 0; i < count; ++i) {
+ uint32_t cur_wp_id = valid_wp_ids.at(i);
+ if (cur_wp_id != LLDB_INVALID_WATCH_ID) {
+ Watchpoint *wp = target->GetWatchpointList().FindByID(cur_wp_id).get();
+ // Sanity check wp first.
+ if (wp == nullptr)
+ continue;
+
+ WatchpointOptions *wp_options = wp->GetOptions();
+ // Skip this watchpoint if wp_options is not good.
+ if (wp_options == nullptr)
+ continue;
+
+ // If we are using script language, get the script interpreter
+ // in order to set or collect command callback. Otherwise, call
+ // the methods associated with this object.
+ if (m_options.m_use_script_language) {
+ // Special handling for one-liner specified inline.
+ if (m_options.m_use_one_liner) {
+ m_interpreter.GetScriptInterpreter()->SetWatchpointCommandCallback(
+ wp_options, m_options.m_one_liner.c_str());
+ }
+ // Special handling for using a Python function by name
+ // instead of extending the watchpoint callback data structures, we
+ // just automatize
+ // what the user would do manually: make their watchpoint command be a
+ // function call
+ else if (!m_options.m_function_name.empty()) {
+ std::string oneliner(m_options.m_function_name);
+ oneliner += "(frame, wp, internal_dict)";
+ m_interpreter.GetScriptInterpreter()->SetWatchpointCommandCallback(
+ wp_options, oneliner.c_str());
+ } else {
+ m_interpreter.GetScriptInterpreter()
+ ->CollectDataForWatchpointCommandCallback(wp_options, result);
+ }
+ } else {
+ // Special handling for one-liner specified inline.
+ if (m_options.m_use_one_liner)
+ SetWatchpointCommandCallback(wp_options,
+ m_options.m_one_liner.c_str());
+ else
+ CollectDataForWatchpointCommandCallback(wp_options, result);
+ }
+ }
+ }
- { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 0, eArgTypeNone,
- "Specify the language for the commands - if none is specified, the lldb command interpreter will be used."},
+ return result.Succeeded();
+ }
- { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction,
- "Give the name of a Python function to run as command for this watchpoint. Be sure to give a module name if appropriate."},
-
- { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
+private:
+ CommandOptions m_options;
};
//-------------------------------------------------------------------------
// CommandObjectWatchpointCommandDelete
//-------------------------------------------------------------------------
-class CommandObjectWatchpointCommandDelete : public CommandObjectParsed
-{
+class CommandObjectWatchpointCommandDelete : public CommandObjectParsed {
public:
- CommandObjectWatchpointCommandDelete (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "delete",
+ CommandObjectWatchpointCommandDelete(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "delete",
"Delete the set of commands from a watchpoint.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandArgumentData wp_id_arg;
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData wp_id_arg;
- // Define the first (and only) variant of this arg.
- wp_id_arg.arg_type = eArgTypeWatchpointID;
- wp_id_arg.arg_repetition = eArgRepeatPlain;
+ // Define the first (and only) variant of this arg.
+ wp_id_arg.arg_type = eArgTypeWatchpointID;
+ wp_id_arg.arg_repetition = eArgRepeatPlain;
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (wp_id_arg);
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(wp_id_arg);
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
- ~CommandObjectWatchpointCommandDelete() override = default;
+ ~CommandObjectWatchpointCommandDelete() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
-
- if (target == nullptr)
- {
- result.AppendError ("There is not a current executable; there are no watchpoints from which to delete commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+
+ if (target == nullptr) {
+ result.AppendError("There is not a current executable; there are no "
+ "watchpoints from which to delete commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- const WatchpointList &watchpoints = target->GetWatchpointList();
- size_t num_watchpoints = watchpoints.GetSize();
+ const WatchpointList &watchpoints = target->GetWatchpointList();
+ size_t num_watchpoints = watchpoints.GetSize();
- if (num_watchpoints == 0)
- {
- result.AppendError ("No watchpoints exist to have commands deleted");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_watchpoints == 0) {
+ result.AppendError("No watchpoints exist to have commands deleted");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- result.AppendError ("No watchpoint specified from which to delete the commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (command.GetArgumentCount() == 0) {
+ result.AppendError(
+ "No watchpoint specified from which to delete the commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- std::vector<uint32_t> valid_wp_ids;
- if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, valid_wp_ids))
- {
- result.AppendError("Invalid watchpoints specification.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ std::vector<uint32_t> valid_wp_ids;
+ if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command,
+ valid_wp_ids)) {
+ result.AppendError("Invalid watchpoints specification.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- const size_t count = valid_wp_ids.size();
- for (size_t i = 0; i < count; ++i)
- {
- uint32_t cur_wp_id = valid_wp_ids.at (i);
- if (cur_wp_id != LLDB_INVALID_WATCH_ID)
- {
- Watchpoint *wp = target->GetWatchpointList().FindByID (cur_wp_id).get();
- if (wp)
- wp->ClearCallback();
- }
- else
- {
- result.AppendErrorWithFormat("Invalid watchpoint ID: %u.\n",
- cur_wp_id);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- return result.Succeeded();
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ const size_t count = valid_wp_ids.size();
+ for (size_t i = 0; i < count; ++i) {
+ uint32_t cur_wp_id = valid_wp_ids.at(i);
+ if (cur_wp_id != LLDB_INVALID_WATCH_ID) {
+ Watchpoint *wp = target->GetWatchpointList().FindByID(cur_wp_id).get();
+ if (wp)
+ wp->ClearCallback();
+ } else {
+ result.AppendErrorWithFormat("Invalid watchpoint ID: %u.\n", cur_wp_id);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectWatchpointCommandList
//-------------------------------------------------------------------------
-class CommandObjectWatchpointCommandList : public CommandObjectParsed
-{
+class CommandObjectWatchpointCommandList : public CommandObjectParsed {
public:
- CommandObjectWatchpointCommandList (CommandInterpreter &interpreter) :
- CommandObjectParsed(interpreter,
- "list",
- "List the script or set of commands to be executed when the watchpoint is hit.",
- nullptr)
- {
- CommandArgumentEntry arg;
- CommandArgumentData wp_id_arg;
-
- // Define the first (and only) variant of this arg.
- wp_id_arg.arg_type = eArgTypeWatchpointID;
- wp_id_arg.arg_repetition = eArgRepeatPlain;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (wp_id_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
- }
+ CommandObjectWatchpointCommandList(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "list", "List the script or set of "
+ "commands to be executed when "
+ "the watchpoint is hit.",
+ nullptr) {
+ CommandArgumentEntry arg;
+ CommandArgumentData wp_id_arg;
- ~CommandObjectWatchpointCommandList() override = default;
+ // Define the first (and only) variant of this arg.
+ wp_id_arg.arg_type = eArgTypeWatchpointID;
+ wp_id_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg.push_back(wp_id_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg);
+ }
+
+ ~CommandObjectWatchpointCommandList() override = default;
protected:
- bool
- DoExecute (Args& command, CommandReturnObject &result) override
- {
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
-
- if (target == nullptr)
- {
- result.AppendError ("There is not a current executable; there are no watchpoints for which to list commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+
+ if (target == nullptr) {
+ result.AppendError("There is not a current executable; there are no "
+ "watchpoints for which to list commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- const WatchpointList &watchpoints = target->GetWatchpointList();
- size_t num_watchpoints = watchpoints.GetSize();
+ const WatchpointList &watchpoints = target->GetWatchpointList();
+ size_t num_watchpoints = watchpoints.GetSize();
- if (num_watchpoints == 0)
- {
- result.AppendError ("No watchpoints exist for which to list commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (num_watchpoints == 0) {
+ result.AppendError("No watchpoints exist for which to list commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- if (command.GetArgumentCount() == 0)
- {
- result.AppendError ("No watchpoint specified for which to list the commands");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ if (command.GetArgumentCount() == 0) {
+ result.AppendError(
+ "No watchpoint specified for which to list the commands");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- std::vector<uint32_t> valid_wp_ids;
- if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, valid_wp_ids))
- {
- result.AppendError("Invalid watchpoints specification.");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ std::vector<uint32_t> valid_wp_ids;
+ if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command,
+ valid_wp_ids)) {
+ result.AppendError("Invalid watchpoints specification.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- const size_t count = valid_wp_ids.size();
- for (size_t i = 0; i < count; ++i)
- {
- uint32_t cur_wp_id = valid_wp_ids.at (i);
- if (cur_wp_id != LLDB_INVALID_WATCH_ID)
- {
- Watchpoint *wp = target->GetWatchpointList().FindByID (cur_wp_id).get();
-
- if (wp)
- {
- const WatchpointOptions *wp_options = wp->GetOptions();
- if (wp_options)
- {
- // Get the callback baton associated with the current watchpoint.
- const Baton *baton = wp_options->GetBaton();
- if (baton)
- {
- result.GetOutputStream().Printf ("Watchpoint %u:\n", cur_wp_id);
- result.GetOutputStream().IndentMore ();
- baton->GetDescription(&result.GetOutputStream(), eDescriptionLevelFull);
- result.GetOutputStream().IndentLess ();
- }
- else
- {
- result.AppendMessageWithFormat ("Watchpoint %u does not have an associated command.\n",
- cur_wp_id);
- }
- }
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat("Invalid watchpoint ID: %u.\n", cur_wp_id);
- result.SetStatus (eReturnStatusFailed);
- }
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ const size_t count = valid_wp_ids.size();
+ for (size_t i = 0; i < count; ++i) {
+ uint32_t cur_wp_id = valid_wp_ids.at(i);
+ if (cur_wp_id != LLDB_INVALID_WATCH_ID) {
+ Watchpoint *wp = target->GetWatchpointList().FindByID(cur_wp_id).get();
+
+ if (wp) {
+ const WatchpointOptions *wp_options = wp->GetOptions();
+ if (wp_options) {
+ // Get the callback baton associated with the current watchpoint.
+ const Baton *baton = wp_options->GetBaton();
+ if (baton) {
+ result.GetOutputStream().Printf("Watchpoint %u:\n", cur_wp_id);
+ result.GetOutputStream().IndentMore();
+ baton->GetDescription(&result.GetOutputStream(),
+ eDescriptionLevelFull);
+ result.GetOutputStream().IndentLess();
+ } else {
+ result.AppendMessageWithFormat(
+ "Watchpoint %u does not have an associated command.\n",
+ cur_wp_id);
}
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("Invalid watchpoint ID: %u.\n",
+ cur_wp_id);
+ result.SetStatus(eReturnStatusFailed);
}
-
- return result.Succeeded();
+ }
}
+
+ return result.Succeeded();
+ }
};
//-------------------------------------------------------------------------
// CommandObjectWatchpointCommand
//-------------------------------------------------------------------------
-CommandObjectWatchpointCommand::CommandObjectWatchpointCommand(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "command", "Commands for adding, removing and examining LLDB commands "
- "executed when the watchpoint is hit (watchpoint 'commmands').",
- "command <sub-command> [<sub-command-options>] <watchpoint-id>")
-{
- CommandObjectSP add_command_object (new CommandObjectWatchpointCommandAdd (interpreter));
- CommandObjectSP delete_command_object (new CommandObjectWatchpointCommandDelete (interpreter));
- CommandObjectSP list_command_object (new CommandObjectWatchpointCommandList (interpreter));
-
- add_command_object->SetCommandName ("watchpoint command add");
- delete_command_object->SetCommandName ("watchpoint command delete");
- list_command_object->SetCommandName ("watchpoint command list");
-
- LoadSubCommand ("add", add_command_object);
- LoadSubCommand ("delete", delete_command_object);
- LoadSubCommand ("list", list_command_object);
+CommandObjectWatchpointCommand::CommandObjectWatchpointCommand(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "command",
+ "Commands for adding, removing and examining LLDB commands "
+ "executed when the watchpoint is hit (watchpoint 'commmands').",
+ "command <sub-command> [<sub-command-options>] <watchpoint-id>") {
+ CommandObjectSP add_command_object(
+ new CommandObjectWatchpointCommandAdd(interpreter));
+ CommandObjectSP delete_command_object(
+ new CommandObjectWatchpointCommandDelete(interpreter));
+ CommandObjectSP list_command_object(
+ new CommandObjectWatchpointCommandList(interpreter));
+
+ add_command_object->SetCommandName("watchpoint command add");
+ delete_command_object->SetCommandName("watchpoint command delete");
+ list_command_object->SetCommandName("watchpoint command list");
+
+ LoadSubCommand("add", add_command_object);
+ LoadSubCommand("delete", delete_command_object);
+ LoadSubCommand("list", list_command_object);
}
CommandObjectWatchpointCommand::~CommandObjectWatchpointCommand() = default;
diff --git a/source/Commands/CommandObjectWatchpointCommand.h b/source/Commands/CommandObjectWatchpointCommand.h
index d77b32a2fd4d..63152f2f68a6 100644
--- a/source/Commands/CommandObjectWatchpointCommand.h
+++ b/source/Commands/CommandObjectWatchpointCommand.h
@@ -16,10 +16,9 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-types.h"
-#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
-
+#include "lldb/Interpreter/Options.h"
+#include "lldb/lldb-types.h"
namespace lldb_private {
@@ -27,12 +26,11 @@ namespace lldb_private {
// CommandObjectMultiwordWatchpoint
//-------------------------------------------------------------------------
-class CommandObjectWatchpointCommand : public CommandObjectMultiword
-{
+class CommandObjectWatchpointCommand : public CommandObjectMultiword {
public:
- CommandObjectWatchpointCommand (CommandInterpreter &interpreter);
+ CommandObjectWatchpointCommand(CommandInterpreter &interpreter);
- ~CommandObjectWatchpointCommand() override;
+ ~CommandObjectWatchpointCommand() override;
};
} // namespace lldb_private