diff options
Diffstat (limited to 'lldb/source/Commands')
| -rw-r--r-- | lldb/source/Commands/CommandObjectDisassemble.cpp | 8 | ||||
| -rw-r--r-- | lldb/source/Commands/CommandObjectDisassemble.h | 1 | ||||
| -rw-r--r-- | lldb/source/Commands/CommandObjectProcess.cpp | 128 | ||||
| -rw-r--r-- | lldb/source/Commands/CommandObjectTarget.cpp | 69 | ||||
| -rw-r--r-- | lldb/source/Commands/CommandObjectThread.cpp | 33 | ||||
| -rw-r--r-- | lldb/source/Commands/CommandObjectTrace.cpp | 116 | ||||
| -rw-r--r-- | lldb/source/Commands/Options.td | 28 |
7 files changed, 258 insertions, 125 deletions
diff --git a/lldb/source/Commands/CommandObjectDisassemble.cpp b/lldb/source/Commands/CommandObjectDisassemble.cpp index 9d081c83c0fb..6c33edc8a3a8 100644 --- a/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -65,6 +65,10 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( show_bytes = true; break; + case 'k': + show_control_flow_kind = true; + break; + case 's': { start_addr = OptionArgParser::ToAddress(execution_context, option_arg, LLDB_INVALID_ADDRESS, &error); @@ -154,6 +158,7 @@ void CommandObjectDisassemble::CommandOptions::OptionParsingStarting( ExecutionContext *execution_context) { show_mixed = false; show_bytes = false; + show_control_flow_kind = false; num_lines_context = 0; num_instructions = 0; func_name.clear(); @@ -493,6 +498,9 @@ bool CommandObjectDisassemble::DoExecute(Args &command, if (m_options.show_bytes) options |= Disassembler::eOptionShowBytes; + if (m_options.show_control_flow_kind) + options |= Disassembler::eOptionShowControlFlowKind; + if (m_options.raw) options |= Disassembler::eOptionRawOuput; diff --git a/lldb/source/Commands/CommandObjectDisassemble.h b/lldb/source/Commands/CommandObjectDisassemble.h index a4b3df8724da..b5146863628d 100644 --- a/lldb/source/Commands/CommandObjectDisassemble.h +++ b/lldb/source/Commands/CommandObjectDisassemble.h @@ -46,6 +46,7 @@ public: bool show_mixed; // Show mixed source/assembly bool show_bytes; + bool show_control_flow_kind; uint32_t num_lines_context = 0; uint32_t num_instructions = 0; bool raw; diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index c76ae99057f2..d36a574aba7d 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -579,14 +579,14 @@ protected: } } } - + Target *target = m_exe_ctx.GetTargetPtr(); BreakpointIDList run_to_bkpt_ids; // Don't pass an empty run_to_breakpoint list, as Verify will look for the // default breakpoint. if (m_options.m_run_to_bkpt_args.GetArgumentCount() > 0) CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - m_options.m_run_to_bkpt_args, target, result, &run_to_bkpt_ids, + m_options.m_run_to_bkpt_args, target, result, &run_to_bkpt_ids, BreakpointName::Permissions::disablePerm); if (!result.Succeeded()) { return false; @@ -604,7 +604,7 @@ protected: std::vector<break_id_t> bkpts_disabled; std::vector<BreakpointID> locs_disabled; if (num_run_to_bkpt_ids != 0) { - // Go through the ID's specified, and separate the breakpoints from are + // Go through the ID's specified, and separate the breakpoints from are // the breakpoint.location specifications since the latter require // special handling. We also figure out whether there's at least one // specifier in the set that is enabled. @@ -613,22 +613,22 @@ protected: std::unordered_set<break_id_t> bkpts_with_locs_seen; BreakpointIDList with_locs; bool any_enabled = false; - + for (size_t idx = 0; idx < num_run_to_bkpt_ids; idx++) { BreakpointID bkpt_id = run_to_bkpt_ids.GetBreakpointIDAtIndex(idx); break_id_t bp_id = bkpt_id.GetBreakpointID(); break_id_t loc_id = bkpt_id.GetLocationID(); - BreakpointSP bp_sp + BreakpointSP bp_sp = bkpt_list.FindBreakpointByID(bp_id); - // Note, VerifyBreakpointOrLocationIDs checks for existence, so we + // Note, VerifyBreakpointOrLocationIDs checks for existence, so we // don't need to do it again here. if (bp_sp->IsEnabled()) { if (loc_id == LLDB_INVALID_BREAK_ID) { - // A breakpoint (without location) was specified. Make sure that + // A breakpoint (without location) was specified. Make sure that // at least one of the locations is enabled. size_t num_locations = bp_sp->GetNumLocations(); for (size_t loc_idx = 0; loc_idx < num_locations; loc_idx++) { - BreakpointLocationSP loc_sp + BreakpointLocationSP loc_sp = bp_sp->GetLocationAtIndex(loc_idx); if (loc_sp->IsEnabled()) { any_enabled = true; @@ -641,7 +641,7 @@ protected: if (loc_sp->IsEnabled()) any_enabled = true; } - + // Then sort the bp & bp.loc entries for later use: if (bkpt_id.GetLocationID() == LLDB_INVALID_BREAK_ID) bkpts_seen.insert(bkpt_id.GetBreakpointID()); @@ -653,14 +653,14 @@ protected: } // Do all the error checking here so once we start disabling we don't // have to back out half-way through. - + // Make sure at least one of the specified breakpoints is enabled. if (!any_enabled) { result.AppendError("at least one of the continue-to breakpoints must " "be enabled."); return false; } - + // Also, if you specify BOTH a breakpoint and one of it's locations, // we flag that as an error, since it won't do what you expect, the // breakpoint directive will mean "run to all locations", which is not @@ -671,7 +671,7 @@ protected: "one of its locations: {0}", bp_id); } } - + // Now go through the breakpoints in the target, disabling all the ones // that the user didn't mention: for (BreakpointSP bp_sp : bkpt_list.Breakpoints()) { @@ -695,7 +695,7 @@ protected: BreakpointLocationSP loc_sp = bp_sp->GetLocationAtIndex(loc_idx); tmp_id.SetBreakpointLocationID(loc_idx); size_t position = 0; - if (!with_locs.FindBreakpointID(tmp_id, &position) + if (!with_locs.FindBreakpointID(tmp_id, &position) && loc_sp->IsEnabled()) { locs_disabled.push_back(tmp_id); loc_sp->SetEnabled(false); @@ -723,20 +723,20 @@ protected: Status error; // For now we can only do -b with synchronous: bool old_sync = GetDebugger().GetAsyncExecution(); - + if (run_to_bkpt_ids.GetSize() != 0) { GetDebugger().SetAsyncExecution(false); synchronous_execution = true; - } + } if (synchronous_execution) error = process->ResumeSynchronous(&stream); else error = process->Resume(); - + if (run_to_bkpt_ids.GetSize() != 0) { GetDebugger().SetAsyncExecution(old_sync); - } - + } + // Now re-enable the breakpoints we disabled: BreakpointList &bkpt_list = target->GetBreakpointList(); for (break_id_t bp_id : bkpts_disabled) { @@ -745,10 +745,10 @@ protected: bp_sp->SetEnabled(true); } for (const BreakpointID &bkpt_id : locs_disabled) { - BreakpointSP bp_sp + BreakpointSP bp_sp = bkpt_list.FindBreakpointByID(bkpt_id.GetBreakpointID()); if (bp_sp) { - BreakpointLocationSP loc_sp + BreakpointLocationSP loc_sp = bp_sp->FindLocationByID(bkpt_id.GetLocationID()); if (loc_sp) loc_sp->SetEnabled(true); @@ -1731,7 +1731,7 @@ protected: bool DoExecute(Args &signal_args, CommandReturnObject &result) override { Target &target = GetSelectedOrDummyTarget(); - // Any signals that are being set should be added to the Target's + // Any signals that are being set should be added to the Target's // DummySignals so they will get applied on rerun, etc. // If we have a process, however, we can do a more accurate job of vetting // the user's options. @@ -1761,8 +1761,8 @@ protected: "true or false.\n"); return false; } - - bool no_actions = (stop_action == -1 && pass_action == -1 + + bool no_actions = (stop_action == -1 && pass_action == -1 && notify_action == -1); if (m_options.only_target_values && !no_actions) { result.AppendError("-t is for reporting, not setting, target values."); @@ -1832,9 +1832,9 @@ protected: } auto set_lazy_bool = [] (int action) -> LazyBool { LazyBool lazy; - if (action == -1) + if (action == -1) lazy = eLazyBoolCalculate; - else if (action) + else if (action) lazy = eLazyBoolYes; else lazy = eLazyBoolNo; @@ -1876,7 +1876,7 @@ protected: PrintSignalInformation(result.GetOutputStream(), signal_args, num_signals_set, signals_sp); else - target.PrintDummySignals(result.GetOutputStream(), + target.PrintDummySignals(result.GetOutputStream(), signal_args); if (num_signals_set > 0) @@ -1909,80 +1909,6 @@ protected: } }; -// CommandObjectProcessTraceSave -#define LLDB_OPTIONS_process_trace_save -#include "CommandOptions.inc" - -#pragma mark CommandObjectProcessTraceSave - -class CommandObjectProcessTraceSave : public CommandObjectParsed { -public: - class CommandOptions : public Options { - public: - CommandOptions() { OptionParsingStarting(nullptr); } - - 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 'd': { - m_directory.SetFile(option_arg, FileSpec::Style::native); - FileSystem::Instance().Resolve(m_directory); - break; - } - default: - llvm_unreachable("Unimplemented option"); - } - return error; - } - - void OptionParsingStarting(ExecutionContext *execution_context) override{}; - - llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::makeArrayRef(g_process_trace_save_options); - }; - - FileSpec m_directory; - }; - - Options *GetOptions() override { return &m_options; } - CommandObjectProcessTraceSave(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "process trace save", - "Save the trace of the current process in the specified directory. " - "The directory will be created if needed. " - "This will also create a file <directory>/trace.json with the main " - "properties of the trace session, along with others files which " - "contain the actual trace data. The trace.json file can be used " - "later as input for the \"trace load\" command to load the trace " - "in LLDB", - "process trace save [<cmd-options>]", - eCommandRequiresProcess | eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | - eCommandProcessMustBeTraced) {} - - ~CommandObjectProcessTraceSave() override = default; - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { - ProcessSP process_sp = m_exe_ctx.GetProcessSP(); - - TraceSP trace_sp = process_sp->GetTarget().GetTrace(); - - if (llvm::Error err = trace_sp->SaveLiveTraceToDisk(m_options.m_directory)) - result.AppendError(toString(std::move(err))); - else - result.SetStatus(eReturnStatusSuccessFinishResult); - - return result.Succeeded(); - } - - CommandOptions m_options; -}; - // CommandObjectProcessTraceStop class CommandObjectProcessTraceStop : public CommandObjectParsed { public: @@ -2020,8 +1946,6 @@ public: : CommandObjectMultiword( interpreter, "trace", "Commands for tracing the current process.", "process trace <subcommand> [<subcommand objects>]") { - LoadSubCommand("save", CommandObjectSP( - new CommandObjectProcessTraceSave(interpreter))); LoadSubCommand("start", CommandObjectSP(new CommandObjectProcessTraceStart( interpreter))); LoadSubCommand("stop", CommandObjectSP( diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 2b71f1bc7bc8..51978878c8b9 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -47,12 +47,18 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Timer.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private-enumerations.h" +#include "clang/CodeGen/ObjectFilePCHContainerOperations.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/FrontendActions.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatAdapters.h" @@ -2155,6 +2161,59 @@ protected: } }; +class CommandObjectTargetModulesDumpClangPCMInfo : public CommandObjectParsed { +public: + CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "target modules dump pcm-info", + "Dump information about the given clang module (pcm).") { + // Take a single file argument. + CommandArgumentData arg{eArgTypeFilename, eArgRepeatPlain}; + m_arguments.push_back({arg}); + } + + ~CommandObjectTargetModulesDumpClangPCMInfo() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + if (command.GetArgumentCount() != 1) { + result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.", + m_cmd_name.c_str()); + return false; + } + + const char *pcm_path = command.GetArgumentAtIndex(0); + FileSpec pcm_file{pcm_path}; + + if (pcm_file.GetFileNameExtension().GetStringRef() != ".pcm") { + result.AppendError("file must have a .pcm extension"); + return false; + } + + if (!FileSystem::Instance().Exists(pcm_file)) { + result.AppendError("pcm file does not exist"); + return false; + } + + clang::CompilerInstance compiler; + compiler.createDiagnostics(); + + const char *clang_args[] = {"clang", pcm_path}; + compiler.setInvocation(clang::createInvocation(clang_args)); + + clang::DumpModuleInfoAction dump_module_info; + dump_module_info.OutputStream = &result.GetOutputStream().AsRawOstream(); + // DumpModuleInfoAction requires ObjectFilePCHContainerReader. + compiler.getPCHContainerOperations()->registerReader( + std::make_unique<clang::ObjectFilePCHContainerReader>()); + + if (compiler.ExecuteAction(dump_module_info)) + result.SetStatus(eReturnStatusSuccessFinishResult); + + return result.Succeeded(); + } +}; + #pragma mark CommandObjectTargetModulesDumpClangAST // Clang AST dumping command @@ -2406,10 +2465,10 @@ public: CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : CommandObjectMultiword( interpreter, "target modules dump", - "Commands for dumping information about one or " - "more target modules.", + "Commands for dumping information about one or more target " + "modules.", "target modules dump " - "[headers|symtab|sections|ast|symfile|line-table] " + "[objfile|symtab|sections|ast|symfile|line-table|pcm-info] " "[<file1> <file2> ...]") { LoadSubCommand("objfile", CommandObjectSP( @@ -2429,6 +2488,10 @@ public: LoadSubCommand("line-table", CommandObjectSP(new CommandObjectTargetModulesDumpLineTable( interpreter))); + LoadSubCommand( + "pcm-info", + CommandObjectSP( + new CommandObjectTargetModulesDumpClangPCMInfo(interpreter))); } ~CommandObjectTargetModulesDump() override = default; diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index 993523e06736..ad49d27bb9a7 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -1033,11 +1033,21 @@ protected: line_table->FindLineEntryByAddress(fun_end_addr, function_start, &end_ptr); + // Since not all source lines will contribute code, check if we are + // setting the breakpoint on the exact line number or the nearest + // subsequent line number and set breakpoints at all the line table + // entries of the chosen line number (exact or nearest subsequent). for (uint32_t line_number : line_numbers) { + LineEntry line_entry; + bool exact = false; uint32_t start_idx_ptr = index_ptr; + start_idx_ptr = sc.comp_unit->FindLineEntry( + index_ptr, line_number, nullptr, exact, &line_entry); + if (start_idx_ptr != UINT32_MAX) + line_number = line_entry.line; + exact = true; + start_idx_ptr = index_ptr; while (start_idx_ptr <= end_ptr) { - LineEntry line_entry; - const bool exact = false; start_idx_ptr = sc.comp_unit->FindLineEntry( start_idx_ptr, line_number, nullptr, exact, &line_entry); if (start_idx_ptr == UINT32_MAX) @@ -2164,6 +2174,10 @@ public: m_dumper_options.forwards = true; break; } + case 'k': { + m_dumper_options.show_control_flow_kind = true; + break; + } case 't': { m_dumper_options.show_tsc = true; break; @@ -2337,6 +2351,10 @@ public: m_verbose = true; break; } + case 'j': { + m_json = true; + break; + } default: llvm_unreachable("Unimplemented option"); } @@ -2345,6 +2363,7 @@ public: void OptionParsingStarting(ExecutionContext *execution_context) override { m_verbose = false; + m_json = false; } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { @@ -2353,15 +2372,9 @@ public: // Instance variables to hold the values for command options. bool m_verbose; + bool m_json; }; - bool DoExecute(Args &command, CommandReturnObject &result) override { - Target &target = m_exe_ctx.GetTargetRef(); - result.GetOutputStream().Format("Trace technology: {0}\n", - target.GetTrace()->GetPluginName()); - return CommandObjectIterateOverThreads::DoExecute(command, result); - } - CommandObjectTraceDumpInfo(CommandInterpreter &interpreter) : CommandObjectIterateOverThreads( interpreter, "thread trace dump info", @@ -2383,7 +2396,7 @@ protected: ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); trace_sp->DumpTraceInfo(*thread_sp, result.GetOutputStream(), - m_options.m_verbose); + m_options.m_verbose, m_options.m_json); return true; } diff --git a/lldb/source/Commands/CommandObjectTrace.cpp b/lldb/source/Commands/CommandObjectTrace.cpp index 17aded9ed2a0..227de2de7065 100644 --- a/lldb/source/Commands/CommandObjectTrace.cpp +++ b/lldb/source/Commands/CommandObjectTrace.cpp @@ -30,6 +30,108 @@ using namespace lldb; using namespace lldb_private; using namespace llvm; +// CommandObjectTraceSave +#define LLDB_OPTIONS_trace_save +#include "CommandOptions.inc" + +#pragma mark CommandObjectTraceSave + +class CommandObjectTraceSave : public CommandObjectParsed { +public: + class CommandOptions : public Options { + public: + CommandOptions() { OptionParsingStarting(nullptr); } + + 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': { + m_compact = true; + break; + } + default: + llvm_unreachable("Unimplemented option"); + } + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_compact = false; + }; + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_trace_save_options); + }; + + bool m_compact; + }; + + Options *GetOptions() override { return &m_options; } + + CommandObjectTraceSave(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "trace save", + "Save the trace of the current target in the specified directory, " + "which will be created if needed. " + "This directory will contain a trace bundle, with all the " + "necessary files the reconstruct the trace session even on a " + "different computer. " + "Part of this bundle is the bundle description file with the name " + "trace.json. This file can be used by the \"trace load\" command " + "to load this trace in LLDB." + "Note: if the current target contains information of multiple " + "processes or targets, they all will be included in the bundle.", + "trace save [<cmd-options>] <bundle_directory>", + eCommandRequiresProcess | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | + eCommandProcessMustBeTraced) { + CommandArgumentData bundle_dir{eArgTypeDirectoryName, eArgRepeatPlain}; + m_arguments.push_back({bundle_dir}); + } + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, + request, nullptr); + } + + ~CommandObjectTraceSave() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + if (command.size() != 1) { + result.AppendError("a single path to a directory where the trace bundle " + "will be created is required"); + return false; + } + + FileSpec bundle_dir(command[0].ref()); + FileSystem::Instance().Resolve(bundle_dir); + + ProcessSP process_sp = m_exe_ctx.GetProcessSP(); + + TraceSP trace_sp = process_sp->GetTarget().GetTrace(); + + if (llvm::Expected<FileSpec> desc_file = + trace_sp->SaveToDisk(bundle_dir, m_options.m_compact)) { + result.AppendMessageWithFormatv( + "Trace bundle description file written to: {0}", *desc_file); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendError(toString(desc_file.takeError())); + } + + return result.Succeeded(); + } + + CommandOptions m_options; +}; + // CommandObjectTraceLoad #define LLDB_OPTIONS_trace_load #include "CommandOptions.inc" @@ -75,11 +177,19 @@ public: : CommandObjectParsed( interpreter, "trace load", "Load a post-mortem processor trace session from a trace bundle.", - "trace load") { - CommandArgumentData session_file_arg{eArgTypePath, eArgRepeatPlain}; + "trace load <trace_description_file>") { + CommandArgumentData session_file_arg{eArgTypeFilename, eArgRepeatPlain}; m_arguments.push_back({session_file_arg}); } + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, + request, nullptr); + } + ~CommandObjectTraceLoad() override = default; Options *GetOptions() override { return &m_options; } @@ -284,6 +394,8 @@ CommandObjectTrace::CommandObjectTrace(CommandInterpreter &interpreter) CommandObjectSP(new CommandObjectTraceLoad(interpreter))); LoadSubCommand("dump", CommandObjectSP(new CommandObjectTraceDump(interpreter))); + LoadSubCommand("save", + CommandObjectSP(new CommandObjectTraceSave(interpreter))); LoadSubCommand("schema", CommandObjectSP(new CommandObjectTraceSchema(interpreter))); } diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 7755daa878be..7981917fd8b5 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -300,6 +300,11 @@ let Command = "breakpoint command delete" in { let Command = "disassemble" in { def disassemble_options_bytes : Option<"bytes", "b">, Desc<"Show opcode bytes when disassembling.">; + def disassemble_options_kind : Option<"kind", "k">, + Desc<"Show instruction control flow kind. Refer to the enum " + "`InstructionControlFlowKind` for a list of control flow kind. " + "As an important note, far jumps, far calls and far returns often indicate " + "calls to and from kernel.">; def disassemble_options_context : Option<"context", "C">, Arg<"NumLines">, Desc<"Number of context lines of source to show.">; def disassemble_options_mixed : Option<"mixed", "m">, @@ -783,14 +788,6 @@ let Command = "process save_core" in { "This allows core files to be saved in different formats.">; } -let Command = "process trace save" in { - def process_trace_save_directory: Option<"directory", "d">, - Group<1>, - Arg<"Value">, Required, - Desc<"The directory where the trace will be saved." - "It will be created if it does not exist.">; -} - let Command = "script import" in { def script_import_allow_reload : Option<"allow-reload", "r">, Group<1>, Desc<"Allow the script to be loaded even if it was already loaded before. " @@ -1150,6 +1147,11 @@ let Command = "thread trace dump instructions" in { def thread_trace_dump_instructions_pretty_print: Option<"pretty-json", "J">, Group<1>, Desc<"Dump in JSON format but pretty printing the output for easier readability.">; + def thread_trace_dump_instructions_show_kind : Option<"kind", "k">, Group<1>, + Desc<"Show instruction control flow kind. Refer to the enum " + "`InstructionControlFlowKind` for a list of control flow kind. " + "As an important note, far jumps, far calls and far returns often indicate " + "calls to and from kernel.">; def thread_trace_dump_instructions_show_tsc : Option<"tsc", "t">, Group<1>, Desc<"For each instruction, print the corresponding timestamp counter if " "available.">; @@ -1167,6 +1169,8 @@ let Command = "thread trace dump instructions" in { let Command = "thread trace dump info" in { def thread_trace_dump_info_verbose : Option<"verbose", "v">, Group<1>, Desc<"show verbose thread trace dump info">; + def thread_trace_dump_info_json: Option<"json", "j">, Group<1>, + Desc<"Dump in JSON format.">; } let Command = "type summary add" in { @@ -1349,6 +1353,14 @@ let Command = "trace load" in { "implementation.">; } +let Command = "trace save" in { + def trace_save_compact: Option<"compact", "c">, + Group<1>, + Desc<"Try not to save to disk information irrelevant to the traced " + "processes. Each trace plug-in implements this in a different " + "fashion.">; +} + let Command = "trace dump" in { def trace_dump_verbose : Option<"verbose", "v">, Group<1>, Desc<"Show verbose trace information.">; |
