aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Commands
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Commands')
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp202
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp140
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp42
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp206
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp22
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp45
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp145
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp41
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp128
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp99
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp90
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h61
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp216
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp138
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h42
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp208
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectSession.h23
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp17
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp608
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp539
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp158
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h81
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp305
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h25
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp109
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp52
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp147
-rw-r--r--contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h49
-rw-r--r--contrib/llvm-project/lldb/source/Commands/Options.td122
30 files changed, 3145 insertions, 919 deletions
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp
index 48df77357201..0ea6d4288169 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp
@@ -9,16 +9,21 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSet.h"
+#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Variable.h"
+#include "lldb/Target/Language.h"
+#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/TildeExpressionResolver.h"
@@ -52,6 +57,7 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks(
{eDiskDirectoryCompletion, CommandCompletions::DiskDirectories},
{eSymbolCompletion, CommandCompletions::Symbols},
{eModuleCompletion, CommandCompletions::Modules},
+ {eModuleUUIDCompletion, CommandCompletions::ModuleUUIDs},
{eSettingsNameCompletion, CommandCompletions::SettingsNames},
{ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames},
{eArchitectureCompletion, CommandCompletions::ArchitectureNames},
@@ -59,6 +65,19 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks(
{eRegisterCompletion, CommandCompletions::Registers},
{eBreakpointCompletion, CommandCompletions::Breakpoints},
{eProcessPluginCompletion, CommandCompletions::ProcessPluginNames},
+ {eDisassemblyFlavorCompletion, CommandCompletions::DisassemblyFlavors},
+ {eTypeLanguageCompletion, CommandCompletions::TypeLanguages},
+ {eFrameIndexCompletion, CommandCompletions::FrameIndexes},
+ {eStopHookIDCompletion, CommandCompletions::StopHookIDs},
+ {eThreadIndexCompletion, CommandCompletions::ThreadIndexes},
+ {eWatchPointIDCompletion, CommandCompletions::WatchPointIDs},
+ {eBreakpointNameCompletion, CommandCompletions::BreakpointNames},
+ {eProcessIDCompletion, CommandCompletions::ProcessIDs},
+ {eProcessNameCompletion, CommandCompletions::ProcessNames},
+ {eRemoteDiskFileCompletion, CommandCompletions::RemoteDiskFiles},
+ {eRemoteDiskDirectoryCompletion,
+ CommandCompletions::RemoteDiskDirectories},
+ {eTypeCategoryNameCompletion, CommandCompletions::TypeCategoryNames},
{eNoCompletion, nullptr} // This one has to be last in the list.
};
@@ -472,6 +491,24 @@ void CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name,
DiskFilesOrDirectories(partial_file_name, true, matches, Resolver);
}
+void CommandCompletions::RemoteDiskFiles(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::PlatformSP platform_sp =
+ interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
+ if (platform_sp)
+ platform_sp->AutoCompleteDiskFileOrDirectory(request, false);
+}
+
+void CommandCompletions::RemoteDiskDirectories(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::PlatformSP platform_sp =
+ interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
+ if (platform_sp)
+ platform_sp->AutoCompleteDiskFileOrDirectory(request, true);
+}
+
void CommandCompletions::Modules(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
@@ -486,6 +523,24 @@ void CommandCompletions::Modules(CommandInterpreter &interpreter,
}
}
+void CommandCompletions::ModuleUUIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const ExecutionContext &exe_ctx = interpreter.GetExecutionContext();
+ if (!exe_ctx.HasTargetScope())
+ return;
+
+ exe_ctx.GetTargetPtr()->GetImages().ForEach(
+ [&request](const lldb::ModuleSP &module) {
+ StreamString strm;
+ module->GetDescription(strm.AsRawOstream(),
+ lldb::eDescriptionLevelInitial);
+ request.TryCompleteCurrentArg(module->GetUUID().GetAsString(),
+ strm.GetString());
+ return true;
+ });
+}
+
void CommandCompletions::Symbols(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
@@ -588,9 +643,154 @@ void CommandCompletions::Breakpoints(CommandInterpreter &interpreter,
}
}
+void CommandCompletions::BreakpointNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::TargetSP target = interpreter.GetDebugger().GetSelectedTarget();
+ if (!target)
+ return;
+
+ std::vector<std::string> name_list;
+ target->GetBreakpointNames(name_list);
+
+ for (const std::string &name : name_list)
+ request.TryCompleteCurrentArg(name);
+}
+
void CommandCompletions::ProcessPluginNames(CommandInterpreter &interpreter,
CompletionRequest &request,
SearchFilter *searcher) {
PluginManager::AutoCompleteProcessName(request.GetCursorArgumentPrefix(),
request);
-} \ No newline at end of file
+}
+void CommandCompletions::DisassemblyFlavors(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ // Currently the only valid options for disassemble -F are default, and for
+ // Intel architectures, att and intel.
+ static const char *flavors[] = {"default", "att", "intel"};
+ for (const char *flavor : flavors) {
+ request.TryCompleteCurrentArg(flavor);
+ }
+}
+
+void CommandCompletions::ProcessIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::PlatformSP platform_sp(interpreter.GetPlatform(true));
+ if (!platform_sp)
+ return;
+ ProcessInstanceInfoList process_infos;
+ ProcessInstanceInfoMatch match_info;
+ platform_sp->FindProcesses(match_info, process_infos);
+ for (const ProcessInstanceInfo &info : process_infos)
+ request.TryCompleteCurrentArg(std::to_string(info.GetProcessID()),
+ info.GetNameAsStringRef());
+}
+
+void CommandCompletions::ProcessNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ lldb::PlatformSP platform_sp(interpreter.GetPlatform(true));
+ if (!platform_sp)
+ return;
+ ProcessInstanceInfoList process_infos;
+ ProcessInstanceInfoMatch match_info;
+ platform_sp->FindProcesses(match_info, process_infos);
+ for (const ProcessInstanceInfo &info : process_infos)
+ request.TryCompleteCurrentArg(info.GetNameAsStringRef());
+}
+
+void CommandCompletions::TypeLanguages(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ for (int bit :
+ Language::GetLanguagesSupportingTypeSystems().bitvector.set_bits()) {
+ request.TryCompleteCurrentArg(
+ Language::GetNameForLanguageType(static_cast<lldb::LanguageType>(bit)));
+ }
+}
+
+void CommandCompletions::FrameIndexes(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const ExecutionContext &exe_ctx = interpreter.GetExecutionContext();
+ if (!exe_ctx.HasProcessScope())
+ return;
+
+ lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP();
+ const uint32_t frame_num = thread_sp->GetStackFrameCount();
+ for (uint32_t i = 0; i < frame_num; ++i) {
+ lldb::StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(i);
+ StreamString strm;
+ frame_sp->Dump(&strm, false, true);
+ request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
+ }
+}
+
+void CommandCompletions::StopHookIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const lldb::TargetSP target_sp =
+ interpreter.GetExecutionContext().GetTargetSP();
+ if (!target_sp)
+ return;
+
+ const size_t num = target_sp->GetNumStopHooks();
+ for (size_t idx = 0; idx < num; ++idx) {
+ StreamString strm;
+ // The value 11 is an offset to make the completion description looks
+ // neater.
+ strm.SetIndentLevel(11);
+ const Target::StopHookSP stophook_sp = target_sp->GetStopHookAtIndex(idx);
+ stophook_sp->GetDescription(&strm, lldb::eDescriptionLevelInitial);
+ request.TryCompleteCurrentArg(std::to_string(stophook_sp->GetID()),
+ strm.GetString());
+ }
+}
+
+void CommandCompletions::ThreadIndexes(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const ExecutionContext &exe_ctx = interpreter.GetExecutionContext();
+ if (!exe_ctx.HasProcessScope())
+ return;
+
+ ThreadList &threads = exe_ctx.GetProcessPtr()->GetThreadList();
+ lldb::ThreadSP thread_sp;
+ for (uint32_t idx = 0; (thread_sp = threads.GetThreadAtIndex(idx)); ++idx) {
+ StreamString strm;
+ thread_sp->GetStatus(strm, 0, 1, 1, true);
+ request.TryCompleteCurrentArg(std::to_string(thread_sp->GetIndexID()),
+ strm.GetString());
+ }
+}
+
+void CommandCompletions::WatchPointIDs(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ const ExecutionContext &exe_ctx = interpreter.GetExecutionContext();
+ if (!exe_ctx.HasTargetScope())
+ return;
+
+ const WatchpointList &wp_list = exe_ctx.GetTargetPtr()->GetWatchpointList();
+ const size_t wp_num = wp_list.GetSize();
+ for (size_t idx = 0; idx < wp_num; ++idx) {
+ const lldb::WatchpointSP wp_sp = wp_list.GetByIndex(idx);
+ StreamString strm;
+ wp_sp->Dump(&strm);
+ request.TryCompleteCurrentArg(std::to_string(wp_sp->GetID()),
+ strm.GetString());
+ }
+}
+
+void CommandCompletions::TypeCategoryNames(CommandInterpreter &interpreter,
+ CompletionRequest &request,
+ SearchFilter *searcher) {
+ DataVisualization::Categories::ForEach(
+ [&request](const lldb::TypeCategoryImplSP &category_sp) {
+ request.TryCompleteCurrentArg(category_sp->GetName(),
+ category_sp->GetDescription());
+ return true;
+ });
+}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp
index be7ef8a1b60b..0844c56cef2f 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -17,6 +17,7 @@
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueFileColonLine.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
#include "lldb/Interpreter/Options.h"
@@ -443,7 +444,22 @@ public:
case 'X':
m_source_regex_func_names.insert(std::string(option_arg));
break;
-
+
+ case 'y':
+ {
+ OptionValueFileColonLine value;
+ Status fcl_err = value.SetValueFromString(option_arg);
+ if (!fcl_err.Success()) {
+ error.SetErrorStringWithFormat(
+ "Invalid value for file:line specifier: %s",
+ fcl_err.AsCString());
+ } else {
+ m_filenames.AppendIfUnique(value.GetFileSpec());
+ m_line_num = value.GetLineNumber();
+ m_column = value.GetColumnNumber();
+ }
+ } break;
+
default:
llvm_unreachable("Unimplemented option");
}
@@ -1407,7 +1423,8 @@ public:
class CommandOptions : public Options {
public:
- CommandOptions() : Options(), m_use_dummy(false), m_force(false) {}
+ CommandOptions() : Options(), m_use_dummy(false), m_force(false),
+ m_delete_disabled(false) {}
~CommandOptions() override = default;
@@ -1424,6 +1441,10 @@ public:
case 'D':
m_use_dummy = true;
break;
+
+ case 'd':
+ m_delete_disabled = true;
+ break;
default:
llvm_unreachable("Unimplemented option");
@@ -1435,6 +1456,7 @@ public:
void OptionParsingStarting(ExecutionContext *execution_context) override {
m_use_dummy = false;
m_force = false;
+ m_delete_disabled = false;
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -1444,16 +1466,18 @@ public:
// Instance variables to hold the values for command options.
bool m_use_dummy;
bool m_force;
+ bool m_delete_disabled;
};
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
-
+ result.Clear();
+
std::unique_lock<std::recursive_mutex> lock;
target.GetBreakpointList().GetListMutex(lock);
- const BreakpointList &breakpoints = target.GetBreakpointList();
+ BreakpointList &breakpoints = target.GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -1463,7 +1487,7 @@ protected:
return false;
}
- if (command.empty()) {
+ if (command.empty() && !m_options.m_delete_disabled) {
if (!m_options.m_force &&
!m_interpreter.Confirm(
"About to delete all breakpoints, do you want to do that?",
@@ -1479,10 +1503,34 @@ protected:
} else {
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
- CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, &target, result, &valid_bp_ids,
- BreakpointName::Permissions::PermissionKinds::deletePerm);
-
+
+ if (m_options.m_delete_disabled) {
+ BreakpointIDList excluded_bp_ids;
+
+ if (!command.empty()) {
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, &target, result, &excluded_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::deletePerm);
+ }
+ for (auto breakpoint_sp : breakpoints.Breakpoints()) {
+ if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) {
+ BreakpointID bp_id(breakpoint_sp->GetID());
+ size_t pos = 0;
+ if (!excluded_bp_ids.FindBreakpointID(bp_id, &pos))
+ valid_bp_ids.AddBreakpointID(breakpoint_sp->GetID());
+ }
+ }
+ if (valid_bp_ids.GetSize() == 0) {
+ result.AppendError("No disabled breakpoints.");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ } else {
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
+ command, &target, result, &valid_bp_ids,
+ BreakpointName::Permissions::PermissionKinds::deletePerm);
+ }
+
if (result.Succeeded()) {
int delete_count = 0;
int disable_count = 0;
@@ -2081,7 +2129,79 @@ public:
return llvm::makeArrayRef(g_breakpoint_read_options);
}
- // Instance variables to hold the values for command options.
+ void HandleOptionArgumentCompletion(
+ CompletionRequest &request, OptionElementVector &opt_element_vector,
+ int opt_element_index, CommandInterpreter &interpreter) 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;
+
+ switch (GetDefinitions()[opt_defs_index].short_option) {
+ case 'f':
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ interpreter, CommandCompletions::eDiskFileCompletion, request,
+ nullptr);
+ break;
+
+ case 'N':
+ llvm::Optional<FileSpec> file_spec;
+ const llvm::StringRef dash_f("-f");
+ for (int arg_idx = 0; arg_idx < opt_arg_pos; arg_idx++) {
+ if (dash_f == request.GetParsedLine().GetArgumentAtIndex(arg_idx)) {
+ file_spec.emplace(
+ request.GetParsedLine().GetArgumentAtIndex(arg_idx + 1));
+ break;
+ }
+ }
+ if (!file_spec)
+ return;
+
+ FileSystem::Instance().Resolve(*file_spec);
+ Status error;
+ StructuredData::ObjectSP input_data_sp =
+ StructuredData::ParseJSONFromFile(*file_spec, error);
+ if (!error.Success())
+ return;
+
+ StructuredData::Array *bkpt_array = input_data_sp->GetAsArray();
+ if (!bkpt_array)
+ return;
+
+ const size_t num_bkpts = bkpt_array->GetSize();
+ for (size_t i = 0; i < num_bkpts; i++) {
+ StructuredData::ObjectSP bkpt_object_sp =
+ bkpt_array->GetItemAtIndex(i);
+ if (!bkpt_object_sp)
+ return;
+
+ StructuredData::Dictionary *bkpt_dict =
+ bkpt_object_sp->GetAsDictionary();
+ if (!bkpt_dict)
+ return;
+
+ StructuredData::ObjectSP bkpt_data_sp =
+ bkpt_dict->GetValueForKey(Breakpoint::GetSerializationKey());
+ if (!bkpt_data_sp)
+ return;
+
+ bkpt_dict = bkpt_data_sp->GetAsDictionary();
+ if (!bkpt_dict)
+ return;
+
+ StructuredData::Array *names_array;
+
+ if (!bkpt_dict->GetValueForKeyAsArray("Names", names_array))
+ return;
+
+ size_t num_names = names_array->GetSize();
+
+ for (size_t i = 0; i < num_names; i++) {
+ llvm::StringRef name;
+ if (names_array->GetItemAtIndexAsString(i, name))
+ request.TryCompleteCurrentArg(name);
+ }
+ }
+ }
+ }
std::string m_filename;
std::vector<std::string> m_names;
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
index 45df86589011..caaf3bfb482f 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -141,12 +141,16 @@ Example Python one-line breakpoint command:
(lldb) breakpoint command add -s python 1
Enter your Python command(s). Type 'DONE' to end.
-> print "Hit this breakpoint!"
-> DONE
+def function (frame, bp_loc, internal_dict):
+ """frame: the lldb.SBFrame for the location at which you stopped
+ bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
+ internal_dict: an LLDB support object not to be used"""
+ print("Hit this breakpoint!")
+ DONE
As a convenience, this also works for a short Python one-liner:
-(lldb) breakpoint command add -s python 1 -o 'import time; print time.asctime()'
+(lldb) breakpoint command add -s python 1 -o 'import time; print(time.asctime())'
(lldb) run
Launching '.../a.out' (x86_64)
(lldb) Fri Sep 10 12:17:45 2010
@@ -164,21 +168,14 @@ Example multiple line Python breakpoint command:
(lldb) breakpoint command add -s p 1
Enter your Python command(s). Type 'DONE' to end.
-> global bp_count
-> bp_count = bp_count + 1
-> print "Hit this breakpoint " + repr(bp_count) + " times!"
-> DONE
-
-Example multiple line Python breakpoint command, using function definition:
-
-(lldb) breakpoint command add -s python 1
-Enter your Python command(s). Type 'DONE' to end.
-> def breakpoint_output (bp_no):
-> out_string = "Hit breakpoint number " + repr (bp_no)
-> print out_string
-> return True
-> breakpoint_output (1)
-> DONE
+def function (frame, bp_loc, internal_dict):
+ """frame: the lldb.SBFrame for the location at which you stopped
+ bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
+ internal_dict: an LLDB support object not to be used"""
+ global bp_count
+ bp_count = bp_count + 1
+ print("Hit this breakpoint " + repr(bp_count) + " times!")
+ DONE
)"
"In this case, since there is a reference to a global variable, \
@@ -417,22 +414,23 @@ protected:
// to set or collect command callback. Otherwise, call the methods
// associated with this object.
if (m_options.m_use_script_language) {
+ Status error;
ScriptInterpreter *script_interp = GetDebugger().GetScriptInterpreter(
/*can_create=*/true, m_options.m_script_language);
// Special handling for one-liner specified inline.
if (m_options.m_use_one_liner) {
- script_interp->SetBreakpointCommandCallback(
+ error = script_interp->SetBreakpointCommandCallback(
m_bp_options_vec, m_options.m_one_liner.c_str());
} else if (!m_func_options.GetName().empty()) {
- Status error = script_interp->SetBreakpointCommandCallbackFunction(
+ error = script_interp->SetBreakpointCommandCallbackFunction(
m_bp_options_vec, m_func_options.GetName().c_str(),
m_func_options.GetStructuredData());
- if (!error.Success())
- result.SetError(error);
} else {
script_interp->CollectDataForBreakpointCommandCallback(
m_bp_options_vec, result);
}
+ if (!error.Success())
+ result.SetError(error);
} else {
// Special handling for one-liner specified inline.
if (m_options.m_use_one_liner)
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp
index d77e69c6f6a6..3b3cdde6ab9a 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp
@@ -6,15 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/StringRef.h"
-
#include "CommandObjectCommands.h"
#include "CommandObjectHelp.h"
+#include "CommandObjectRegexCommand.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/Interpreter/CommandHistory.h"
#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandObjectRegexCommand.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
@@ -24,161 +22,13 @@
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/StringList.h"
+#include "llvm/ADT/StringRef.h"
using namespace lldb;
using namespace lldb_private;
// CommandObjectCommandsSource
-#define LLDB_OPTIONS_history
-#include "CommandOptions.inc"
-
-class CommandObjectCommandsHistory : public CommandObjectParsed {
-public:
- CommandObjectCommandsHistory(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "command history",
- "Dump the history of commands in this session.\n"
- "Commands in the history list can be run again "
- "using \"!<INDEX>\". \"!-<OFFSET>\" will re-run "
- "the command that is <OFFSET> commands from the end"
- " of the list (counting the current command).",
- nullptr),
- m_options() {}
-
- ~CommandObjectCommandsHistory() override = default;
-
- Options *GetOptions() override { return &m_options; }
-
-protected:
- class CommandOptions : public Options {
- public:
- CommandOptions()
- : Options(), m_start_idx(0), m_stop_idx(0), m_count(0), m_clear(false) {
- }
-
- ~CommandOptions() override = default;
-
- Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
- ExecutionContext *execution_context) override {
- Status 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:
- llvm_unreachable("Unimplemented option");
- }
-
- return error;
- }
-
- void OptionParsingStarting(ExecutionContext *execution_context) override {
- m_start_idx.Clear();
- m_stop_idx.Clear();
- m_count.Clear();
- m_clear.Clear();
- }
-
- llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
- return llvm::makeArrayRef(g_history_options);
- }
-
- // 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 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);
- }
- }
- return result.Succeeded();
- }
-
- CommandOptions m_options;
-};
-
-// CommandObjectCommandsSource
-
#define LLDB_OPTIONS_source
#include "CommandOptions.inc"
@@ -614,7 +464,7 @@ protected:
OptionArgVectorSP(new OptionArgVector);
if (CommandObjectSP cmd_obj_sp =
- m_interpreter.GetCommandSPExact(cmd_obj.GetCommandName(), false)) {
+ m_interpreter.GetCommandSPExact(cmd_obj.GetCommandName())) {
if (m_interpreter.AliasExists(alias_command) ||
m_interpreter.UserCommandExists(alias_command)) {
result.AppendWarningWithFormat(
@@ -708,10 +558,9 @@ protected:
if (!args.empty()) {
CommandObjectSP tmp_sp =
- m_interpreter.GetCommandSPExact(cmd_obj->GetCommandName(), false);
+ m_interpreter.GetCommandSPExact(cmd_obj->GetCommandName());
if (use_subcommand)
- tmp_sp = m_interpreter.GetCommandSPExact(sub_cmd_obj->GetCommandName(),
- false);
+ tmp_sp = m_interpreter.GetCommandSPExact(sub_cmd_obj->GetCommandName());
args.GetCommandString(args_string);
}
@@ -767,6 +616,17 @@ public:
~CommandObjectCommandsUnalias() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0)
+ return;
+
+ for (const auto &ent : m_interpreter.GetAliases()) {
+ request.TryCompleteCurrentArg(ent.first, ent.second->GetHelp());
+ }
+ }
+
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
CommandObject::CommandMap::iterator pos;
@@ -848,6 +708,18 @@ public:
~CommandObjectCommandsDelete() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0)
+ return;
+
+ for (const auto &ent : m_interpreter.GetCommands()) {
+ if (ent.second->IsRemovable())
+ request.TryCompleteCurrentArg(ent.first, ent.second->GetHelp());
+ }
+ }
+
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
CommandObject::CommandMap::iterator pos;
@@ -1119,7 +991,7 @@ protected:
std::string subst(std::string(regex_sed.substr(
second_separator_char_pos + 1,
third_separator_char_pos - second_separator_char_pos - 1)));
- m_regex_cmd_up->AddRegexCommand(regex.c_str(), subst.c_str());
+ m_regex_cmd_up->AddRegexCommand(regex, subst);
}
return error;
}
@@ -1399,6 +1271,9 @@ protected:
case 'r':
// NO-OP
break;
+ case 'c':
+ relative_to_command_file = true;
+ break;
default:
llvm_unreachable("Unimplemented option");
}
@@ -1407,11 +1282,13 @@ protected:
}
void OptionParsingStarting(ExecutionContext *execution_context) override {
+ relative_to_command_file = false;
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
return llvm::makeArrayRef(g_script_import_options);
}
+ bool relative_to_command_file = false;
};
bool DoExecute(Args &command, CommandReturnObject &result) override {
@@ -1421,6 +1298,17 @@ protected:
return false;
}
+ FileSpec source_dir = {};
+ if (m_options.relative_to_command_file) {
+ source_dir = GetDebugger().GetCommandInterpreter().GetCurrentSourceDir();
+ if (!source_dir) {
+ result.AppendError("command script import -c can only be specified "
+ "from a command file");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
for (auto &entry : command.entries()) {
Status error;
@@ -1435,7 +1323,7 @@ protected:
// more)
m_exe_ctx.Clear();
if (GetDebugger().GetScriptInterpreter()->LoadScriptingModule(
- entry.c_str(), init_session, error)) {
+ entry.c_str(), init_session, error, nullptr, source_dir)) {
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
result.AppendErrorWithFormat("module importing failed: %s",
@@ -1850,8 +1738,6 @@ CommandObjectMultiwordCommands::CommandObjectMultiwordCommands(
CommandObjectSP(new CommandObjectCommandsDelete(interpreter)));
LoadSubCommand(
"regex", CommandObjectSP(new CommandObjectCommandsAddRegex(interpreter)));
- LoadSubCommand("history", CommandObjectSP(
- new CommandObjectCommandsHistory(interpreter)));
LoadSubCommand(
"script",
CommandObjectSP(new CommandObjectMultiwordCommandsScript(interpreter)));
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp
index b23adb087b49..58eaa3f973cb 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp
@@ -304,11 +304,8 @@ void CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
return;
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
-
- Target *target = exe_ctx.GetTargetPtr();
-
- if (!target)
- target = &GetDummyTarget();
+ Target *exe_target = exe_ctx.GetTargetPtr();
+ Target &target = exe_target ? *exe_target : GetDummyTarget();
unsigned cursor_pos = request.GetRawCursorPos();
// Get the full user input including the suffix. The suffix is necessary
@@ -342,7 +339,7 @@ void CommandObjectExpression::HandleCompletion(CompletionRequest &request) {
auto language = exe_ctx.GetFrameRef().GetLanguage();
Status error;
- lldb::UserExpressionSP expr(target->GetUserExpressionForLanguage(
+ lldb::UserExpressionSP expr(target.GetUserExpressionForLanguage(
code, llvm::StringRef(), language, UserExpression::eResultTypeAny,
options, nullptr, error));
if (error.Fail())
@@ -411,22 +408,19 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
// 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();
+ Target *exe_target = exe_ctx.GetTargetPtr();
+ Target &target = exe_target ? *exe_target : GetDummyTarget();
lldb::ValueObjectSP result_valobj_sp;
StackFrame *frame = exe_ctx.GetFramePtr();
- const EvaluateExpressionOptions options = GetEvalOptions(*target);
- ExpressionResults success = target->EvaluateExpression(
+ const EvaluateExpressionOptions options = GetEvalOptions(target);
+ 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 (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) {
+ if (!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());
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp
index 6ebad9b5c488..a656a99a1c71 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp
@@ -291,17 +291,12 @@ public:
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
- if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0)
+ if (request.GetCursorIndex() != 0)
return;
- lldb::ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
- const uint32_t frame_num = thread_sp->GetStackFrameCount();
- for (uint32_t i = 0; i < frame_num; ++i) {
- lldb::StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(i);
- StreamString strm;
- frame_sp->Dump(&strm, false, true);
- request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
- }
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eFrameIndexCompletion,
+ request, nullptr);
}
Options *GetOptions() override { return &m_options; }
@@ -898,12 +893,14 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command,
RegularExpressionSP(new RegularExpression(m_options.m_module));
auto func =
RegularExpressionSP(new RegularExpression(m_options.m_symbols.front()));
- StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func);
+ GetSelectedOrDummyTarget().GetFrameRecognizerManager().AddRecognizer(
+ recognizer_sp, module, func);
} else {
auto module = ConstString(m_options.m_module);
std::vector<ConstString> symbols(m_options.m_symbols.begin(),
m_options.m_symbols.end());
- StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, symbols);
+ GetSelectedOrDummyTarget().GetFrameRecognizerManager().AddRecognizer(
+ recognizer_sp, module, symbols);
}
#endif
@@ -921,7 +918,9 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
- StackFrameRecognizerManager::RemoveAllRecognizers();
+ GetSelectedOrDummyTarget()
+ .GetFrameRecognizerManager()
+ .RemoveAllRecognizers();
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
@@ -941,7 +940,7 @@ public:
if (request.GetCursorIndex() != 0)
return;
- StackFrameRecognizerManager::ForEach(
+ GetSelectedOrDummyTarget().GetFrameRecognizerManager().ForEach(
[&request](uint32_t rid, std::string rname, std::string module,
llvm::ArrayRef<lldb_private::ConstString> symbols,
bool regexp) {
@@ -973,7 +972,9 @@ protected:
return false;
}
- StackFrameRecognizerManager::RemoveAllRecognizers();
+ GetSelectedOrDummyTarget()
+ .GetFrameRecognizerManager()
+ .RemoveAllRecognizers();
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
@@ -993,7 +994,14 @@ protected:
return false;
}
- StackFrameRecognizerManager::RemoveRecognizerWithID(recognizer_id);
+ if (!GetSelectedOrDummyTarget()
+ .GetFrameRecognizerManager()
+ .RemoveRecognizerWithID(recognizer_id)) {
+ result.AppendErrorWithFormat("'%s' is not a valid recognizer id.\n",
+ command.GetArgumentAtIndex(0));
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
@@ -1011,7 +1019,7 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
bool any_printed = false;
- StackFrameRecognizerManager::ForEach(
+ GetSelectedOrDummyTarget().GetFrameRecognizerManager().ForEach(
[&result, &any_printed](
uint32_t recognizer_id, std::string name, std::string module,
llvm::ArrayRef<ConstString> symbols, bool regexp) {
@@ -1106,8 +1114,9 @@ protected:
return false;
}
- auto recognizer =
- StackFrameRecognizerManager::GetRecognizerForFrame(frame_sp);
+ auto recognizer = GetSelectedOrDummyTarget()
+ .GetFrameRecognizerManager()
+ .GetRecognizerForFrame(frame_sp);
Stream &output_stream = result.GetOutputStream();
output_stream.Printf("frame %d ", frame_index);
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp
index 474c37710149..7d5c642d0131 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp
@@ -33,8 +33,7 @@
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/StreamString.h"
-
-
+#include "llvm/Support/MathExtras.h"
#include <cinttypes>
#include <memory>
@@ -1281,29 +1280,6 @@ public:
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
@@ -1449,7 +1425,7 @@ protected:
"'%s' is not a valid hex string value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
- } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
result.AppendErrorWithFormat("Value 0x%" PRIx64
" is too large to fit in a %" PRIu64
" byte unsigned integer value.\n",
@@ -1477,7 +1453,7 @@ protected:
"'%s' is not a valid binary string value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
- } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
result.AppendErrorWithFormat("Value 0x%" PRIx64
" is too large to fit in a %" PRIu64
" byte unsigned integer value.\n",
@@ -1516,7 +1492,7 @@ protected:
"'%s' is not a valid signed decimal value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
- } else if (!SIntValueIsValidForSize(sval64, item_byte_size)) {
+ } else if (!llvm::isIntN(item_byte_size * 8, sval64)) {
result.AppendErrorWithFormat(
"Value %" PRIi64 " is too large or small to fit in a %" PRIu64
" byte signed integer value.\n",
@@ -1535,7 +1511,7 @@ protected:
entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
- } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
result.AppendErrorWithFormat("Value %" PRIu64
" is too large to fit in a %" PRIu64
" byte unsigned integer value.\n",
@@ -1552,7 +1528,7 @@ protected:
"'%s' is not a valid octal string value.\n", entry.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
- } else if (!UIntValueIsValidForSize(uval64, item_byte_size)) {
+ } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
result.AppendErrorWithFormat("Value %" PRIo64
" is too large to fit in a %" PRIu64
" byte unsigned integer value.\n",
@@ -1687,63 +1663,72 @@ public:
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
ProcessSP process_sp = m_exe_ctx.GetProcessSP();
- if (process_sp) {
- Status error;
- lldb::addr_t load_addr = m_prev_end_addr;
+ if (!process_sp) {
m_prev_end_addr = LLDB_INVALID_ADDRESS;
+ result.AppendError("invalid process");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ Status 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);
+ return false;
+ }
- 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());
+ if (argc == 1) {
+ auto load_addr_str = command[0].ref();
+ load_addr = OptionArgParser::ToAddress(&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);
- } else {
- if (command.GetArgumentCount() == 1) {
- auto load_addr_str = command[0].ref();
- load_addr = OptionArgParser::ToAddress(&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 false;
+ }
+ }
- lldb_private::MemoryRegionInfo range_info;
- error = process_sp->GetMemoryRegionInfo(load_addr, range_info);
- if (error.Success()) {
- lldb_private::Address addr;
- ConstString name = range_info.GetName();
- 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.AppendMessageWithFormatv(
- "[{0:x16}-{1:x16}) {2:r}{3:w}{4:x}{5}{6}{7}{8}\n",
- range_info.GetRange().GetRangeBase(),
- range_info.GetRange().GetRangeEnd(), range_info.GetReadable(),
- range_info.GetWritable(), range_info.GetExecutable(),
- name ? " " : "", name, section_name ? " " : "", section_name);
- m_prev_end_addr = range_info.GetRange().GetRangeEnd();
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- result.SetStatus(eReturnStatusFailed);
- result.AppendErrorWithFormat("%s\n", error.AsCString());
+ lldb_private::MemoryRegionInfo range_info;
+ error = process_sp->GetMemoryRegionInfo(load_addr, range_info);
+ if (error.Success()) {
+ lldb_private::Address addr;
+ ConstString name = range_info.GetName();
+ 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();
}
}
- } else {
- m_prev_end_addr = LLDB_INVALID_ADDRESS;
- result.AppendError("invalid process");
- result.SetStatus(eReturnStatusFailed);
+
+ result.AppendMessageWithFormatv(
+ "[{0:x16}-{1:x16}) {2:r}{3:w}{4:x}{5}{6}{7}{8}",
+ range_info.GetRange().GetRangeBase(),
+ range_info.GetRange().GetRangeEnd(), range_info.GetReadable(),
+ range_info.GetWritable(), range_info.GetExecutable(), name ? " " : "",
+ name, section_name ? " " : "", section_name);
+ MemoryRegionInfo::OptionalBool memory_tagged =
+ range_info.GetMemoryTagged();
+ if (memory_tagged == MemoryRegionInfo::OptionalBool::eYes)
+ result.AppendMessage("memory tagging: enabled");
+
+ m_prev_end_addr = range_info.GetRange().GetRangeEnd();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
}
- return result.Succeeded();
+
+ result.SetStatus(eReturnStatusFailed);
+ result.AppendErrorWithFormat("%s\n", error.AsCString());
+ return false;
}
const char *GetRepeatCommand(Args &current_command_args,
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp
index 9033cfebf46b..0f20a1d88bd9 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp
@@ -261,11 +261,32 @@ CommandObjectProxy::CommandObjectProxy(CommandInterpreter &interpreter,
CommandObjectProxy::~CommandObjectProxy() = default;
+Options *CommandObjectProxy::GetOptions() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetOptions();
+ return CommandObject::GetOptions();
+}
+
+llvm::StringRef CommandObjectProxy::GetHelp() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetHelp();
+ return CommandObject::GetHelp();
+}
+
+llvm::StringRef CommandObjectProxy::GetSyntax() {
+ CommandObject *proxy_command = GetProxyCommandObject();
+ if (proxy_command)
+ return proxy_command->GetSyntax();
+ return CommandObject::GetSyntax();
+}
+
llvm::StringRef CommandObjectProxy::GetHelpLong() {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
return proxy_command->GetHelpLong();
- return llvm::StringRef();
+ return CommandObject::GetHelpLong();
}
bool CommandObjectProxy::IsRemovable() const {
@@ -293,7 +314,9 @@ CommandObjectMultiword *CommandObjectProxy::GetAsMultiwordCommand() {
void CommandObjectProxy::GenerateHelpText(Stream &result) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
- return proxy_command->GenerateHelpText(result);
+ proxy_command->GenerateHelpText(result);
+ else
+ CommandObject::GenerateHelpText(result);
}
lldb::CommandObjectSP
@@ -345,13 +368,6 @@ bool CommandObjectProxy::WantsCompletion() {
return false;
}
-Options *CommandObjectProxy::GetOptions() {
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->GetOptions();
- return nullptr;
-}
-
void CommandObjectProxy::HandleCompletion(CompletionRequest &request) {
CommandObject *proxy_command = GetProxyCommandObject();
if (proxy_command)
@@ -373,12 +389,15 @@ const char *CommandObjectProxy::GetRepeatCommand(Args &current_command_args,
return nullptr;
}
+llvm::StringRef CommandObjectProxy::GetUnsupportedError() {
+ return "command is not implemented";
+}
+
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);
+ result.SetError(GetUnsupportedError());
return false;
}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp
index fcc8af6f915c..f306da3c8543 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "CommandObjectPlatform.h"
+#include "CommandOptionsProcessLaunch.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -392,7 +393,8 @@ public:
"or for a platform by name.",
"platform settings", 0),
m_options(),
- m_option_working_dir(LLDB_OPT_SET_1, false, "working-dir", 'w', 0,
+ m_option_working_dir(LLDB_OPT_SET_1, false, "working-dir", 'w',
+ CommandCompletions::eRemoteDiskDirectoryCompletion,
eArgTypePath,
"The working directory for the platform.") {
m_options.Append(&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
@@ -485,6 +487,15 @@ public:
~CommandObjectPlatformFOpen() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() == 0)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eRemoteDiskFileCompletion, request, nullptr);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
PlatformSP platform_sp(
GetDebugger().GetPlatformList().GetSelectedPlatform());
@@ -817,6 +828,19 @@ public:
~CommandObjectPlatformGetFile() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() == 0)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eRemoteDiskFileCompletion, request, nullptr);
+ else if (request.GetCursorIndex() == 1)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ request, nullptr);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
// If the number of arguments is incorrect, issue an error message.
if (args.GetArgumentCount() != 2) {
@@ -882,6 +906,17 @@ public:
~CommandObjectPlatformGetSize() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() != 0)
+ return;
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eRemoteDiskFileCompletion,
+ request, nullptr);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
// If the number of arguments is incorrect, issue an error message.
if (args.GetArgumentCount() != 1) {
@@ -927,6 +962,19 @@ public:
~CommandObjectPlatformPutFile() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() == 0)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ request, nullptr);
+ else if (request.GetCursorIndex() == 1)
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eRemoteDiskFileCompletion, request, nullptr);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
const char *src = args.GetArgumentAtIndex(0);
const char *dst = args.GetArgumentAtIndex(1);
@@ -1036,7 +1084,7 @@ protected:
return result.Succeeded();
}
- ProcessLaunchCommandOptions m_options;
+ CommandOptionsProcessLaunch m_options;
};
// "platform process list"
@@ -1331,6 +1379,14 @@ public:
~CommandObjectPlatformProcessInfo() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eProcessIDCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &args, CommandReturnObject &result) override {
Target *target = GetDebugger().GetSelectedTarget().get();
@@ -1447,46 +1503,6 @@ public:
return llvm::makeArrayRef(g_platform_process_attach_options);
}
- void HandleOptionArgumentCompletion(
- CompletionRequest &request, OptionElementVector &opt_element_vector,
- int opt_element_index, CommandInterpreter &interpreter) 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...
-
- // Are we in the name?
- if (GetDefinitions()[opt_defs_index].short_option != 'n')
- return;
-
- // 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 = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
-
- PlatformSP platform_sp(interpreter.GetPlatform(true));
- if (!platform_sp)
- return;
-
- ProcessInstanceInfoList process_infos;
- ProcessInstanceInfoMatch match_info;
- if (partial_name) {
- match_info.GetProcessInfo().GetExecutableFile().SetFile(
- partial_name, FileSpec::Style::native);
- match_info.SetNameMatchType(NameMatch::StartsWith);
- }
- platform_sp->FindProcesses(match_info, process_infos);
- const uint32_t num_matches = process_infos.size();
- if (num_matches == 0)
- return;
-
- for (uint32_t i = 0; i < num_matches; ++i) {
- request.AddCompletion(process_infos[i].GetNameAsStringRef());
- }
- return;
- }
-
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
@@ -1596,6 +1612,16 @@ public:
else
m_timeout = std::chrono::seconds(timeout_sec);
break;
+ case 's': {
+ if (option_arg.empty()) {
+ error.SetErrorStringWithFormat(
+ "missing shell interpreter path for option -i|--interpreter.");
+ return error;
+ }
+
+ m_shell_interpreter = option_arg.str();
+ break;
+ }
default:
llvm_unreachable("Unimplemented option");
}
@@ -1606,10 +1632,12 @@ public:
void OptionParsingStarting(ExecutionContext *execution_context) override {
m_timeout.reset();
m_use_host_platform = false;
+ m_shell_interpreter.clear();
}
Timeout<std::micro> m_timeout = std::chrono::seconds(10);
bool m_use_host_platform;
+ std::string m_shell_interpreter;
};
CommandObjectPlatformShell(CommandInterpreter &interpreter)
@@ -1635,7 +1663,6 @@ public:
const bool is_alias = !raw_command_line.contains("platform");
OptionsWithRaw args(raw_command_line);
- const char *expr = args.GetRawPart().c_str();
if (args.HasArgs())
if (!ParseOptions(args.GetArgs(), result))
@@ -1647,6 +1674,8 @@ public:
return false;
}
+ llvm::StringRef cmd = args.GetRawPart();
+
PlatformSP platform_sp(
m_options.m_use_host_platform
? Platform::GetHostPlatform()
@@ -1657,7 +1686,8 @@ public:
std::string output;
int status = -1;
int signo = -1;
- error = (platform_sp->RunShellCommand(expr, working_dir, &status, &signo,
+ error = (platform_sp->RunShellCommand(m_options.m_shell_interpreter, cmd,
+ working_dir, &status, &signo,
&output, m_options.m_timeout));
if (!output.empty())
result.GetOutputStream().PutCString(output);
@@ -1706,6 +1736,16 @@ public:
~CommandObjectPlatformInstall() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ request, nullptr);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
if (args.GetArgumentCount() != 2) {
result.AppendError("platform target-install takes two arguments");
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp
index f86779d85b5f..35835f638557 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "CommandObjectProcess.h"
+#include "CommandOptionsProcessLaunch.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
@@ -48,19 +49,19 @@ protected:
state = process->GetState();
if (process->IsAlive() && state != eStateConnected) {
- char message[1024];
+ std::string message;
if (process->GetState() == eStateAttaching)
- ::snprintf(message, sizeof(message),
- "There is a pending attach, abort it and %s?",
- m_new_process_action.c_str());
+ message =
+ llvm::formatv("There is a pending attach, abort it and {0}?",
+ m_new_process_action);
else if (process->GetShouldDetach())
- ::snprintf(message, sizeof(message),
- "There is a running process, detach from it and %s?",
- m_new_process_action.c_str());
+ message = llvm::formatv(
+ "There is a running process, detach from it and {0}?",
+ m_new_process_action);
else
- ::snprintf(message, sizeof(message),
- "There is a running process, kill it and %s?",
- m_new_process_action.c_str());
+ message =
+ llvm::formatv("There is a running process, kill it and {0}?",
+ m_new_process_action);
if (!m_interpreter.Confirm(message, true)) {
result.SetStatus(eReturnStatusFailed);
@@ -184,6 +185,9 @@ protected:
else
m_options.launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
+ if (target->GetInheritTCC())
+ m_options.launch_info.GetFlags().Set(eLaunchFlagInheritTCCFromParent);
+
if (target->GetDetachOnError())
m_options.launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
@@ -248,7 +252,7 @@ protected:
return result.Succeeded();
}
- ProcessLaunchCommandOptions m_options;
+ CommandOptionsProcessLaunch m_options;
};
#define LLDB_OPTIONS_process_attach
@@ -317,49 +321,6 @@ public:
return llvm::makeArrayRef(g_process_attach_options);
}
- void HandleOptionArgumentCompletion(
- CompletionRequest &request, OptionElementVector &opt_element_vector,
- int opt_element_index, CommandInterpreter &interpreter) 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;
-
- switch (GetDefinitions()[opt_defs_index].short_option) {
- case 'n': {
- // 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 = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos);
-
- PlatformSP platform_sp(interpreter.GetPlatform(true));
- if (!platform_sp)
- return;
- ProcessInstanceInfoList process_infos;
- ProcessInstanceInfoMatch match_info;
- if (partial_name) {
- match_info.GetProcessInfo().GetExecutableFile().SetFile(
- partial_name, FileSpec::Style::native);
- match_info.SetNameMatchType(NameMatch::StartsWith);
- }
- platform_sp->FindProcesses(match_info, process_infos);
- const size_t num_matches = process_infos.size();
- if (num_matches == 0)
- return;
- for (size_t i = 0; i < num_matches; ++i) {
- request.AddCompletion(process_infos[i].GetNameAsStringRef());
- }
- } break;
-
- case 'P':
- CommandCompletions::InvokeCommonCompletionCallbacks(
- interpreter, CommandCompletions::eProcessPluginCompletion, request,
- nullptr);
- break;
- }
- }
-
- // Instance variables to hold the values for command options.
-
ProcessAttachInfo attach_info;
};
@@ -404,7 +365,6 @@ protected:
result.AppendError(error.AsCString("Error creating target"));
return false;
}
- GetDebugger().GetTargetList().SetSelectedTarget(target);
}
// Record the old executable module, we want to issue a warning if the
@@ -920,6 +880,17 @@ public:
~CommandObjectProcessLoad() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (!m_exe_ctx.HasProcessScope())
+ return;
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_options; }
protected:
@@ -985,6 +956,24 @@ public:
~CommandObjectProcessUnload() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+
+ if (request.GetCursorIndex() || !m_exe_ctx.HasProcessScope())
+ return;
+
+ Process *process = m_exe_ctx.GetProcessPtr();
+
+ const std::vector<lldb::addr_t> &tokens = process->GetImageTokens();
+ const size_t token_num = tokens.size();
+ for (size_t i = 0; i < token_num; ++i) {
+ if (tokens[i] == LLDB_INVALID_IMAGE_TOKEN)
+ continue;
+ request.TryCompleteCurrentArg(std::to_string(i));
+ }
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Process *process = m_exe_ctx.GetProcessPtr();
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp
index d0c7bbd3abf8..d4d15bea9a8e 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectQuit.cpp
@@ -103,5 +103,9 @@ bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) {
CommandInterpreter::eBroadcastBitQuitCommandReceived;
m_interpreter.BroadcastEvent(event_type);
result.SetStatus(eReturnStatusQuit);
+
+ if (m_interpreter.GetSaveSessionOnQuit())
+ m_interpreter.SaveTranscript(result);
+
return true;
}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp
new file mode 100644
index 000000000000..1bf29d3c047b
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp
@@ -0,0 +1,90 @@
+//===-- CommandObjectRegexCommand.cpp -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectRegexCommand.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// CommandObjectRegexCommand constructor
+CommandObjectRegexCommand::CommandObjectRegexCommand(
+ CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help,
+ llvm::StringRef syntax, uint32_t max_matches, uint32_t completion_type_mask,
+ bool is_removable)
+ : CommandObjectRaw(interpreter, name, help, syntax),
+ m_max_matches(max_matches), m_completion_type_mask(completion_type_mask),
+ m_entries(), m_is_removable(is_removable) {}
+
+// Destructor
+CommandObjectRegexCommand::~CommandObjectRegexCommand() {}
+
+bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) {
+ EntryCollection::const_iterator pos, end = m_entries.end();
+ for (pos = m_entries.begin(); pos != end; ++pos) {
+ llvm::SmallVector<llvm::StringRef, 4> matches;
+ if (pos->regex.Execute(command, &matches)) {
+ std::string new_command(pos->command);
+ char percent_var[8];
+ size_t idx, percent_var_idx;
+ for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) {
+ if (match_idx < matches.size()) {
+ const std::string match_str = matches[match_idx].str();
+ const int percent_var_len =
+ ::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx);
+ for (idx = 0; (percent_var_idx = new_command.find(
+ percent_var, idx)) != std::string::npos;) {
+ new_command.erase(percent_var_idx, percent_var_len);
+ new_command.insert(percent_var_idx, match_str);
+ idx += percent_var_idx + match_str.size();
+ }
+ }
+ }
+ // Interpret the new command and return this as the result!
+ if (m_interpreter.GetExpandRegexAliases())
+ result.GetOutputStream().Printf("%s\n", new_command.c_str());
+ // Pass in true for "no context switching". The command that called us
+ // should have set up the context appropriately, we shouldn't have to
+ // redo that.
+ return m_interpreter.HandleCommand(
+ new_command.c_str(), eLazyBoolCalculate, result, nullptr, true, true);
+ }
+ }
+ result.SetStatus(eReturnStatusFailed);
+ if (!GetSyntax().empty())
+ result.AppendError(GetSyntax());
+ else
+ result.GetOutputStream() << "Command contents '" << command
+ << "' failed to match any "
+ "regular expression in the '"
+ << m_cmd_name << "' regex ";
+ return false;
+}
+
+bool CommandObjectRegexCommand::AddRegexCommand(llvm::StringRef re_cstr,
+ llvm::StringRef command_cstr) {
+ m_entries.resize(m_entries.size() + 1);
+ // Only add the regular expression if it compiles
+ m_entries.back().regex = RegularExpression(re_cstr);
+ if (m_entries.back().regex.IsValid()) {
+ m_entries.back().command = command_cstr.str();
+ return true;
+ }
+ // The regex didn't compile...
+ m_entries.pop_back();
+ return false;
+}
+
+void CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
+ if (m_completion_type_mask) {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), m_completion_type_mask, request, nullptr);
+ }
+}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h
new file mode 100644
index 000000000000..2f65c2cd815d
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h
@@ -0,0 +1,61 @@
+//===-- CommandObjectRegexCommand.h -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_INTERPRETER_COMMANDOBJECTREGEXCOMMAND_H
+#define LLDB_INTERPRETER_COMMANDOBJECTREGEXCOMMAND_H
+
+#include <list>
+
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Utility/CompletionRequest.h"
+#include "lldb/Utility/RegularExpression.h"
+
+namespace lldb_private {
+
+// CommandObjectRegexCommand
+
+class CommandObjectRegexCommand : public CommandObjectRaw {
+public:
+ CommandObjectRegexCommand(CommandInterpreter &interpreter,
+ llvm::StringRef name, llvm::StringRef help,
+ llvm::StringRef syntax, uint32_t max_matches,
+ uint32_t completion_type_mask, bool is_removable);
+
+ ~CommandObjectRegexCommand() override;
+
+ bool IsRemovable() const override { return m_is_removable; }
+
+ bool AddRegexCommand(llvm::StringRef re_cstr, llvm::StringRef command_cstr);
+
+ bool HasRegexEntries() const { return !m_entries.empty(); }
+
+ void HandleCompletion(CompletionRequest &request) override;
+
+protected:
+ bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
+
+ struct Entry {
+ RegularExpression regex;
+ std::string command;
+ };
+
+ typedef std::list<Entry> EntryCollection;
+ const uint32_t m_max_matches;
+ const uint32_t m_completion_type_mask;
+ EntryCollection m_entries;
+ bool m_is_removable;
+
+private:
+ CommandObjectRegexCommand(const CommandObjectRegexCommand &) = delete;
+ const CommandObjectRegexCommand &
+ operator=(const CommandObjectRegexCommand &) = delete;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_INTERPRETER_COMMANDOBJECTREGEXCOMMAND_H
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp
index 104130b70b2b..55f34c05d11d 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectReproducer.cpp
@@ -27,10 +27,12 @@ using namespace lldb_private::repro;
enum ReproducerProvider {
eReproducerProviderCommands,
eReproducerProviderFiles,
+ eReproducerProviderSymbolFiles,
eReproducerProviderGDB,
eReproducerProviderProcessInfo,
eReproducerProviderVersion,
eReproducerProviderWorkingDirectory,
+ eReproducerProviderHomeDirectory,
eReproducerProviderNone
};
@@ -46,6 +48,11 @@ static constexpr OptionEnumValueElement g_reproducer_provider_type[] = {
"Files",
},
{
+ eReproducerProviderSymbolFiles,
+ "symbol-files",
+ "Symbol Files",
+ },
+ {
eReproducerProviderGDB,
"gdb",
"GDB Remote Packets",
@@ -66,6 +73,11 @@ static constexpr OptionEnumValueElement g_reproducer_provider_type[] = {
"Working Directory",
},
{
+ eReproducerProviderHomeDirectory,
+ "home",
+ "Home Directory",
+ },
+ {
eReproducerProviderNone,
"none",
"None",
@@ -104,6 +116,9 @@ static constexpr OptionEnumValues ReproducerSignalType() {
#define LLDB_OPTIONS_reproducer_xcrash
#include "CommandOptions.inc"
+#define LLDB_OPTIONS_reproducer_verify
+#include "CommandOptions.inc"
+
template <typename T>
llvm::Expected<T> static ReadFromYAML(StringRef filename) {
auto error_or_file = MemoryBuffer::getFile(filename);
@@ -122,6 +137,38 @@ llvm::Expected<T> static ReadFromYAML(StringRef filename) {
return t;
}
+static void SetError(CommandReturnObject &result, Error err) {
+ result.GetErrorStream().Printf("error: %s\n",
+ toString(std::move(err)).c_str());
+ result.SetStatus(eReturnStatusFailed);
+}
+
+/// Create a loader from the given path if specified. Otherwise use the current
+/// loader used for replay.
+static Loader *
+GetLoaderFromPathOrCurrent(llvm::Optional<Loader> &loader_storage,
+ CommandReturnObject &result,
+ FileSpec reproducer_path) {
+ if (reproducer_path) {
+ loader_storage.emplace(reproducer_path);
+ Loader *loader = &(*loader_storage);
+ if (Error err = loader->LoadIndex()) {
+ // This is a hard error and will set the result to eReturnStatusFailed.
+ SetError(result, std::move(err));
+ return nullptr;
+ }
+ return loader;
+ }
+
+ if (Loader *loader = Reproducer::Instance().GetLoader())
+ return loader;
+
+ // This is a soft error because this is expected to fail during capture.
+ result.SetError("Not specifying a reproducer is only support during replay.");
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return nullptr;
+}
+
class CommandObjectReproducerGenerate : public CommandObjectParsed {
public:
CommandObjectReproducerGenerate(CommandInterpreter &interpreter)
@@ -145,6 +192,10 @@ protected:
auto &r = Reproducer::Instance();
if (auto generator = r.GetGenerator()) {
generator->Keep();
+ if (llvm::Error e = repro::Finalize(r.GetReproducerPath())) {
+ SetError(result, std::move(e));
+ return result.Succeeded();
+ }
} else if (r.IsReplaying()) {
// Make this operation a NO-OP in replay mode.
result.SetStatus(eReturnStatusSuccessFinishNoResult);
@@ -300,12 +351,6 @@ protected:
}
};
-static void SetError(CommandReturnObject &result, Error err) {
- result.GetErrorStream().Printf("error: %s\n",
- toString(std::move(err)).c_str());
- result.SetStatus(eReturnStatusFailed);
-}
-
class CommandObjectReproducerDump : public CommandObjectParsed {
public:
CommandObjectReproducerDump(CommandInterpreter &interpreter)
@@ -370,29 +415,11 @@ protected:
return false;
}
- // If no reproducer path is specified, use the loader currently used for
- // replay. Otherwise create a new loader just for dumping.
llvm::Optional<Loader> loader_storage;
- Loader *loader = nullptr;
- if (!m_options.file) {
- loader = Reproducer::Instance().GetLoader();
- if (loader == nullptr) {
- result.SetError(
- "Not specifying a reproducer is only support during replay.");
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return false;
- }
- } else {
- loader_storage.emplace(m_options.file);
- loader = &(*loader_storage);
- if (Error err = loader->LoadIndex()) {
- SetError(result, std::move(err));
- return false;
- }
- }
-
- // If we get here we should have a valid loader.
- assert(loader);
+ Loader *loader =
+ GetLoaderFromPathOrCurrent(loader_storage, result, m_options.file);
+ if (!loader)
+ return false;
switch (m_options.provider) {
case eReproducerProviderFiles: {
@@ -421,6 +448,29 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
+ case eReproducerProviderSymbolFiles: {
+ Expected<std::string> symbol_files =
+ loader->LoadBuffer<SymbolFileProvider>();
+ if (!symbol_files) {
+ SetError(result, symbol_files.takeError());
+ return false;
+ }
+
+ std::vector<SymbolFileProvider::Entry> entries;
+ llvm::yaml::Input yin(*symbol_files);
+ yin >> entries;
+
+ for (const auto &entry : entries) {
+ result.AppendMessageWithFormat("- uuid: %s\n",
+ entry.uuid.c_str());
+ result.AppendMessageWithFormat(" module path: %s\n",
+ entry.module_path.c_str());
+ result.AppendMessageWithFormat(" symbol path: %s\n",
+ entry.symbol_path.c_str());
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
case eReproducerProviderVersion: {
Expected<std::string> version = loader->LoadBuffer<VersionProvider>();
if (!version) {
@@ -433,7 +483,7 @@ protected:
}
case eReproducerProviderWorkingDirectory: {
Expected<std::string> cwd =
- loader->LoadBuffer<WorkingDirectoryProvider>();
+ repro::GetDirectoryFrom<WorkingDirectoryProvider>(loader);
if (!cwd) {
SetError(result, cwd.takeError());
return false;
@@ -442,6 +492,17 @@ protected:
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
+ case eReproducerProviderHomeDirectory: {
+ Expected<std::string> home =
+ repro::GetDirectoryFrom<HomeDirectoryProvider>(loader);
+ if (!home) {
+ SetError(result, home.takeError());
+ return false;
+ }
+ result.AppendMessage(*home);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
case eReproducerProviderCommands: {
std::unique_ptr<repro::MultiLoader<repro::CommandProvider>> multi_loader =
repro::MultiLoader<repro::CommandProvider>::Create(loader);
@@ -537,6 +598,101 @@ private:
CommandOptions m_options;
};
+class CommandObjectReproducerVerify : public CommandObjectParsed {
+public:
+ CommandObjectReproducerVerify(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "reproducer verify",
+ "Verify the contents of a reproducer. "
+ "If no reproducer is specified during replay, it "
+ "verifies the content of the current reproducer.",
+ nullptr) {}
+
+ ~CommandObjectReproducerVerify() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options(), file() {}
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'f':
+ file.SetFile(option_arg, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(file);
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ file.Clear();
+ }
+
+ ArrayRef<OptionDefinition> GetDefinitions() override {
+ return makeArrayRef(g_reproducer_verify_options);
+ }
+
+ FileSpec file;
+ };
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (!command.empty()) {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
+ return false;
+ }
+
+ llvm::Optional<Loader> loader_storage;
+ Loader *loader =
+ GetLoaderFromPathOrCurrent(loader_storage, result, m_options.file);
+ if (!loader)
+ return false;
+
+ bool errors = false;
+ auto error_callback = [&](llvm::StringRef error) {
+ errors = true;
+ result.AppendError(error);
+ };
+
+ bool warnings = false;
+ auto warning_callback = [&](llvm::StringRef warning) {
+ warnings = true;
+ result.AppendWarning(warning);
+ };
+
+ auto note_callback = [&](llvm::StringRef warning) {
+ result.AppendMessage(warning);
+ };
+
+ Verifier verifier(loader);
+ verifier.Verify(error_callback, warning_callback, note_callback);
+
+ if (warnings || errors) {
+ result.AppendMessage("reproducer verification failed");
+ result.SetStatus(eReturnStatusFailed);
+ } else {
+ result.AppendMessage("reproducer verification succeeded");
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+
+ return result.Succeeded();
+ }
+
+private:
+ CommandOptions m_options;
+};
+
CommandObjectReproducer::CommandObjectReproducer(
CommandInterpreter &interpreter)
: CommandObjectMultiword(
@@ -559,6 +715,8 @@ CommandObjectReproducer::CommandObjectReproducer(
new CommandObjectReproducerStatus(interpreter)));
LoadSubCommand("dump",
CommandObjectSP(new CommandObjectReproducerDump(interpreter)));
+ LoadSubCommand("verify", CommandObjectSP(
+ new CommandObjectReproducerVerify(interpreter)));
LoadSubCommand("xcrash", CommandObjectSP(
new CommandObjectReproducerXCrash(interpreter)));
}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp
new file mode 100644
index 000000000000..9dadf11ebfc8
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.cpp
@@ -0,0 +1,138 @@
+//===-- CommandObjectScript.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectScript.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/Host/Config.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "lldb/Utility/Args.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static constexpr OptionEnumValueElement g_script_option_enumeration[] = {
+ {
+ eScriptLanguagePython,
+ "python",
+ "Python",
+ },
+ {
+ eScriptLanguageLua,
+ "lua",
+ "Lua",
+ },
+ {
+ eScriptLanguageNone,
+ "default",
+ "The default scripting language.",
+ },
+};
+
+static constexpr OptionEnumValues ScriptOptionEnum() {
+ return OptionEnumValues(g_script_option_enumeration);
+}
+
+#define LLDB_OPTIONS_script
+#include "CommandOptions.inc"
+
+Status CommandObjectScript::CommandOptions::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'l':
+ language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum(
+ option_arg, GetDefinitions()[option_idx].enum_values,
+ eScriptLanguageNone, error);
+ if (!error.Success())
+ error.SetErrorStringWithFormat("unrecognized value for language '%s'",
+ option_arg.str().c_str());
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+}
+
+void CommandObjectScript::CommandOptions::OptionParsingStarting(
+ ExecutionContext *execution_context) {
+ language = lldb::eScriptLanguageNone;
+}
+
+llvm::ArrayRef<OptionDefinition>
+CommandObjectScript::CommandOptions::GetDefinitions() {
+ return llvm::makeArrayRef(g_script_options);
+}
+
+CommandObjectScript::CommandObjectScript(CommandInterpreter &interpreter)
+ : CommandObjectRaw(
+ interpreter, "script",
+ "Invoke the script interpreter with provided code and display any "
+ "results. Start the interactive interpreter if no code is supplied.",
+ "script [--language <scripting-language> --] [<script-code>]") {}
+
+CommandObjectScript::~CommandObjectScript() {}
+
+bool CommandObjectScript::DoExecute(llvm::StringRef command,
+ CommandReturnObject &result) {
+ // Try parsing the language option but when the command contains a raw part
+ // separated by the -- delimiter.
+ OptionsWithRaw raw_args(command);
+ if (raw_args.HasArgs()) {
+ if (!ParseOptions(raw_args.GetArgs(), result))
+ return false;
+ command = raw_args.GetRawPart();
+ }
+
+ lldb::ScriptLanguage language =
+ (m_options.language == lldb::eScriptLanguageNone)
+ ? m_interpreter.GetDebugger().GetScriptLanguage()
+ : m_options.language;
+
+ if (language == lldb::eScriptLanguageNone) {
+ result.AppendError(
+ "the script-lang setting is set to none - scripting not available");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ ScriptInterpreter *script_interpreter =
+ GetDebugger().GetScriptInterpreter(true, language);
+
+ if (script_interpreter == nullptr) {
+ result.AppendError("no script interpreter");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Script might change Python code we use for formatting. Make sure we keep
+ // up to date with it.
+ DataVisualization::ForceUpdate();
+
+ if (command.empty()) {
+ script_interpreter->ExecuteInterpreterLoop();
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
+
+ // We can do better when reporting the status of one-liner script execution.
+ if (script_interpreter->ExecuteOneLine(command, &result))
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
+
+ return result.Succeeded();
+}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h
new file mode 100644
index 000000000000..b9fee7124818
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectScript.h
@@ -0,0 +1,42 @@
+//===-- CommandObjectScript.h -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H
+#define LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H
+
+#include "lldb/Interpreter/CommandObject.h"
+
+namespace lldb_private {
+
+class CommandObjectScript : public CommandObjectRaw {
+public:
+ CommandObjectScript(CommandInterpreter &interpreter);
+ ~CommandObjectScript() override;
+ Options *GetOptions() override { return &m_options; }
+
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() {}
+ ~CommandOptions() override = default;
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override;
+ void OptionParsingStarting(ExecutionContext *execution_context) override;
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+ lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
+ };
+
+protected:
+ bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
+
+private:
+ CommandOptions m_options;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_INTERPRETER_COMMANDOBJECTSCRIPT_H
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp
new file mode 100644
index 000000000000..c2cdfa29a3f6
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp
@@ -0,0 +1,208 @@
+#include "CommandObjectSession.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionValue.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/OptionValueUInt64.h"
+#include "lldb/Interpreter/Options.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+class CommandObjectSessionSave : public CommandObjectParsed {
+public:
+ CommandObjectSessionSave(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "session save",
+ "Save the current session transcripts to a file.\n"
+ "If no file if specified, transcripts will be "
+ "saved to a temporary file.",
+ "session save [file]") {
+ CommandArgumentEntry arg1;
+ arg1.emplace_back(eArgTypePath, eArgRepeatOptional);
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectSessionSave() override = default;
+
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
+ request, nullptr);
+ }
+
+protected:
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ llvm::StringRef file_path;
+
+ if (!args.empty())
+ file_path = args[0].ref();
+
+ if (m_interpreter.SaveTranscript(result, file_path.str()))
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ else
+ result.SetStatus(eReturnStatusFailed);
+ return result.Succeeded();
+ }
+};
+
+#define LLDB_OPTIONS_history
+#include "CommandOptions.inc"
+
+class CommandObjectSessionHistory : public CommandObjectParsed {
+public:
+ CommandObjectSessionHistory(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "session history",
+ "Dump the history of commands in this session.\n"
+ "Commands in the history list can be run again "
+ "using \"!<INDEX>\". \"!-<OFFSET>\" will re-run "
+ "the command that is <OFFSET> commands from the end"
+ " of the list (counting the current command).",
+ nullptr),
+ m_options() {}
+
+ ~CommandObjectSessionHistory() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions()
+ : Options(), m_start_idx(0), m_stop_idx(0), m_count(0), m_clear(false) {
+ }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status 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:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_start_idx.Clear();
+ m_stop_idx.Clear();
+ m_count.Clear();
+ m_clear.Clear();
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_history_options);
+ }
+
+ // 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 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);
+ }
+ }
+ return result.Succeeded();
+ }
+
+ CommandOptions m_options;
+};
+
+CommandObjectSession::CommandObjectSession(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "session",
+ "Commands controlling LLDB session.",
+ "session <subcommand> [<command-options>]") {
+ LoadSubCommand("save",
+ CommandObjectSP(new CommandObjectSessionSave(interpreter)));
+ LoadSubCommand("history",
+ CommandObjectSP(new CommandObjectSessionHistory(interpreter)));
+}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.h
new file mode 100644
index 000000000000..0af0e279f47e
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.h
@@ -0,0 +1,23 @@
+//===-- CommandObjectSession.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTSESSION_H
+#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTSESSION_H
+
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+
+namespace lldb_private {
+
+class CommandObjectSession : public CommandObjectMultiword {
+public:
+ CommandObjectSession(CommandInterpreter &interpreter);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTSESSION_H
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp
index 1ccfd3a5166f..8fff22a06366 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp
@@ -16,6 +16,7 @@
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionValueFileColonLine.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
@@ -667,6 +668,22 @@ class CommandObjectSourceList : public CommandObjectParsed {
case 'r':
reverse = true;
break;
+ case 'y':
+ {
+ OptionValueFileColonLine value;
+ Status fcl_err = value.SetValueFromString(option_arg);
+ if (!fcl_err.Success()) {
+ error.SetErrorStringWithFormat(
+ "Invalid value for file:line specifier: %s",
+ fcl_err.AsCString());
+ } else {
+ file_name = value.GetFileSpec().GetPath();
+ start_line = value.GetLineNumber();
+ // I don't see anything useful to do with a column number, but I don't
+ // want to complain since someone may well have cut and pasted a
+ // listing from somewhere that included a column.
+ }
+ } break;
default:
llvm_unreachable("Unimplemented option");
}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp
index 7bb71f4d518c..1cb21384fd2a 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp
@@ -23,6 +23,8 @@
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/OptionGroupFile.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
+#include "lldb/Interpreter/OptionGroupPlatform.h"
+#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
#include "lldb/Interpreter/OptionGroupString.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionGroupUUID.h"
@@ -48,6 +50,7 @@
#include "lldb/Utility/State.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatAdapters.h"
@@ -206,8 +209,6 @@ private:
#pragma mark CommandObjectTargetCreate
-// "target create"
-
class CommandObjectTargetCreate : public CommandObjectParsed {
public:
CommandObjectTargetCreate(CommandInterpreter &interpreter)
@@ -216,11 +217,9 @@ public:
"Create a target using the argument as the main executable.",
nullptr),
m_option_group(), m_arch_option(),
+ m_platform_options(true), // Include the --platform 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 "
@@ -245,8 +244,8 @@ public:
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_platform_options, LLDB_OPT_SET_ALL, 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);
@@ -300,8 +299,7 @@ protected:
}
const char *file_path = command.GetArgumentAtIndex(0);
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path);
+ LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
FileSpec file_spec;
if (file_path) {
@@ -317,124 +315,127 @@ protected:
llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
Status error(debugger.GetTargetList().CreateTarget(
debugger, file_path, arch_cstr,
- m_add_dependents.m_load_dependent_files, nullptr, target_sp));
+ m_add_dependents.m_load_dependent_files, &m_platform_options,
+ 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 && FileSystem::Instance().Exists(file_spec)) {
- // if the remote file does not exist, push it there
- if (!platform_sp->GetFileExists(remote_file)) {
- Status 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");
+ if (!target_sp) {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ auto on_error = llvm::make_scope_exit(
+ [&target_list = debugger.GetTargetList(), &target_sp]() {
+ target_list.DeleteTarget(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 && FileSystem::Instance().Exists(file_spec)) {
+ // if the remote file does not exist, push it there
+ if (!platform_sp->GetFileExists(remote_file)) {
+ Status err = platform_sp->PutFile(file_spec, remote_file);
+ if (err.Fail()) {
+ result.AppendError(err.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
- if (file_path) {
- // copy the remote file to the local file
- Status 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");
+ }
+ } 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 (file_path) {
+ // copy the remote file to the local file
+ Status 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;
}
+ } 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);
- }
+ 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->GetOrCreateModule(main_module_spec, true /* notify */);
- if (module_sp)
- module_sp->SetPlatformFileSpec(remote_file);
- }
+ if (must_set_platform_path) {
+ ModuleSpec main_module_spec(file_spec);
+ ModuleSP module_sp =
+ target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(remote_file);
+ }
- if (core_file) {
- FileSpec core_file_dir;
- core_file_dir.GetDirectory() = core_file.GetDirectory();
- target_sp->AppendExecutableSearchPaths(core_file_dir);
+ if (core_file) {
+ FileSpec core_file_dir;
+ core_file_dir.GetDirectory() = core_file.GetDirectory();
+ target_sp->AppendExecutableSearchPaths(core_file_dir);
- ProcessSP process_sp(target_sp->CreateProcess(
- GetDebugger().GetListener(), llvm::StringRef(), &core_file));
+ ProcessSP process_sp(target_sp->CreateProcess(
+ GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
- if (process_sp) {
- // Seems weird that we Launch a core file, but that is what we
- // do!
- error = process_sp->LoadCore();
+ 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.AppendMessageWithFormatv("Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
- target_sp->GetArchitecture().GetArchitectureName());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- }
- } else {
- result.AppendErrorWithFormatv(
- "Unable to find process plug-in for core file '{0}'\n",
- core_file.GetPath());
+ if (error.Fail()) {
+ result.AppendError(
+ error.AsCString("can't find plug-in for core file"));
result.SetStatus(eReturnStatusFailed);
+ return false;
+ } else {
+ result.AppendMessageWithFormatv(
+ "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
+ target_sp->GetArchitecture().GetArchitectureName());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ on_error.release();
}
} else {
- result.AppendMessageWithFormat(
- "Current executable set to '%s' (%s).\n",
- file_spec.GetPath().c_str(),
- target_sp->GetArchitecture().GetArchitectureName());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ result.AppendErrorWithFormatv(
+ "Unable to find process plug-in for core file '{0}'\n",
+ core_file.GetPath());
+ result.SetStatus(eReturnStatusFailed);
}
} else {
- result.AppendError(error.AsCString());
- result.SetStatus(eReturnStatusFailed);
+ result.AppendMessageWithFormat(
+ "Current executable set to '%s' (%s).\n",
+ file_spec.GetPath().c_str(),
+ target_sp->GetArchitecture().GetArchitectureName());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ on_error.release();
}
} else {
result.AppendErrorWithFormat("'%s' takes exactly one executable path "
@@ -442,14 +443,15 @@ protected:
m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
}
+
return result.Succeeded();
}
private:
OptionGroupOptions m_option_group;
OptionGroupArchitecture m_arch_option;
+ OptionGroupPlatform m_platform_options;
OptionGroupFile m_core_file;
- OptionGroupFile m_platform_path;
OptionGroupFile m_symbol_file;
OptionGroupFile m_remote_file;
OptionGroupDependents m_add_dependents;
@@ -457,8 +459,6 @@ private:
#pragma mark CommandObjectTargetList
-// "target list"
-
class CommandObjectTargetList : public CommandObjectParsed {
public:
CommandObjectTargetList(CommandInterpreter &interpreter)
@@ -490,8 +490,6 @@ protected:
#pragma mark CommandObjectTargetSelect
-// "target select"
-
class CommandObjectTargetSelect : public CommandObjectParsed {
public:
CommandObjectTargetSelect(CommandInterpreter &interpreter)
@@ -511,18 +509,11 @@ protected:
TargetList &target_list = 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);
- }
+ target_list.SetSelectedTarget(target_idx);
+ Stream &strm = result.GetOutputStream();
+ bool show_stopped_process_status = false;
+ DumpTargetList(target_list, show_stopped_process_status, strm);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
if (num_targets > 0) {
result.AppendErrorWithFormat(
@@ -551,8 +542,6 @@ protected:
#pragma mark CommandObjectTargetDelete
-// "target delete"
-
class CommandObjectTargetDelete : public CommandObjectParsed {
public:
CommandObjectTargetDelete(CommandInterpreter &interpreter)
@@ -697,8 +686,6 @@ protected:
#pragma mark CommandObjectTargetVariable
-// "target variable"
-
class CommandObjectTargetVariable : public CommandObjectParsed {
static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
@@ -917,6 +904,7 @@ protected:
CompileUnit *comp_unit = nullptr;
if (frame) {
SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
+ comp_unit = sc.comp_unit;
if (sc.comp_unit) {
const bool can_create = true;
VariableListSP comp_unit_varlist_sp(
@@ -1167,6 +1155,25 @@ public:
~CommandObjectTargetModulesSearchPathsInsert() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
+ return;
+
+ Target *target = m_exe_ctx.GetTargetPtr();
+ const PathMappingList &list = target->GetImageSearchPathList();
+ const size_t num = list.GetSize();
+ ConstString old_path, new_path;
+ for (size_t i = 0; i < num; ++i) {
+ if (!list.GetPathsAtIndex(i, old_path, new_path))
+ break;
+ StreamString strm;
+ strm << old_path << " -> " << new_path;
+ request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
+ }
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target *target = &GetSelectedTarget();
@@ -1392,31 +1399,30 @@ static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
}
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();
- if (objfile)
- objfile->Dump(&strm);
- else {
- strm.Format("No object file for module: {0:F}\n",
- module->GetFileSpec());
- }
+ if (num_modules == 0)
+ return 0;
+
+ size_t num_dumped = 0;
+ strm.Format("Dumping headers for {0} module(s).\n", num_modules);
+ strm.IndentMore();
+ for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
+ if (module_sp) {
+ if (num_dumped++ > 0) {
+ strm.EOL();
+ strm.EOL();
+ }
+ ObjectFile *objfile = module_sp->GetObjectFile();
+ if (objfile)
+ objfile->Dump(&strm);
+ else {
+ strm.Format("No object file for module: {0:F}\n",
+ module_sp->GetFileSpec());
}
}
- strm.IndentLess();
}
+ strm.IndentLess();
return num_dumped;
}
@@ -1624,7 +1630,8 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
return 0;
}
-static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
+static size_t LookupTypeInModule(Target *target,
+ CommandInterpreter &interpreter, Stream &strm,
Module *module, const char *name_cstr,
bool name_is_regex) {
TypeList type_list;
@@ -1652,7 +1659,7 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
// 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);
+ type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
// Print all typedef chains
TypeSP typedef_type_sp(type_sp);
TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
@@ -1661,7 +1668,8 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
strm.Printf(" typedef '%s': ",
typedef_type_sp->GetName().GetCString());
typedefed_type_sp->GetFullCompilerType();
- typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
+ typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
+ target);
typedef_type_sp = typedefed_type_sp;
typedefed_type_sp = typedef_type_sp->GetTypedefType();
}
@@ -1671,9 +1679,9 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
return type_list.GetSize();
}
-static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
- Module &module, const char *name_cstr,
- bool name_is_regex) {
+static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
+ Stream &strm, Module &module,
+ const char *name_cstr, bool name_is_regex) {
TypeList type_list;
const uint32_t max_num_matches = UINT32_MAX;
bool name_is_fully_qualified = false;
@@ -1696,8 +1704,8 @@ static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
// 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
+ type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
+ // Print all typedef chains.
TypeSP typedef_type_sp(type_sp);
TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
while (typedefed_type_sp) {
@@ -1705,7 +1713,8 @@ static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
strm.Printf(" typedef '%s': ",
typedef_type_sp->GetName().GetCString());
typedefed_type_sp->GetFullCompilerType();
- typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
+ typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
+ target);
typedef_type_sp = typedefed_type_sp;
typedefed_type_sp = typedef_type_sp->GetTypedefType();
}
@@ -2015,14 +2024,13 @@ protected:
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();
+ const ModuleList &module_list = target->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
+ const size_t num_modules = module_list.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) {
+ result.GetOutputStream().Format(
+ "Dumping symbol table for {0} modules.\n", num_modules);
+ for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
if (num_dumped > 0) {
result.GetOutputStream().EOL();
result.GetOutputStream().EOL();
@@ -2030,10 +2038,9 @@ protected:
if (m_interpreter.WasInterrupted())
break;
num_dumped++;
- DumpModuleSymtab(
- m_interpreter, result.GetOutputStream(),
- target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
- m_options.m_sort_order, name_preference);
+ DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
+ module_sp.get(), m_options.m_sort_order,
+ name_preference);
}
} else {
result.AppendError("the target has no associated executable images");
@@ -2050,9 +2057,8 @@ protected:
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) {
+ for (ModuleSP module_sp : module_list.Modules()) {
+ if (module_sp) {
if (num_dumped > 0) {
result.GetOutputStream().EOL();
result.GetOutputStream().EOL();
@@ -2060,8 +2066,9 @@ protected:
if (m_interpreter.WasInterrupted())
break;
num_dumped++;
- DumpModuleSymtab(m_interpreter, result.GetOutputStream(), module,
- m_options.m_sort_order, name_preference);
+ DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
+ module_sp.get(), m_options.m_sort_order,
+ name_preference);
}
}
} else
@@ -2110,23 +2117,22 @@ protected:
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) {
- if (m_interpreter.WasInterrupted())
- break;
- num_dumped++;
- DumpModuleSections(
- m_interpreter, result.GetOutputStream(),
- target->GetImages().GetModulePointerAtIndex(image_idx));
- }
- } else {
+ if (num_modules == 0) {
result.AppendError("the target has no associated executable images");
result.SetStatus(eReturnStatusFailed);
return false;
}
+
+ result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
+ num_modules);
+ for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ if (m_interpreter.WasInterrupted())
+ break;
+ num_dumped++;
+ DumpModuleSections(
+ m_interpreter, result.GetOutputStream(),
+ target->GetImages().GetModulePointerAtIndex(image_idx));
+ }
} else {
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
@@ -2188,7 +2194,8 @@ protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target *target = &GetSelectedTarget();
- const size_t num_modules = target->GetImages().GetSize();
+ const ModuleList &module_list = target->GetImages();
+ const size_t num_modules = module_list.GetSize();
if (num_modules == 0) {
result.AppendError("the target has no associated executable images");
result.SetStatus(eReturnStatusFailed);
@@ -2197,14 +2204,12 @@ protected:
if (command.GetArgumentCount() == 0) {
// Dump all ASTs for all modules images
- result.GetOutputStream().Printf("Dumping clang ast for %" PRIu64
- " modules.\n",
- (uint64_t)num_modules);
- for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
+ result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
+ num_modules);
+ for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
if (m_interpreter.WasInterrupted())
break;
- Module *m = target->GetImages().GetModulePointerAtIndex(image_idx);
- if (SymbolFile *sf = m->GetSymbolFile())
+ if (SymbolFile *sf = module_sp->GetSymbolFile())
sf->DumpClangAST(result.GetOutputStream());
}
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -2269,23 +2274,19 @@ protected:
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 (m_interpreter.WasInterrupted())
- break;
- if (DumpModuleSymbolFile(
- result.GetOutputStream(),
- target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
- num_dumped++;
- }
- } else {
+ if (num_modules == 0) {
result.AppendError("the target has no associated executable images");
result.SetStatus(eReturnStatusFailed);
return false;
}
+ result.GetOutputStream().Format(
+ "Dumping debug symbols for {0} modules.\n", num_modules);
+ for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
+ if (m_interpreter.WasInterrupted())
+ break;
+ if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
+ num_dumped++;
+ }
} else {
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
@@ -2363,15 +2364,13 @@ protected:
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) {
+ if (target_modules.GetSize() > 0) {
uint32_t num_dumped = 0;
- for (uint32_t i = 0; i < num_modules; ++i) {
+ for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
if (m_interpreter.WasInterrupted())
break;
if (DumpCompileUnitLineTable(
- m_interpreter, result.GetOutputStream(),
- target_modules.GetModulePointerAtIndexUnlocked(i),
+ m_interpreter, result.GetOutputStream(), module_sp.get(),
file_spec,
m_options.m_verbose ? eDescriptionLevelFull
: eDescriptionLevelBrief))
@@ -3409,10 +3408,35 @@ protected:
continue;
result.GetOutputStream().Printf(
- "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
+ "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
funcname.AsCString(), start_addr);
+ Args args;
+ target->GetUserSpecifiedTrapHandlerNames(args);
+ size_t count = args.GetArgumentCount();
+ for (size_t i = 0; i < count; i++) {
+ const char *trap_func_name = args.GetArgumentAtIndex(i);
+ if (strcmp(funcname.GetCString(), trap_func_name) == 0)
+ result.GetOutputStream().Printf(
+ "This function is "
+ "treated as a trap handler function via user setting.\n");
+ }
+ PlatformSP platform_sp(target->GetPlatform());
+ if (platform_sp) {
+ const std::vector<ConstString> trap_handler_names(
+ platform_sp->GetTrapHandlerSymbolNames());
+ for (ConstString trap_name : trap_handler_names) {
+ if (trap_name == funcname) {
+ result.GetOutputStream().Printf(
+ "This function's "
+ "name is listed by the platform as a trap handler.\n");
+ }
+ }
+ }
+
+ result.GetOutputStream().Printf("\n");
+
UnwindPlanSP non_callsite_unwind_plan =
func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
if (non_callsite_unwind_plan) {
@@ -3745,9 +3769,9 @@ public:
return false;
case eLookupTypeType:
if (!m_options.m_str.empty()) {
- if (LookupTypeHere(m_interpreter, result.GetOutputStream(),
- *sym_ctx.module_sp, m_options.m_str.c_str(),
- m_options.m_use_regex)) {
+ if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
+ result.GetOutputStream(), *sym_ctx.module_sp,
+ m_options.m_str.c_str(), m_options.m_use_regex)) {
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
@@ -3817,9 +3841,9 @@ public:
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)) {
+ if (LookupTypeInModule(
+ &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
+ module, m_options.m_str.c_str(), m_options.m_use_regex)) {
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
@@ -3868,25 +3892,20 @@ protected:
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 {
+ if (target_modules.GetSize() == 0) {
result.AppendError("the target has no associated executable images");
result.SetStatus(eReturnStatusFailed);
return false;
}
+
+ for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
+ if (module_sp != current_module &&
+ LookupInModule(m_interpreter, module_sp.get(), result,
+ syntax_error)) {
+ result.GetOutputStream().EOL();
+ num_successful_lookups++;
+ }
+ }
} else {
// Dump specified images (by basename or fullpath)
const char *arg_cstr;
@@ -4332,7 +4351,6 @@ protected:
module_spec.GetSymbolFileSpec() = symfile_spec;
}
- ArchSpec arch;
bool symfile_exists =
FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
@@ -4405,10 +4423,10 @@ private:
class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
public IOHandlerDelegateMultiline {
public:
- class CommandOptions : public Options {
+ class CommandOptions : public OptionGroup {
public:
CommandOptions()
- : Options(), m_line_start(0), m_line_end(UINT_MAX),
+ : OptionGroup(), 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() {}
@@ -4422,7 +4440,8 @@ public:
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
ExecutionContext *execution_context) override {
Status error;
- const int short_option = m_getopt_table[option_idx].val;
+ const int short_option =
+ g_target_stop_hook_add_options[option_idx].short_option;
switch (short_option) {
case 'c':
@@ -4552,20 +4571,75 @@ public:
// Instance variables to hold the values for one_liner options.
bool m_use_one_liner;
std::vector<std::string> m_one_liner;
+
bool m_auto_continue;
};
CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "target stop-hook add",
- "Add a hook to be executed when the target stops.",
+ "Add a hook to be executed when the target stops."
+ "The hook can either be a list of commands or an "
+ "appropriately defined Python class. You can also "
+ "add filters so the hook only runs a certain stop "
+ "points.",
"target stop-hook add"),
IOHandlerDelegateMultiline("DONE",
IOHandlerDelegate::Completion::LLDBCommand),
- m_options() {}
+ m_options(), m_python_class_options("scripted stop-hook", true, 'P') {
+ SetHelpLong(
+ R"(
+Command Based stop-hooks:
+-------------------------
+ Stop hooks can run a list of lldb commands by providing one or more
+ --one-line-command options. The commands will get run in the order they are
+ added. Or you can provide no commands, in which case you will enter a
+ command editor where you can enter the commands to be run.
+
+Python Based Stop Hooks:
+------------------------
+ Stop hooks can be implemented with a suitably defined Python class, whose name
+ is passed in the --python-class option.
+
+ When the stop hook is added, the class is initialized by calling:
+
+ def __init__(self, target, extra_args, dict):
+
+ target: The target that the stop hook is being added to.
+ extra_args: An SBStructuredData Dictionary filled with the -key -value
+ option pairs passed to the command.
+ dict: An implementation detail provided by lldb.
+
+ Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
+ The method has the signature:
+
+ def handle_stop(self, exe_ctx, stream):
+
+ exe_ctx: An SBExecutionContext for the thread that has stopped.
+ stream: An SBStream, anything written to this stream will be printed in the
+ the stop message when the process stops.
+
+ Return Value: The method returns "should_stop". If should_stop is false
+ from all the stop hook executions on threads that stopped
+ with a reason, then the process will continue. Note that this
+ will happen only after all the stop hooks are run.
+
+Filter Options:
+---------------
+ Stop hooks can be set to always run, or to only run when the stopped thread
+ matches the filter options passed on the command line. The available filter
+ options include a shared library or a thread or queue specification,
+ a line range in a source file, a function name or a class name.
+ )");
+ m_all_options.Append(&m_python_class_options,
+ LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
+ LLDB_OPT_SET_FROM_TO(4, 6));
+ m_all_options.Append(&m_options);
+ m_all_options.Finalize();
+ }
~CommandObjectTargetStopHookAdd() override = default;
- Options *GetOptions() override { return &m_options; }
+ Options *GetOptions() override { return &m_all_options; }
protected:
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
@@ -4589,10 +4663,15 @@ protected:
error_sp->Flush();
}
Target *target = GetDebugger().GetSelectedTarget().get();
- if (target)
- target->RemoveStopHookByID(m_stop_hook_sp->GetID());
+ if (target) {
+ target->UndoCreateStopHook(m_stop_hook_sp->GetID());
+ }
} else {
- m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
+ // The IOHandler editor is only for command lines stop hooks:
+ Target::StopHookCommandLine *hook_ptr =
+ static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
+
+ hook_ptr->SetActionFromString(line);
StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
if (output_sp) {
output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
@@ -4609,7 +4688,10 @@ protected:
m_stop_hook_sp.reset();
Target &target = GetSelectedOrDummyTarget();
- Target::StopHookSP new_hook_sp = target.CreateStopHook();
+ Target::StopHookSP new_hook_sp =
+ target.CreateStopHook(m_python_class_options.GetName().empty() ?
+ Target::StopHook::StopHookKind::CommandBased
+ : Target::StopHook::StopHookKind::ScriptBased);
// First step, make the specifier.
std::unique_ptr<SymbolContextSpecifier> specifier_up;
@@ -4678,11 +4760,30 @@ protected:
new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
if (m_options.m_use_one_liner) {
- // Use one-liners.
- for (auto cmd : m_options.m_one_liner)
- new_hook_sp->GetCommandPointer()->AppendString(cmd.c_str());
+ // This is a command line stop hook:
+ Target::StopHookCommandLine *hook_ptr =
+ static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
+ hook_ptr->SetActionFromStrings(m_options.m_one_liner);
result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
new_hook_sp->GetID());
+ } else if (!m_python_class_options.GetName().empty()) {
+ // This is a scripted stop hook:
+ Target::StopHookScripted *hook_ptr =
+ static_cast<Target::StopHookScripted *>(new_hook_sp.get());
+ Status error = hook_ptr->SetScriptCallback(
+ m_python_class_options.GetName(),
+ m_python_class_options.GetStructuredData());
+ if (error.Success())
+ result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
+ new_hook_sp->GetID());
+ else {
+ // FIXME: Set the stop hook ID counter back.
+ result.AppendErrorWithFormat("Couldn't add stop hook: %s",
+ error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ target.UndoCreateStopHook(new_hook_sp->GetID());
+ return false;
+ }
} else {
m_stop_hook_sp = new_hook_sp;
m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
@@ -4695,6 +4796,9 @@ protected:
private:
CommandOptions m_options;
+ OptionGroupPythonClassWithDict m_python_class_options;
+ OptionGroupOptions m_all_options;
+
Target::StopHookSP m_stop_hook_sp;
};
@@ -4711,6 +4815,14 @@ public:
~CommandObjectTargetStopHookDelete() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target &target = GetSelectedOrDummyTarget();
@@ -4759,6 +4871,16 @@ public:
~CommandObjectTargetStopHookEnableDisable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target &target = GetSelectedOrDummyTarget();
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp
index f0ad1798fec6..f4ce5cc599cb 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp
@@ -8,6 +8,10 @@
#include "CommandObjectThread.h"
+#include <sstream>
+
+#include "CommandObjectThreadUtil.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -26,207 +30,12 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanStepInRange.h"
+#include "lldb/Target/Trace.h"
#include "lldb/Utility/State.h"
using namespace lldb;
using namespace lldb_private;
-// CommandObjectIterateOverThreads
-
-class CommandObjectIterateOverThreads : public CommandObjectParsed {
-
- class UniqueStack {
-
- public:
- UniqueStack(std::stack<lldb::addr_t> stack_frames, uint32_t thread_index_id)
- : m_stack_frames(stack_frames) {
- m_thread_index_ids.push_back(thread_index_id);
- }
-
- void AddThread(uint32_t thread_index_id) const {
- m_thread_index_ids.push_back(thread_index_id);
- }
-
- const std::vector<uint32_t> &GetUniqueThreadIndexIDs() const {
- return m_thread_index_ids;
- }
-
- lldb::tid_t GetRepresentativeThread() const {
- return m_thread_index_ids.front();
- }
-
- friend bool inline operator<(const UniqueStack &lhs,
- const UniqueStack &rhs) {
- return lhs.m_stack_frames < rhs.m_stack_frames;
- }
-
- protected:
- // Mark the thread index as mutable, as we don't care about it from a const
- // perspective, we only care about m_stack_frames so we keep our std::set
- // sorted.
- mutable std::vector<uint32_t> m_thread_index_ids;
- std::stack<lldb::addr_t> m_stack_frames;
- };
-
-public:
- 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);
-
- bool all_threads = false;
- if (command.GetArgumentCount() == 0) {
- Thread *thread = m_exe_ctx.GetThreadPtr();
- if (!thread || !HandleOneThread(thread->GetID(), result))
- return false;
- return result.Succeeded();
- } else if (command.GetArgumentCount() == 1) {
- all_threads = ::strcmp(command.GetArgumentAtIndex(0), "all") == 0;
- m_unique_stacks = ::strcmp(command.GetArgumentAtIndex(0), "unique") == 0;
- }
-
- // 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;
-
- if (all_threads || m_unique_stacks) {
- Process *process = m_exe_ctx.GetProcessPtr();
-
- 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();
-
- std::lock_guard<std::recursive_mutex> guard(
- process->GetThreadList().GetMutex());
-
- for (size_t i = 0; i < num_args; i++) {
- uint32_t thread_idx;
- if (!llvm::to_integer(command.GetArgumentAtIndex(i), thread_idx)) {
- 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());
- }
- }
-
- if (m_unique_stacks) {
- // Iterate over threads, finding unique stack buckets.
- std::set<UniqueStack> unique_stacks;
- for (const lldb::tid_t &tid : tids) {
- if (!BucketThread(tid, unique_stacks, result)) {
- return false;
- }
- }
-
- // Write the thread id's and unique call stacks to the output stream
- Stream &strm = result.GetOutputStream();
- Process *process = m_exe_ctx.GetProcessPtr();
- for (const UniqueStack &stack : unique_stacks) {
- // List the common thread ID's
- const std::vector<uint32_t> &thread_index_ids =
- stack.GetUniqueThreadIndexIDs();
- strm.Format("{0} thread(s) ", thread_index_ids.size());
- for (const uint32_t &thread_index_id : thread_index_ids) {
- strm.Format("#{0} ", thread_index_id);
- }
- strm.EOL();
-
- // List the shared call stack for this set of threads
- uint32_t representative_thread_id = stack.GetRepresentativeThread();
- ThreadSP thread = process->GetThreadList().FindThreadByIndexID(
- representative_thread_id);
- if (!HandleOneThread(thread->GetID(), result)) {
- return false;
- }
- }
- } else {
- uint32_t idx = 0;
- for (const lldb::tid_t &tid : tids) {
- if (idx != 0 && m_add_return)
- result.AppendMessage("");
-
- 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;
-
- bool BucketThread(lldb::tid_t tid, std::set<UniqueStack> &unique_stacks,
- CommandReturnObject &result) {
- // Grab the corresponding thread for the given thread id.
- Process *process = m_exe_ctx.GetProcessPtr();
- Thread *thread = process->GetThreadList().FindThreadByID(tid).get();
- if (thread == nullptr) {
- result.AppendErrorWithFormatv("Failed to process thread #{0}.\n", tid);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-
- // Collect the each frame's address for this call-stack
- std::stack<lldb::addr_t> stack_frames;
- const uint32_t frame_count = thread->GetStackFrameCount();
- for (uint32_t frame_index = 0; frame_index < frame_count; frame_index++) {
- const lldb::StackFrameSP frame_sp =
- thread->GetStackFrameAtIndex(frame_index);
- const lldb::addr_t pc = frame_sp->GetStackID().GetPC();
- stack_frames.push(pc);
- }
-
- uint32_t thread_index_id = thread->GetIndexID();
- UniqueStack new_unique_stack(stack_frames, thread_index_id);
-
- // Try to match the threads stack to and existing entry.
- std::set<UniqueStack>::iterator matching_stack =
- unique_stacks.find(new_unique_stack);
- if (matching_stack != unique_stacks.end()) {
- matching_stack->AddThread(thread_index_id);
- } else {
- unique_stacks.insert(new_unique_stack);
- }
- return true;
- }
-
- ReturnStatus m_success_return = eReturnStatusSuccessFinishResult;
- bool m_unique_stacks = false;
- bool m_add_return = true;
-};
-
// CommandObjectThreadBacktrace
#define LLDB_OPTIONS_thread_backtrace
#include "CommandOptions.inc"
@@ -482,8 +291,16 @@ public:
// Check if we are in Non-Stop mode
TargetSP target_sp =
execution_context ? execution_context->GetTargetSP() : TargetSP();
- if (target_sp && target_sp->GetNonStopModeEnabled())
+ if (target_sp && target_sp->GetNonStopModeEnabled()) {
+ // NonStopMode runs all threads by definition, so when it is on we don't
+ // need to check the process setting for runs all threads.
m_run_mode = eOnlyThisThread;
+ } else {
+ ProcessSP process_sp =
+ execution_context ? execution_context->GetProcessSP() : ProcessSP();
+ if (process_sp && process_sp->GetSteppingRunsAllThreads())
+ m_run_mode = eAllThreads;
+ }
m_avoid_regexp.clear();
m_step_in_target.clear();
@@ -541,6 +358,17 @@ public:
~CommandObjectThreadStepWithTypeAndScope() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_all_options; }
protected:
@@ -612,8 +440,7 @@ protected:
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);
+ bool_stop_other_threads = (m_step_type != eStepTypeOut);
else
bool_stop_other_threads = true;
@@ -808,6 +635,14 @@ public:
~CommandObjectThreadContinue() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
+ request, nullptr);
+ }
+
bool DoExecute(Args &command, CommandReturnObject &result) override {
bool synchronous_execution = m_interpreter.GetSynchronous();
@@ -1300,6 +1135,17 @@ public:
~CommandObjectThreadSelect() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Process *process = m_exe_ctx.GetProcessPtr();
@@ -1431,6 +1277,14 @@ public:
~CommandObjectThreadInfo() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_options; }
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
@@ -1475,6 +1329,14 @@ public:
~CommandObjectThreadException() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion,
+ request, nullptr);
+ }
+
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
ThreadSP thread_sp =
m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
@@ -1929,8 +1791,7 @@ public:
protected:
bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
// If we have already handled this from a -t option, skip it here.
- if (std::find(m_options.m_tids.begin(), m_options.m_tids.end(), tid) !=
- m_options.m_tids.end())
+ if (llvm::is_contained(m_options.m_tids, tid))
return true;
Process *process = m_exe_ctx.GetProcessPtr();
@@ -1978,6 +1839,15 @@ public:
~CommandObjectThreadPlanDiscard() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (!m_exe_ctx.HasThreadScope() || request.GetCursorIndex())
+ return;
+
+ m_exe_ctx.GetThreadPtr()->AutoCompleteThreadPlans(request);
+ }
+
bool DoExecute(Args &args, CommandReturnObject &result) override {
Thread *thread = m_exe_ctx.GetThreadPtr();
if (args.GetArgumentCount() != 1) {
@@ -2104,6 +1974,271 @@ public:
~CommandObjectMultiwordThreadPlan() override = default;
};
+// Next are the subcommands of CommandObjectMultiwordTrace
+
+// CommandObjectTraceStart
+
+/// This class works by delegating the logic to the actual trace plug-in that
+/// can support the current process.
+class CommandObjectTraceStart : public CommandObjectProxy {
+public:
+ CommandObjectTraceStart(CommandInterpreter &interpreter)
+ : CommandObjectProxy(interpreter, "thread trace start",
+ "Start tracing threads with the corresponding trace "
+ "plug-in for the current process.",
+ "thread trace start [<trace-options>]") {}
+
+protected:
+ llvm::Expected<CommandObjectSP> DoGetProxyCommandObject() {
+ ProcessSP process_sp = m_interpreter.GetExecutionContext().GetProcessSP();
+
+ if (!process_sp)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Process not available.");
+ if (!process_sp->IsAlive())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Process must be launched.");
+
+ llvm::Expected<TraceTypeInfo> trace_type =
+ process_sp->GetSupportedTraceType();
+
+ if (!trace_type)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(), "Tracing is not supported. %s",
+ llvm::toString(trace_type.takeError()).c_str());
+
+ CommandObjectSP delegate_sp =
+ PluginManager::GetTraceStartCommand(trace_type->name, m_interpreter);
+ if (!delegate_sp)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "No trace plug-in matches the specified type: \"%s\"",
+ trace_type->name.c_str());
+ return delegate_sp;
+ }
+
+ CommandObject *GetProxyCommandObject() override {
+ if (llvm::Expected<CommandObjectSP> delegate = DoGetProxyCommandObject()) {
+ m_delegate_sp = *delegate;
+ m_delegate_error.clear();
+ return m_delegate_sp.get();
+ } else {
+ m_delegate_sp.reset();
+ m_delegate_error = llvm::toString(delegate.takeError());
+ return nullptr;
+ }
+ }
+
+private:
+ llvm::StringRef GetUnsupportedError() override { return m_delegate_error; }
+
+ CommandObjectSP m_delegate_sp;
+ std::string m_delegate_error;
+};
+
+// CommandObjectTraceStop
+
+class CommandObjectTraceStop : public CommandObjectIterateOverThreads {
+public:
+ CommandObjectTraceStop(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread trace stop",
+ "Stop tracing threads. "
+ "Defaults to the current thread. Thread indices can be "
+ "specified as arguments.\n Use the thread-index \"all\" to trace "
+ "all threads.",
+ "thread trace stop [<thread-index> <thread-index> ...]",
+ eCommandRequiresProcess | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
+ eCommandProcessMustBeTraced) {}
+
+ ~CommandObjectTraceStop() override = default;
+
+ bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
+ const Thread &thread =
+ *m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+ Trace &trace = *m_exe_ctx.GetTargetSP()->GetTrace();
+
+ if (llvm::Error err = trace.StopTracingThread(thread)) {
+ result.AppendErrorWithFormat("Failed stopping thread %" PRIu64 ": %s\n",
+ tid, toString(std::move(err)).c_str());
+ result.SetStatus(eReturnStatusFailed);
+ }
+
+ // We don't return false on errors to try to stop as many threads as
+ // possible.
+ return true;
+ }
+};
+
+// CommandObjectTraceDumpInstructions
+#define LLDB_OPTIONS_thread_trace_dump_instructions
+#include "CommandOptions.inc"
+
+class CommandObjectTraceDumpInstructions
+ : public CommandObjectIterateOverThreads {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'c': {
+ int32_t count;
+ if (option_arg.empty() || option_arg.getAsInteger(0, count) ||
+ count < 0)
+ error.SetErrorStringWithFormat(
+ "invalid integer value for option '%s'",
+ option_arg.str().c_str());
+ else
+ m_count = count;
+ break;
+ }
+ case 'p': {
+ int32_t position;
+ if (option_arg.empty() || option_arg.getAsInteger(0, position) ||
+ position < 0)
+ error.SetErrorStringWithFormat(
+ "invalid integer value for option '%s'",
+ option_arg.str().c_str());
+ else
+ m_position = position;
+ break;
+ }
+ case 'r': {
+ m_raw = true;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_count = kDefaultCount;
+ m_position = llvm::None;
+ m_raw = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_thread_trace_dump_instructions_options);
+ }
+
+ static const size_t kDefaultCount = 20;
+
+ // Instance variables to hold the values for command options.
+ size_t m_count;
+ llvm::Optional<ssize_t> m_position;
+ bool m_raw;
+ };
+
+ CommandObjectTraceDumpInstructions(CommandInterpreter &interpreter)
+ : CommandObjectIterateOverThreads(
+ interpreter, "thread trace dump instructions",
+ "Dump the traced instructions 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 | eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched | eCommandProcessMustBePaused |
+ eCommandProcessMustBeTraced),
+ m_options(), m_create_repeat_command_just_invoked(false) {}
+
+ ~CommandObjectTraceDumpInstructions() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+ const char *GetRepeatCommand(Args &current_command_args,
+ uint32_t index) override {
+ current_command_args.GetCommandString(m_repeat_command);
+ m_create_repeat_command_just_invoked = true;
+ m_consecutive_repetitions = 0;
+ return m_repeat_command.c_str();
+ }
+
+protected:
+ bool DoExecute(Args &args, CommandReturnObject &result) override {
+ if (IsRepeatCommand())
+ m_consecutive_repetitions++;
+ bool status = CommandObjectIterateOverThreads::DoExecute(args, result);
+
+ m_create_repeat_command_just_invoked = false;
+ return status;
+ }
+
+ bool IsRepeatCommand() {
+ return !m_repeat_command.empty() && !m_create_repeat_command_just_invoked;
+ }
+
+ bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override {
+ const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace();
+ ThreadSP thread_sp =
+ m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid);
+
+ size_t count = m_options.m_count;
+ ssize_t position = m_options.m_position.getValueOr(
+ trace_sp->GetCursorPosition(*thread_sp)) -
+ m_consecutive_repetitions * count;
+ if (position < 0)
+ result.SetError("error: no more data");
+ else
+ trace_sp->DumpTraceInstructions(*thread_sp, result.GetOutputStream(),
+ count, position, m_options.m_raw);
+ return true;
+ }
+
+ CommandOptions m_options;
+
+ // Repeat command helpers
+ std::string m_repeat_command;
+ bool m_create_repeat_command_just_invoked;
+ size_t m_consecutive_repetitions = 0;
+};
+
+// CommandObjectMultiwordTraceDump
+class CommandObjectMultiwordTraceDump : public CommandObjectMultiword {
+public:
+ CommandObjectMultiwordTraceDump(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "dump",
+ "Commands for displaying trace information of the threads "
+ "in the current process.",
+ "thread trace dump <subcommand> [<subcommand objects>]") {
+ LoadSubCommand(
+ "instructions",
+ CommandObjectSP(new CommandObjectTraceDumpInstructions(interpreter)));
+ }
+ ~CommandObjectMultiwordTraceDump() override = default;
+};
+
+// CommandObjectMultiwordTrace
+class CommandObjectMultiwordTrace : public CommandObjectMultiword {
+public:
+ CommandObjectMultiwordTrace(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "trace",
+ "Commands for operating on traces of the threads in the current "
+ "process.",
+ "thread trace <subcommand> [<subcommand objects>]") {
+ LoadSubCommand("dump", CommandObjectSP(new CommandObjectMultiwordTraceDump(
+ interpreter)));
+ LoadSubCommand("start",
+ CommandObjectSP(new CommandObjectTraceStart(interpreter)));
+ LoadSubCommand("stop",
+ CommandObjectSP(new CommandObjectTraceStop(interpreter)));
+ }
+
+ ~CommandObjectMultiwordTrace() override = default;
+};
+
// CommandObjectMultiwordThread
CommandObjectMultiwordThread::CommandObjectMultiwordThread(
@@ -2179,6 +2314,8 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread(
LoadSubCommand("plan", CommandObjectSP(new CommandObjectMultiwordThreadPlan(
interpreter)));
+ LoadSubCommand("trace",
+ CommandObjectSP(new CommandObjectMultiwordTrace(interpreter)));
}
CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default;
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp
new file mode 100644
index 000000000000..b93698c7be60
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.cpp
@@ -0,0 +1,158 @@
+//===-- CommandObjectThreadUtil.cpp -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectThreadUtil.h"
+
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+CommandObjectIterateOverThreads::CommandObjectIterateOverThreads(
+ CommandInterpreter &interpreter, const char *name, const char *help,
+ const char *syntax, uint32_t flags)
+ : CommandObjectParsed(interpreter, name, help, syntax, flags) {}
+
+bool CommandObjectIterateOverThreads::DoExecute(Args &command,
+ CommandReturnObject &result) {
+ result.SetStatus(m_success_return);
+
+ bool all_threads = false;
+ if (command.GetArgumentCount() == 0) {
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ if (!thread || !HandleOneThread(thread->GetID(), result))
+ return false;
+ return result.Succeeded();
+ } else if (command.GetArgumentCount() == 1) {
+ all_threads = ::strcmp(command.GetArgumentAtIndex(0), "all") == 0;
+ m_unique_stacks = ::strcmp(command.GetArgumentAtIndex(0), "unique") == 0;
+ }
+
+ // 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;
+
+ if (all_threads || m_unique_stacks) {
+ Process *process = m_exe_ctx.GetProcessPtr();
+
+ 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();
+
+ std::lock_guard<std::recursive_mutex> guard(
+ process->GetThreadList().GetMutex());
+
+ for (size_t i = 0; i < num_args; i++) {
+ uint32_t thread_idx;
+ if (!llvm::to_integer(command.GetArgumentAtIndex(i), thread_idx)) {
+ 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());
+ }
+ }
+
+ if (m_unique_stacks) {
+ // Iterate over threads, finding unique stack buckets.
+ std::set<UniqueStack> unique_stacks;
+ for (const lldb::tid_t &tid : tids) {
+ if (!BucketThread(tid, unique_stacks, result)) {
+ return false;
+ }
+ }
+
+ // Write the thread id's and unique call stacks to the output stream
+ Stream &strm = result.GetOutputStream();
+ Process *process = m_exe_ctx.GetProcessPtr();
+ for (const UniqueStack &stack : unique_stacks) {
+ // List the common thread ID's
+ const std::vector<uint32_t> &thread_index_ids =
+ stack.GetUniqueThreadIndexIDs();
+ strm.Format("{0} thread(s) ", thread_index_ids.size());
+ for (const uint32_t &thread_index_id : thread_index_ids) {
+ strm.Format("#{0} ", thread_index_id);
+ }
+ strm.EOL();
+
+ // List the shared call stack for this set of threads
+ uint32_t representative_thread_id = stack.GetRepresentativeThread();
+ ThreadSP thread = process->GetThreadList().FindThreadByIndexID(
+ representative_thread_id);
+ if (!HandleOneThread(thread->GetID(), result)) {
+ return false;
+ }
+ }
+ } else {
+ uint32_t idx = 0;
+ for (const lldb::tid_t &tid : tids) {
+ if (idx != 0 && m_add_return)
+ result.AppendMessage("");
+
+ if (!HandleOneThread(tid, result))
+ return false;
+
+ ++idx;
+ }
+ }
+ return result.Succeeded();
+}
+
+bool CommandObjectIterateOverThreads::BucketThread(
+ lldb::tid_t tid, std::set<UniqueStack> &unique_stacks,
+ CommandReturnObject &result) {
+ // Grab the corresponding thread for the given thread id.
+ Process *process = m_exe_ctx.GetProcessPtr();
+ Thread *thread = process->GetThreadList().FindThreadByID(tid).get();
+ if (thread == nullptr) {
+ result.AppendErrorWithFormatv("Failed to process thread #{0}.\n", tid);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // Collect the each frame's address for this call-stack
+ std::stack<lldb::addr_t> stack_frames;
+ const uint32_t frame_count = thread->GetStackFrameCount();
+ for (uint32_t frame_index = 0; frame_index < frame_count; frame_index++) {
+ const lldb::StackFrameSP frame_sp =
+ thread->GetStackFrameAtIndex(frame_index);
+ const lldb::addr_t pc = frame_sp->GetStackID().GetPC();
+ stack_frames.push(pc);
+ }
+
+ uint32_t thread_index_id = thread->GetIndexID();
+ UniqueStack new_unique_stack(stack_frames, thread_index_id);
+
+ // Try to match the threads stack to and existing entry.
+ std::set<UniqueStack>::iterator matching_stack =
+ unique_stacks.find(new_unique_stack);
+ if (matching_stack != unique_stacks.end()) {
+ matching_stack->AddThread(thread_index_id);
+ } else {
+ unique_stacks.insert(new_unique_stack);
+ }
+ return true;
+}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h
new file mode 100644
index 000000000000..7122982d8943
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThreadUtil.h
@@ -0,0 +1,81 @@
+//===-- CommandObjectThreadUtil.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H
+#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H
+
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+
+namespace lldb_private {
+
+class CommandObjectIterateOverThreads : public CommandObjectParsed {
+
+ class UniqueStack {
+ public:
+ UniqueStack(std::stack<lldb::addr_t> stack_frames, uint32_t thread_index_id)
+ : m_stack_frames(stack_frames) {
+ m_thread_index_ids.push_back(thread_index_id);
+ }
+
+ void AddThread(uint32_t thread_index_id) const {
+ m_thread_index_ids.push_back(thread_index_id);
+ }
+
+ const std::vector<uint32_t> &GetUniqueThreadIndexIDs() const {
+ return m_thread_index_ids;
+ }
+
+ lldb::tid_t GetRepresentativeThread() const {
+ return m_thread_index_ids.front();
+ }
+
+ friend bool inline operator<(const UniqueStack &lhs,
+ const UniqueStack &rhs) {
+ return lhs.m_stack_frames < rhs.m_stack_frames;
+ }
+
+ protected:
+ // Mark the thread index as mutable, as we don't care about it from a const
+ // perspective, we only care about m_stack_frames so we keep our std::set
+ // sorted.
+ mutable std::vector<uint32_t> m_thread_index_ids;
+ std::stack<lldb::addr_t> m_stack_frames;
+ };
+
+public:
+ CommandObjectIterateOverThreads(CommandInterpreter &interpreter,
+ const char *name, const char *help,
+ const char *syntax, uint32_t flags);
+
+ ~CommandObjectIterateOverThreads() override = default;
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override;
+
+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;
+
+ bool BucketThread(lldb::tid_t tid, std::set<UniqueStack> &unique_stacks,
+ CommandReturnObject &result);
+
+ lldb::ReturnStatus m_success_return = lldb::eReturnStatusSuccessFinishResult;
+ bool m_unique_stacks = false;
+ bool m_add_return = true;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp
new file mode 100644
index 000000000000..170630b85b2e
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp
@@ -0,0 +1,305 @@
+//===-- CommandObjectTrace.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectTrace.h"
+
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.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/Target/Trace.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+// CommandObjectTraceLoad
+#define LLDB_OPTIONS_trace_load
+#include "CommandOptions.inc"
+
+#pragma mark CommandObjectTraceLoad
+
+class CommandObjectTraceLoad : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'v': {
+ m_verbose = true;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_verbose = false;
+ }
+
+ ArrayRef<OptionDefinition> GetDefinitions() override {
+ return makeArrayRef(g_trace_load_options);
+ }
+
+ bool m_verbose; // Enable verbose logging for debugging purposes.
+ };
+
+ CommandObjectTraceLoad(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "trace load",
+ "Load a processor trace session from a JSON file.",
+ "trace load"),
+ m_options() {}
+
+ ~CommandObjectTraceLoad() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (command.size() != 1) {
+ result.AppendError(
+ "a single path to a JSON file containing a trace session"
+ "is required");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ auto end_with_failure = [&result](llvm::Error err) -> bool {
+ result.AppendErrorWithFormat("%s\n",
+ llvm::toString(std::move(err)).c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ };
+
+ FileSpec json_file(command[0].ref());
+
+ auto buffer_or_error = llvm::MemoryBuffer::getFile(json_file.GetPath());
+ if (!buffer_or_error) {
+ return end_with_failure(llvm::createStringError(
+ std::errc::invalid_argument, "could not open input file: %s - %s.",
+ json_file.GetPath().c_str(),
+ buffer_or_error.getError().message().c_str()));
+ }
+
+ llvm::Expected<json::Value> session_file =
+ json::parse(buffer_or_error.get()->getBuffer().str());
+ if (!session_file)
+ return end_with_failure(session_file.takeError());
+
+ if (Expected<lldb::TraceSP> traceOrErr =
+ Trace::FindPlugin(GetDebugger(), *session_file,
+ json_file.GetDirectory().AsCString())) {
+ lldb::TraceSP trace_sp = traceOrErr.get();
+ if (m_options.m_verbose)
+ result.AppendMessageWithFormat("loading trace with plugin %s\n",
+ trace_sp->GetPluginName().AsCString());
+ } else
+ return end_with_failure(traceOrErr.takeError());
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+
+ CommandOptions m_options;
+};
+
+// CommandObjectTraceDump
+#define LLDB_OPTIONS_trace_dump
+#include "CommandOptions.inc"
+
+#pragma mark CommandObjectTraceDump
+
+class CommandObjectTraceDump : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'v': {
+ m_verbose = true;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_verbose = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_trace_dump_options);
+ }
+
+ bool m_verbose; // Enable verbose logging for debugging purposes.
+ };
+
+ CommandObjectTraceDump(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "trace dump",
+ "Dump the loaded processor trace data.",
+ "trace dump"),
+ m_options() {}
+
+ ~CommandObjectTraceDump() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Status error;
+ // TODO: fill in the dumping code here!
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("%s\n", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+
+ CommandOptions m_options;
+};
+
+// CommandObjectTraceSchema
+#define LLDB_OPTIONS_trace_schema
+#include "CommandOptions.inc"
+
+#pragma mark CommandObjectTraceSchema
+
+class CommandObjectTraceSchema : public CommandObjectParsed {
+public:
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() : Options() { OptionParsingStarting(nullptr); }
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'v': {
+ m_verbose = true;
+ break;
+ }
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ m_verbose = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
+ return llvm::makeArrayRef(g_trace_schema_options);
+ }
+
+ bool m_verbose; // Enable verbose logging for debugging purposes.
+ };
+
+ CommandObjectTraceSchema(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "trace schema",
+ "Show the schema of the given trace plugin.",
+ "trace schema <plug-in>. Use the plug-in name "
+ "\"all\" to see all schemas.\n"),
+ m_options() {}
+
+ ~CommandObjectTraceSchema() override = default;
+
+ Options *GetOptions() override { return &m_options; }
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ Status error;
+ if (command.empty()) {
+ result.SetError(
+ "trace schema cannot be invoked without a plug-in as argument");
+ return false;
+ }
+
+ StringRef plugin_name(command[0].c_str());
+ if (plugin_name == "all") {
+ size_t index = 0;
+ while (true) {
+ StringRef schema = PluginManager::GetTraceSchema(index++);
+ if (schema.empty())
+ break;
+
+ result.AppendMessage(schema);
+ }
+ } else {
+ if (Expected<StringRef> schemaOrErr =
+ Trace::FindPluginSchema(plugin_name))
+ result.AppendMessage(*schemaOrErr);
+ else
+ error = schemaOrErr.takeError();
+ }
+
+ if (error.Success()) {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ } else {
+ result.AppendErrorWithFormat("%s\n", error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+
+ CommandOptions m_options;
+};
+
+// CommandObjectTrace
+
+CommandObjectTrace::CommandObjectTrace(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "trace",
+ "Commands for loading and using processor "
+ "trace information.",
+ "trace [<sub-command-options>]") {
+ LoadSubCommand("load",
+ CommandObjectSP(new CommandObjectTraceLoad(interpreter)));
+ LoadSubCommand("dump",
+ CommandObjectSP(new CommandObjectTraceDump(interpreter)));
+ LoadSubCommand("schema",
+ CommandObjectSP(new CommandObjectTraceSchema(interpreter)));
+}
+
+CommandObjectTrace::~CommandObjectTrace() = default;
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h
new file mode 100644
index 000000000000..2dca0e26b243
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.h
@@ -0,0 +1,25 @@
+//===-- CommandObjectTrace.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTTRACE_H
+#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTRACE_H
+
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+
+namespace lldb_private {
+
+class CommandObjectTrace : public CommandObjectMultiword {
+public:
+ CommandObjectTrace(CommandInterpreter &interpreter);
+
+ ~CommandObjectTrace() override;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTTRACE_H
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp
index b2020f26621f..004c066b57aa 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp
@@ -37,6 +37,9 @@
#include <functional>
#include <memory>
+#define CHECK_FORMATTER_KIND_MASK(VAL) \
+ ((m_formatter_kind_mask & (VAL)) == (VAL))
+
using namespace lldb;
using namespace lldb_private;
@@ -777,6 +780,39 @@ public:
~CommandObjectTypeFormatterDelete() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+
+ DataVisualization::Categories::ForEach(
+ [this, &request](const lldb::TypeCategoryImplSP &category_sp) {
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemValue))
+ category_sp->GetTypeFormatsContainer()->AutoComplete(request);
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemRegexValue))
+ category_sp->GetRegexTypeFormatsContainer()->AutoComplete(request);
+
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemSummary))
+ category_sp->GetTypeSummariesContainer()->AutoComplete(request);
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemRegexSummary))
+ category_sp->GetRegexTypeSummariesContainer()->AutoComplete(
+ request);
+
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemFilter))
+ category_sp->GetTypeFiltersContainer()->AutoComplete(request);
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemRegexFilter))
+ category_sp->GetRegexTypeFiltersContainer()->AutoComplete(request);
+
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemSynth))
+ category_sp->GetTypeSyntheticsContainer()->AutoComplete(request);
+ if (CHECK_FORMATTER_KIND_MASK(eFormatCategoryItemRegexSynth))
+ category_sp->GetRegexTypeSyntheticsContainer()->AutoComplete(
+ request);
+ return true;
+ });
+ }
+
protected:
virtual bool FormatterSpecificDeletion(ConstString typeCS) { return false; }
@@ -1066,13 +1102,15 @@ protected:
TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
foreach
.SetExact([&result, &formatter_regex, &any_printed](
- ConstString name,
+ const TypeMatcher &type_matcher,
const FormatterSharedPointer &format_sp) -> bool {
if (formatter_regex) {
bool escape = true;
- if (name.GetStringRef() == formatter_regex->GetText()) {
+ if (type_matcher.CreatedBySameMatchString(
+ ConstString(formatter_regex->GetText()))) {
escape = false;
- } else if (formatter_regex->Execute(name.GetStringRef())) {
+ } else if (formatter_regex->Execute(
+ type_matcher.GetMatchString().GetStringRef())) {
escape = false;
}
@@ -1081,20 +1119,23 @@ protected:
}
any_printed = true;
- result.GetOutputStream().Printf("%s: %s\n", name.AsCString(),
- format_sp->GetDescription().c_str());
+ result.GetOutputStream().Printf(
+ "%s: %s\n", type_matcher.GetMatchString().GetCString(),
+ format_sp->GetDescription().c_str());
return true;
});
foreach
.SetWithRegex([&result, &formatter_regex, &any_printed](
- const RegularExpression &regex,
+ const TypeMatcher &type_matcher,
const FormatterSharedPointer &format_sp) -> bool {
if (formatter_regex) {
bool escape = true;
- if (regex.GetText() == formatter_regex->GetText()) {
+ if (type_matcher.CreatedBySameMatchString(
+ ConstString(formatter_regex->GetText()))) {
escape = false;
- } else if (formatter_regex->Execute(regex.GetText())) {
+ } else if (formatter_regex->Execute(
+ type_matcher.GetMatchString().GetStringRef())) {
escape = false;
}
@@ -1103,9 +1144,9 @@ protected:
}
any_printed = true;
- result.GetOutputStream().Printf("%s: %s\n",
- regex.GetText().str().c_str(),
- format_sp->GetDescription().c_str());
+ result.GetOutputStream().Printf(
+ "%s: %s\n", type_matcher.GetMatchString().GetCString(),
+ format_sp->GetDescription().c_str());
return true;
});
@@ -1681,10 +1722,10 @@ protected:
if (DataVisualization::NamedSummaryFormats::GetCount() > 0) {
result.GetOutputStream().Printf("Named summaries:\n");
DataVisualization::NamedSummaryFormats::ForEach(
- [&result](ConstString name,
+ [&result](const TypeMatcher &type_matcher,
const TypeSummaryImplSP &summary_sp) -> bool {
result.GetOutputStream().Printf(
- "%s: %s\n", name.AsCString(),
+ "%s: %s\n", type_matcher.GetMatchString().GetCString(),
summary_sp->GetDescription().c_str());
return true;
});
@@ -1764,6 +1805,14 @@ public:
~CommandObjectTypeCategoryDefine() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eTypeCategoryNameCompletion, request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -1860,6 +1909,14 @@ public:
~CommandObjectTypeCategoryEnable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eTypeCategoryNameCompletion, request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -1922,6 +1979,14 @@ public:
~CommandObjectTypeCategoryDelete() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eTypeCategoryNameCompletion, request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -2027,6 +2092,14 @@ public:
~CommandObjectTypeCategoryDisable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eTypeCategoryNameCompletion, request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
@@ -2084,6 +2157,16 @@ public:
~CommandObjectTypeCategoryList() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex())
+ return;
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(),
+ CommandCompletions::eTypeCategoryNameCompletion, request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
const size_t argc = command.GetArgumentCount();
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp
index ce4662930a7c..e7b1f31f3960 100644
--- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp
+++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp
@@ -292,6 +292,14 @@ public:
~CommandObjectWatchpointEnable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target *target = &GetSelectedTarget();
@@ -362,6 +370,14 @@ public:
~CommandObjectWatchpointDisable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
+ request, nullptr);
+ }
+
protected:
bool DoExecute(Args &command, CommandReturnObject &result) override {
Target *target = &GetSelectedTarget();
@@ -439,6 +455,14 @@ public:
~CommandObjectWatchpointDelete() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_options; }
class CommandOptions : public Options {
@@ -557,6 +581,14 @@ public:
~CommandObjectWatchpointIgnore() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_options; }
class CommandOptions : public Options {
@@ -677,6 +709,14 @@ public:
~CommandObjectWatchpointModify() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_options; }
class CommandOptions : public Options {
@@ -823,6 +863,16 @@ corresponding to the byte size of the data type.");
~CommandObjectWatchpointSetVariable() override = default;
+ void
+ HandleArgumentCompletion(CompletionRequest &request,
+ OptionElementVector &opt_element_vector) override {
+ if (request.GetCursorIndex() != 0)
+ return;
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion,
+ request, nullptr);
+ }
+
Options *GetOptions() override { return &m_option_group; }
protected:
@@ -905,7 +955,7 @@ protected:
// We're in business.
// Find out the size of this variable.
size = m_option_watchpoint.watch_size == 0
- ? valobj_sp->GetByteSize()
+ ? valobj_sp->GetByteSize().getValueOr(0)
: m_option_watchpoint.watch_size;
}
compiler_type = valobj_sp->GetCompilerType();
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
new file mode 100644
index 000000000000..4445457ca852
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
@@ -0,0 +1,147 @@
+//===-- CommandOptionsProcessLaunch.cpp -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandOptionsProcessLaunch.h"
+
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/OptionParser.h"
+#include "lldb/Interpreter/CommandCompletions.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Platform.h"
+#include "lldb/Target/Target.h"
+
+#include "llvm/ADT/ArrayRef.h"
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_private;
+
+#define LLDB_OPTIONS_process_launch
+#include "CommandOptions.inc"
+
+Status CommandOptionsProcessLaunch::SetOptionValue(
+ uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 's': // Stop at program entry point
+ launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
+ break;
+
+ case 'i': // STDIN for read only
+ {
+ FileAction action;
+ if (action.Open(STDIN_FILENO, FileSpec(option_arg), true, false))
+ launch_info.AppendFileAction(action);
+ break;
+ }
+
+ case 'o': // Open STDOUT for write only
+ {
+ FileAction action;
+ if (action.Open(STDOUT_FILENO, FileSpec(option_arg), false, true))
+ launch_info.AppendFileAction(action);
+ break;
+ }
+
+ case 'e': // STDERR for write only
+ {
+ FileAction action;
+ if (action.Open(STDERR_FILENO, FileSpec(option_arg), false, true))
+ launch_info.AppendFileAction(action);
+ break;
+ }
+
+ case 'P': // Process plug-in name
+ launch_info.SetProcessPluginName(option_arg);
+ break;
+
+ case 'n': // Disable STDIO
+ {
+ FileAction action;
+ const FileSpec dev_null(FileSystem::DEV_NULL);
+ if (action.Open(STDIN_FILENO, dev_null, true, false))
+ launch_info.AppendFileAction(action);
+ if (action.Open(STDOUT_FILENO, dev_null, false, true))
+ launch_info.AppendFileAction(action);
+ if (action.Open(STDERR_FILENO, dev_null, false, true))
+ launch_info.AppendFileAction(action);
+ break;
+ }
+
+ case 'w':
+ launch_info.SetWorkingDirectory(FileSpec(option_arg));
+ break;
+
+ case 't': // Open process in new terminal window
+ launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY);
+ break;
+
+ case 'a': {
+ TargetSP target_sp =
+ execution_context ? execution_context->GetTargetSP() : TargetSP();
+ PlatformSP platform_sp =
+ target_sp ? target_sp->GetPlatform() : PlatformSP();
+ launch_info.GetArchitecture() =
+ Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
+ } break;
+
+ case 'A': // Disable ASLR.
+ {
+ bool success;
+ const bool disable_aslr_arg =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
+ if (success)
+ disable_aslr = disable_aslr_arg ? eLazyBoolYes : eLazyBoolNo;
+ else
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for disable-aslr option: '%s'",
+ option_arg.empty() ? "<null>" : option_arg.str().c_str());
+ break;
+ }
+
+ case 'X': // shell expand args.
+ {
+ bool success;
+ const bool expand_args =
+ OptionArgParser::ToBoolean(option_arg, true, &success);
+ if (success)
+ launch_info.SetShellExpandArguments(expand_args);
+ else
+ error.SetErrorStringWithFormat(
+ "Invalid boolean value for shell-expand-args option: '%s'",
+ option_arg.empty() ? "<null>" : option_arg.str().c_str());
+ break;
+ }
+
+ case 'c':
+ if (!option_arg.empty())
+ launch_info.SetShell(FileSpec(option_arg));
+ else
+ launch_info.SetShell(HostInfo::GetDefaultShell());
+ break;
+
+ case 'v':
+ launch_info.GetEnvironment().insert(option_arg);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option character '%c'",
+ short_option);
+ break;
+ }
+ return error;
+}
+
+llvm::ArrayRef<OptionDefinition> CommandOptionsProcessLaunch::GetDefinitions() {
+ return llvm::makeArrayRef(g_process_launch_options);
+}
diff --git a/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h
new file mode 100644
index 000000000000..4028d8e02cb2
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessLaunch.h
@@ -0,0 +1,49 @@
+//===-- CommandOptionsProcessLaunch.h -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_COMMANDS_COMMANDOPTIONSPROCESSLAUNCH_H
+#define LLDB_SOURCE_COMMANDS_COMMANDOPTIONSPROCESSLAUNCH_H
+
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Interpreter/Options.h"
+
+namespace lldb_private {
+
+// CommandOptionsProcessLaunch
+
+class CommandOptionsProcessLaunch : public lldb_private::Options {
+public:
+ CommandOptionsProcessLaunch() : lldb_private::Options() {
+ // Keep default values of all options in one place: OptionParsingStarting
+ // ()
+ OptionParsingStarting(nullptr);
+ }
+
+ ~CommandOptionsProcessLaunch() override = default;
+
+ lldb_private::Status
+ SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ lldb_private::ExecutionContext *execution_context) override;
+
+ void OptionParsingStarting(
+ lldb_private::ExecutionContext *execution_context) override {
+ launch_info.Clear();
+ disable_aslr = lldb_private::eLazyBoolCalculate;
+ }
+
+ llvm::ArrayRef<lldb_private::OptionDefinition> GetDefinitions() override;
+
+ // Instance variables to hold the values for command options.
+
+ lldb_private::ProcessLaunchInfo launch_info;
+ lldb_private::LazyBool disable_aslr;
+}; // CommandOptionsProcessLaunch
+
+}; // namespace lldb_private
+
+#endif // LLDB_SOURCE_COMMANDS_COMMANDOPTIONSPROCESSLAUNCH_H
diff --git a/contrib/llvm-project/lldb/source/Commands/Options.td b/contrib/llvm-project/lldb/source/Commands/Options.td
index d6f1e0a3c96d..d3329078893a 100644
--- a/contrib/llvm-project/lldb/source/Commands/Options.td
+++ b/contrib/llvm-project/lldb/source/Commands/Options.td
@@ -105,7 +105,7 @@ let Command = "breakpoint dummy" in {
let Command = "breakpoint set" in {
def breakpoint_set_shlib : Option<"shlib", "s">, Arg<"ShlibName">,
- Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11]>, // *not* in group 10
+ Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11,12]>, // *not* in group 10
Desc<"Set the breakpoint only in this shared library. Can repeat this "
"option multiple times to specify multiple shared libraries.">;
def breakpoint_set_hardware : Option<"hardware", "H">,
@@ -186,21 +186,24 @@ let Command = "breakpoint set" in {
"expression (note: currently only implemented for setting breakpoints on "
"identifiers). If not set the target.language setting is used.">;
def breakpoint_set_skip_prologue : Option<"skip-prologue", "K">,
- Arg<"Boolean">, Groups<[1,3,4,5,6,7,8]>,
+ Arg<"Boolean">, Groups<[1,3,4,5,6,7,8,12]>,
Desc<"sKip the prologue if the breakpoint is at the beginning of a "
"function. If not set the target.skip-prologue setting is used.">;
def breakpoint_set_breakpoint_name : Option<"breakpoint-name", "N">,
Arg<"BreakpointName">,
Desc<"Adds this to the list of names for this breakpoint.">;
def breakpoint_set_address_slide : Option<"address-slide", "R">,
- Arg<"Address">, Groups<[1,3,4,5,6,7,8]>,
+ Arg<"Address">, Groups<[1,3,4,5,6,7,8,12]>,
Desc<"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.">;
def breakpoint_set_move_to_nearest_code : Option<"move-to-nearest-code", "m">,
- Groups<[1, 9]>, Arg<"Boolean">,
+ Groups<[1,9,12]>, Arg<"Boolean">,
Desc<"Move breakpoints to nearest code. If not set the "
"target.move-to-nearest-codesetting is used.">;
+ def breakpoint_set_file_colon_line : Option<"joint-specifier", "y">, Group<12>, Arg<"FileLineColumn">,
+ Required, Completion<"SourceFile">,
+ Desc<"A specifier in the form filename:line[:column] for setting file & line breakpoints.">;
/* Don't add this option till it actually does something useful...
def breakpoint_set_exception_typename : Option<"exception-typename", "O">,
Arg<"TypeName">, Desc<"The breakpoint will only stop if an "
@@ -224,6 +227,9 @@ let Command = "breakpoint delete" in {
def breakpoint_delete_dummy_breakpoints : Option<"dummy-breakpoints", "D">,
Group<1>, Desc<"Delete Dummy breakpoints - i.e. breakpoints set before a "
"file is provided, which prime new targets.">;
+ def breakpoint_delete_disabled : Option<"disabled", "d">, Group<1>,
+ Desc<"Delete all breakpoints which are currently disabled. When using the disabled option "
+ "any breakpoints listed on the command line are EXCLUDED from deletion.">;
}
let Command = "breakpoint name" in {
@@ -321,7 +327,7 @@ let Command = "disassemble" in {
def disassemble_options_pc : Option<"pc", "p">, Group<5>,
Desc<"Disassemble around the current pc.">;
def disassemble_options_line : Option<"line", "l">, Group<6>,
- Desc<"Disassemble the current frame's current source line instructions if"
+ Desc<"Disassemble the current frame's current source line instructions if "
"there is debug line table information, else disassemble around the pc.">;
def disassemble_options_address : Option<"address", "a">, Group<7>,
Arg<"AddressOrExpression">,
@@ -366,7 +372,7 @@ let Command = "expression" in {
"top-level entities without a $ prefix.">;
def expression_options_allow_jit : Option<"allow-jit", "j">, Groups<[1,2]>,
Arg<"Boolean">,
- Desc<"Controls whether the expression can fall back to being JITted if it's"
+ Desc<"Controls whether the expression can fall back to being JITted if it's "
"not supported by the interpreter (defaults to true).">;
}
@@ -448,6 +454,12 @@ let Command = "reproducer dump" in {
"provided, that reproducer is dumped.">;
}
+let Command = "reproducer verify" in {
+ def reproducer_verify_file : Option<"file", "f">, Group<1>, Arg<"Filename">,
+ Desc<"The reproducer path. If a reproducer is replayed and no path is "
+ "provided, that reproducer is dumped.">;
+}
+
let Command = "reproducer xcrash" in {
def reproducer_signal : Option<"signal", "s">, Group<1>,
EnumArg<"None", "ReproducerSignalType()">,
@@ -628,6 +640,39 @@ let Command = "platform shell" in {
Desc<"Run the commands on the host shell when enabled.">;
def platform_shell_timeout : Option<"timeout", "t">, Arg<"Value">,
Desc<"Seconds to wait for the remote host to finish running the command.">;
+ def platform_shell_interpreter : Option<"shell", "s">, Arg<"Path">,
+ Desc<"Shell interpreter path. This is the binary used to run the command.">;
+}
+
+let Command = "process launch" in {
+ def process_launch_stop_at_entry : Option<"stop-at-entry", "s">,
+ Desc<"Stop at the entry point of the program when launching a process.">;
+ def process_launch_disable_aslr : Option<"disable-aslr", "A">, Arg<"Boolean">,
+ Desc<"Set whether to disable address space layout randomization when launching a process.">;
+ def process_launch_plugin : Option<"plugin", "P">, Arg<"Plugin">,
+ Desc<"Name of the process plugin you want to use.">;
+ def process_launch_working_dir : Option<"working-dir", "w">, Arg<"DirectoryName">,
+ Desc<"Set the current working directory to <path> when running the inferior.">;
+ def process_launch_arch : Option<"arch", "a">, Arg<"Architecture">,
+ Desc<"Set the architecture for the process to launch when ambiguous.">;
+ def process_launch_environment : Option<"environment", "v">,
+ Arg<"None">, Desc<"Specify an environment variable name/value string "
+ "(--environment NAME=VALUE). Can be specified multiple times for subsequent "
+ "environment entries.">;
+ def process_launch_shell : Option<"shell", "c">, GroupRange<1,3>,
+ OptionalArg<"Filename">, Desc<"Run the process in a shell (not supported on all platforms).">;
+ def process_launch_stdin : Option<"stdin", "i">, Group<1>,
+ Arg<"Filename">, Desc<"Redirect stdin for the process to <filename>.">;
+ def process_launch_stdout : Option<"stdout", "o">, Group<1>,
+ Arg<"Filename">, Desc<"Redirect stdout for the process to <filename>.">;
+ def process_launch_stderr : Option<"stderr", "e">, Group<1>,
+ Arg<"Filename">, Desc<"Redirect stderr for the process to <filename>.">;
+ def process_launch_tty : Option<"tty", "t">, Group<2>,
+ Desc<"Start the process in a terminal (not supported on all platforms).">;
+ def process_launch_no_stdio : Option<"no-stdio", "n">, Group<3>,
+ Desc<"Do not set up for terminal I/O to go to running process.">;
+ def process_launch_shell_expand_args : Option<"shell-expand-args", "X">, Group<4>,
+ Arg<"Boolean">, Desc<"Set whether to shell expand arguments to the process when launching.">;
}
let Command = "process attach" in {
@@ -690,6 +735,10 @@ let Command = "script import" in {
Desc<"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.">;
+ def relative_to_command_file : Option<"relative-to-command-file", "c">,
+ Group<1>, Desc<"Resolve non-absolute paths relative to the location of the "
+ "current command file. This argument can only be used when the command is "
+ "being sourced from a file.">;
}
let Command = "script add" in {
@@ -706,6 +755,12 @@ let Command = "script add" in {
"LLDB event system.">;
}
+let Command = "script" in {
+ def script_language : Option<"language", "l">,
+ EnumArg<"ScriptLang", "ScriptOptionEnum()">, Desc<"Specify the scripting "
+ " language. If none is specific the default scripting language is used.">;
+}
+
let Command = "source info" in {
def source_info_count : Option<"count", "c">, Arg<"Count">,
Desc<"The number of line entries to display.">;
@@ -729,7 +784,7 @@ let Command = "source info" in {
let Command = "source list" in {
def source_list_count : Option<"count", "c">, Arg<"Count">,
Desc<"The number of source lines to display.">;
- def source_list_shlib : Option<"shlib", "s">, Groups<[1,2]>, Arg<"ShlibName">,
+ def source_list_shlib : Option<"shlib", "s">, Groups<[1,2,5]>, Arg<"ShlibName">,
Completion<"Module">,
Desc<"Look up the source file in the given shared library.">;
def source_list_show_breakpoints : Option<"show-breakpoints", "b">,
@@ -747,6 +802,10 @@ let Command = "source list" in {
" information for the corresponding file and line.">;
def source_list_reverse : Option<"reverse", "r">, Group<4>, Desc<"Reverse the"
" listing to look backwards from the last displayed block of source.">;
+ def source_list_file_colon_line : Option<"joint-specifier", "y">, Group<5>,
+ Arg<"FileLineColumn">, Completion<"SourceFile">,
+ Desc<"A specifier in the form filename:line[:column] from which to display"
+ " source.">;
}
let Command = "target dependents" in {
@@ -855,7 +914,7 @@ let Command = "target modules lookup" in {
}
let Command = "target stop hook add" in {
- def target_stop_hook_add_one_liner : Option<"one-liner", "o">,
+ def target_stop_hook_add_one_liner : Option<"one-liner", "o">, GroupRange<1,3>,
Arg<"OneLiner">, Desc<"Add a command for the stop hook. Can be specified "
"more than once, and commands will be run in the order they appear.">;
def target_stop_hook_add_shlib : Option<"shlib", "s">, Arg<"ShlibName">,
@@ -873,19 +932,19 @@ let Command = "target stop hook add" in {
def target_stop_hook_add_queue_name : Option<"queue-name", "q">,
Arg<"QueueName">, Desc<"The stop hook is run only for threads in the queue "
"whose name is given by this argument.">;
- def target_stop_hook_add_file : Option<"file", "f">, Group<1>,
+ def target_stop_hook_add_file : Option<"file", "f">, Groups<[1,4]>,
Arg<"Filename">, Desc<"Specify the source file within which the stop-hook "
"is to be run.">, Completion<"SourceFile">;
- def target_stop_hook_add_start_line : Option<"start-line", "l">, Group<1>,
+ def target_stop_hook_add_start_line : Option<"start-line", "l">, Groups<[1,4]>,
Arg<"LineNum">, Desc<"Set the start of the line range for which the "
"stop-hook is to be run.">;
- def target_stop_hook_add_end_line : Option<"end-line", "e">, Group<1>,
+ def target_stop_hook_add_end_line : Option<"end-line", "e">, Groups<[1,4]>,
Arg<"LineNum">, Desc<"Set the end of the line range for which the stop-hook"
" is to be run.">;
- def target_stop_hook_add_classname : Option<"classname", "c">, Group<2>,
+ def target_stop_hook_add_classname : Option<"classname", "c">, Groups<[2,5]>,
Arg<"ClassName">,
Desc<"Specify the class within which the stop-hook is to be run.">;
- def target_stop_hook_add_name : Option<"name", "n">, Group<3>,
+ def target_stop_hook_add_name : Option<"name", "n">, Groups<[3,6]>,
Arg<"FunctionName">, Desc<"Set the function name within which the stop hook"
" will be run.">, Completion<"Symbol">;
def target_stop_hook_add_auto_continue : Option<"auto-continue", "G">,
@@ -924,7 +983,7 @@ let Command = "thread step scope" in {
EnumArg<"RunMode", "TriRunningModes()">, Desc<"Determine how to run other "
"threads while stepping the current thread.">;
def thread_step_scope_step_over_regexp : Option<"step-over-regexp", "r">,
- Group<1>, Arg<"RegularExpression">, Desc<"A regular expression that defines"
+ Group<1>, Arg<"RegularExpression">, Desc<"A regular expression that defines "
"function names to not to stop at when stepping in.">;
def thread_step_scope_step_in_target : Option<"step-in-target", "t">,
Group<1>, Arg<"FunctionName">, Desc<"The name of the directly called "
@@ -937,10 +996,10 @@ let Command = "thread until" in {
def thread_until_thread : Option<"thread", "t">, Group<1>, Arg<"ThreadIndex">,
Desc<"Thread index for the thread for until operation">;
def thread_until_run_mode : Option<"run-mode", "m">, Group<1>,
- EnumArg<"RunMode", "DuoRunningModes()">, Desc<"Determine how to run other"
+ EnumArg<"RunMode", "DuoRunningModes()">, Desc<"Determine how to run other "
"threads while stepping this one">;
def thread_until_address : Option<"address", "a">, Group<1>,
- Arg<"AddressOrExpression">, Desc<"Run until we reach the specified address,"
+ Arg<"AddressOrExpression">, Desc<"Run until we reach the specified address, "
"or leave the function - can be specified multiple times.">;
}
@@ -981,6 +1040,19 @@ let Command = "thread plan list" in {
Desc<"Display thread plans for unreported threads">;
}
+let Command = "thread trace dump instructions" in {
+ def thread_trace_dump_instructions_count : Option<"count", "c">, Group<1>,
+ Arg<"Count">,
+ Desc<"The number of instructions to display ending at the current position.">;
+ def thread_trace_dump_instructions_position : Option<"position", "p">,
+ Group<1>,
+ Arg<"Index">,
+ Desc<"The position to use instead of the current position of the trace.">;
+ def thread_trace_dump_instructions_raw : Option<"raw", "r">,
+ Group<1>,
+ Desc<"Dump only instruction address without disassembly nor symbol information.">;
+}
+
let Command = "type summary add" in {
def type_summary_add_category : Option<"category", "w">, Arg<"Name">,
Desc<"Add this to the given category instead of the default one.">;
@@ -1117,7 +1189,7 @@ let Command = "watchpoint list" in {
"brief description of the watchpoint (no location info).">;
def watchpoint_list_full : Option<"full", "f">, Group<2>, Desc<"Give a full "
"description of the watchpoint and its locations.">;
- def watchpoint_list_verbose : Option<"verbose", "v">, Group<3>, Desc<"Explain"
+ def watchpoint_list_verbose : Option<"verbose", "v">, Group<3>, Desc<"Explain "
"everything we know about the watchpoint (for debugging debugger bugs).">;
}
@@ -1154,3 +1226,19 @@ let Command = "watchpoint delete" in {
def watchpoint_delete_force : Option<"force", "f">, Group<1>,
Desc<"Delete all watchpoints without querying for confirmation.">;
}
+
+let Command = "trace load" in {
+ def trace_load_verbose : Option<"verbose", "v">, Group<1>,
+ Desc<"Show verbose trace load logging for debugging the plug-in "
+ "implementation.">;
+}
+
+let Command = "trace dump" in {
+ def trace_dump_verbose : Option<"verbose", "v">, Group<1>,
+ Desc<"Show verbose trace information.">;
+}
+
+let Command = "trace schema" in {
+ def trace_schema_verbose : Option<"verbose", "v">, Group<1>,
+ Desc<"Show verbose trace schema logging for debugging the plug-in.">;
+}