diff options
author | Jim Ingham <jingham@apple.com> | 2015-02-06 02:10:56 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2015-02-06 02:10:56 +0000 |
commit | 9bdea541cab4e540dc9c8d88edcb9c23f75d9595 (patch) | |
tree | e7491d5d8471722040953d516ed8ef27acab212e /lldb/source/Commands/CommandObjectThread.cpp | |
parent | 8378ac36845a074fd7a81035ee38175c4ef54c46 (diff) | |
download | llvm-9bdea541cab4e540dc9c8d88edcb9c23f75d9595.zip llvm-9bdea541cab4e540dc9c8d88edcb9c23f75d9595.tar.gz llvm-9bdea541cab4e540dc9c8d88edcb9c23f75d9595.tar.bz2 |
Add a "-a/--address" option to "thread until". You can specify one or more line numbers (as arguments)
and/or one or more addresses (with -a) and until will stop at the first one of thesepoints it hits,
or on exit from the function if you leave the function before hitting any of these stop points.
<rdar://problem/12438270>
llvm-svn: 228370
Diffstat (limited to 'lldb/source/Commands/CommandObjectThread.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectThread.cpp | 88 |
1 files changed, 61 insertions, 27 deletions
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index 3789164..199d16b 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -985,6 +985,14 @@ public: switch (short_option) { + case 'a': + { + ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); + lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); + if (error.Success()) + m_until_addrs.push_back(tmp_addr); + } + break; case 't': { m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32); @@ -1031,6 +1039,7 @@ public: m_thread_idx = LLDB_INVALID_THREAD_ID; m_frame_idx = 0; m_stop_others = false; + m_until_addrs.clear(); } const OptionDefinition* @@ -1041,6 +1050,7 @@ public: uint32_t m_step_thread_idx; bool m_stop_others; + std::vector<lldb::addr_t> m_until_addrs; // Options table: Required for subclasses of Options. @@ -1052,7 +1062,7 @@ public: CommandObjectThreadUntil (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, "thread until", - "Run the current or specified thread until it reaches a given line number or leaves the current function.", + "Run the current or specified thread until it reaches a given line number or address or leaves the current function.", NULL, eFlagRequiresThread | eFlagTryTargetAPILock | @@ -1111,23 +1121,33 @@ protected: else { Thread *thread = NULL; - uint32_t line_number; + std::vector<uint32_t> line_numbers; - if (command.GetArgumentCount() != 1) + if (command.GetArgumentCount() >= 1) { - result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax()); - result.SetStatus (eReturnStatusFailed); - return false; + size_t num_args = command.GetArgumentCount(); + for (size_t i = 0; i < num_args; i++) + { + uint32_t line_number; + line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX); + if (line_number == UINT32_MAX) + { + result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0)); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + line_numbers.push_back(line_number); + } } - - line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX); - if (line_number == UINT32_MAX) + else if (m_options.m_until_addrs.empty()) { - result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0)); + result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax()); result.SetStatus (eReturnStatusFailed); return false; } + if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) { thread = process->GetThreadList().GetSelectedThread().get(); @@ -1189,27 +1209,40 @@ protected: Address fun_end_addr(fun_start_addr.GetSection(), fun_start_addr.GetOffset() + fun_addr_range.GetByteSize()); - line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr); bool all_in_function = true; - - while (index_ptr <= end_ptr) + + line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr); + + for (uint32_t line_number : line_numbers) { - LineEntry line_entry; - const bool exact = false; - index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry); - if (index_ptr == UINT32_MAX) - break; - - addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); - if (address != LLDB_INVALID_ADDRESS) + uint32_t start_idx_ptr = index_ptr; + while (start_idx_ptr <= end_ptr) { - if (fun_addr_range.ContainsLoadAddress (address, target)) - address_list.push_back (address); - else - all_in_function = false; + LineEntry line_entry; + const bool exact = false; + start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry); + if (start_idx_ptr == UINT32_MAX) + break; + + addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); + if (address != LLDB_INVALID_ADDRESS) + { + if (fun_addr_range.ContainsLoadAddress (address, target)) + address_list.push_back (address); + else + all_in_function = false; + } + start_idx_ptr++; } - index_ptr++; + } + + for (lldb::addr_t address : m_options.m_until_addrs) + { + if (fun_addr_range.ContainsLoadAddress (address, target)) + address_list.push_back (address); + else + all_in_function = false; } if (address_list.size() == 0) @@ -1291,7 +1324,8 @@ CommandObjectThreadUntil::CommandOptions::g_option_table[] = { { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, -{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"}, +{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one"}, +{ LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."}, { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; |