aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectThread.cpp
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2022-02-04 15:16:31 -0800
committerJim Ingham <jingham@apple.com>2022-02-14 15:48:06 -0800
commit635f03fe976e250cc64999663f47716412dfa029 (patch)
treef4f49f4aae21d4d9393775a90f9e43db5a8db2f1 /lldb/source/Commands/CommandObjectThread.cpp
parenta7c2a6289c22624f8b21b6c0e3f27047c4d4113d (diff)
downloadllvm-635f03fe976e250cc64999663f47716412dfa029.zip
llvm-635f03fe976e250cc64999663f47716412dfa029.tar.gz
llvm-635f03fe976e250cc64999663f47716412dfa029.tar.bz2
Add a repeat command option for "thread backtrace --count N".
This way if you have a long stack, you can issue "thread backtrace --count 10" and then subsequent <Return>-s will page you through the stack. This took a little more effort than just adding the repeat command, since the GetRepeatCommand API was returning a "const char *". That meant the command had to keep the repeat string alive, which is inconvenient. The original API returned either a nullptr, or a const char *, so I changed the private API to return an llvm::Optional<std::string>. Most of the patch is propagating that change. Also, there was a little thinko in fetching the repeat command. We don't fetch repeat commands for commands that aren't being added to history, which is in general reasonable. And we don't add repeat commands to the history - also reasonable. But we do want the repeat command to be able to generate the NEXT repeat command. So I adjusted the logic in HandleCommand to work that way. Differential Revision: https://reviews.llvm.org/D119046
Diffstat (limited to 'lldb/source/Commands/CommandObjectThread.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectThread.cpp60
1 files changed, 56 insertions, 4 deletions
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index f604293..4108adf 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -125,6 +125,58 @@ public:
Options *GetOptions() override { return &m_options; }
+ llvm::Optional<std::string> GetRepeatCommand(Args &current_args,
+ uint32_t idx) override {
+ llvm::StringRef count_opt("--count");
+ llvm::StringRef start_opt("--start");
+
+ // If no "count" was provided, we are dumping the entire backtrace, so
+ // there isn't a repeat command. So we search for the count option in
+ // the args, and if we find it, we make a copy and insert or modify the
+ // start option's value to start count indices greater.
+
+ Args copy_args(current_args);
+ size_t num_entries = copy_args.GetArgumentCount();
+ // These two point at the index of the option value if found.
+ size_t count_idx = 0;
+ size_t start_idx = 0;
+ size_t count_val = 0;
+ size_t start_val = 0;
+
+ for (size_t idx = 0; idx < num_entries; idx++) {
+ llvm::StringRef arg_string = copy_args[idx].ref();
+ if (arg_string.equals("-c") || count_opt.startswith(arg_string)) {
+ idx++;
+ if (idx == num_entries)
+ return llvm::None;
+ count_idx = idx;
+ if (copy_args[idx].ref().getAsInteger(0, count_val))
+ return llvm::None;
+ } else if (arg_string.equals("-s") || start_opt.startswith(arg_string)) {
+ idx++;
+ if (idx == num_entries)
+ return llvm::None;
+ start_idx = idx;
+ if (copy_args[idx].ref().getAsInteger(0, start_val))
+ return llvm::None;
+ }
+ }
+ if (count_idx == 0)
+ return llvm::None;
+
+ std::string new_start_val = llvm::formatv("{0}", start_val + count_val);
+ if (start_idx == 0) {
+ copy_args.AppendArgument(start_opt);
+ copy_args.AppendArgument(new_start_val);
+ } else {
+ copy_args.ReplaceArgumentAtIndex(start_idx, new_start_val);
+ }
+ std::string repeat_command;
+ if (!copy_args.GetQuotedCommandString(repeat_command))
+ return llvm::None;
+ return repeat_command;
+ }
+
protected:
void DoExtendedBacktrace(Thread *thread, CommandReturnObject &result) {
SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime();
@@ -960,7 +1012,7 @@ protected:
uint32_t index_ptr = 0, end_ptr;
std::vector<addr_t> address_list;
- // Find the beginning & end index of the
+ // Find the beginning & end index of the
AddressRange fun_addr_range = sc.function->GetAddressRange();
Address fun_start_addr = fun_addr_range.GetBaseAddress();
line_table->FindLineEntryByAddress(fun_start_addr, function_start,
@@ -2132,11 +2184,11 @@ public:
Options *GetOptions() override { return &m_options; }
- const char *GetRepeatCommand(Args &current_command_args,
- uint32_t index) override {
+ llvm::Optional<std::string> GetRepeatCommand(Args &current_command_args,
+ uint32_t index) override {
current_command_args.GetCommandString(m_repeat_command);
m_create_repeat_command_just_invoked = true;
- return m_repeat_command.c_str();
+ return m_repeat_command;
}
protected: