<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/132901>132901</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
The lldb step command skips commands without debugging information
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Guo-yyds
</td>
</tr>
</table>
<pre>
Now I am doing a project, need to use lldb debugging, I have provided lldb debug information, but some code does not have debug_line, this time in the step debugging, it will become stepin, I also checked the source code, is there any way to directly skip the part without source code?
Here is the source code.
CommandObjectThread.cpp
```cpp
void DoExecute(Args &command, CommandReturnObject &result) override {
std::cout << "[lldb ghn] DoExecute" << m_cmd_name << std::endl;
Process *process = m_exe_ctx.GetProcessPtr();
bool synchronous_execution = m_interpreter.GetSynchronous();
const uint32_t num_threads = process->GetThreadList().GetSize();
Thread *thread = nullptr;
if (command.GetArgumentCount() == 0) {
thread = GetDefaultThread();
if (thread == nullptr) {
result.AppendError("no selected thread in process");
return;
}
} else {
const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
uint32_t step_thread_idx;
if (!llvm::to_integer(thread_idx_cstr, step_thread_idx)) {
result.AppendErrorWithFormat("invalid thread index '%s'.\n",
thread_idx_cstr);
return;
}
thread =
process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
if (thread == nullptr) {
result.AppendErrorWithFormat(
"Thread index %u is out of range (valid values are 0 - %u).\n",
step_thread_idx, num_threads);
return;
}
}
if (m_step_type == eStepTypeScripted) {
if (m_class_options.GetName().empty()) {
result.AppendErrorWithFormat("empty class name for scripted step.");
return;
} else if (!GetDebugger().GetScriptInterpreter()->CheckObjectExists(
m_class_options.GetName().c_str())) {
result.AppendErrorWithFormat(
"class for scripted step: \"%s\" does not exist.",
m_class_options.GetName().c_str());
return;
}
}
if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER &&
m_step_type != eStepTypeInto) {
result.AppendErrorWithFormat(
"end line option is only valid for step into");
return;
}
const bool abort_other_plans = false;
const lldb::RunMode stop_other_threads = m_options.m_run_mode;
// This is a bit unfortunate, but not all the commands in this command
// object support only while stepping, so I use the bool for them.
bool bool_stop_other_threads;
if (m_options.m_run_mode == eAllThreads)
bool_stop_other_threads = false;
else if (m_options.m_run_mode == eOnlyDuringStepping)
bool_stop_other_threads = (m_step_type != eStepTypeOut);
else
bool_stop_other_threads = true;
ThreadPlanSP new_plan_sp;
Status new_plan_status;
if (m_step_type == eStepTypeInto) {
StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
assert(frame != nullptr);
if (frame->HasDebugInformation()) {
std::cout << "[lldb ghn] HasDebugInformation" << std::endl;
AddressRange range;
SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything);
if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER) {
llvm::Error err =
sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range);
if (err) {
result.AppendErrorWithFormatv("invalid end-line option: {0}.",
llvm::toString(std::move(err)));
return;
}
} else if (m_options.m_end_line_is_block_end) {
Status error;
Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
if (!block) {
result.AppendErrorWithFormat("Could not find the current block.");
return;
}
AddressRange block_range;
Address pc_address = frame->GetFrameCodeAddress();
block->GetRangeContainingAddress(pc_address, block_range);
if (!block_range.GetBaseAddress().IsValid()) {
result.AppendErrorWithFormat(
"Could not find the current block address.");
return;
}
lldb::addr_t pc_offset_in_block =
pc_address.GetFileAddress() -
block_range.GetBaseAddress().GetFileAddress();
lldb::addr_t range_length =
block_range.GetByteSize() - pc_offset_in_block;
range = AddressRange(pc_address, range_length);
} else {
// enter
range = sc.line_entry.range;
// 创建一个 StreamFile 对象,输出到 stdout
lldb_private::StreamFile stream(stdout, false); // false 表示不自动关闭输出流
range.DumpDebug(&stream);
}
new_plan_sp = thread->QueueThreadPlanForStepInRange(
abort_other_plans, range,
frame->GetSymbolContext(eSymbolContextEverything),
m_options.m_step_in_target.c_str(), stop_other_threads,
new_plan_status, m_options.m_step_in_avoid_no_debug,
m_options.m_step_out_avoid_no_debug);
if (new_plan_sp && !m_options.m_avoid_regexp.empty()) {
// not enter
ThreadPlanStepInRange *step_in_range_plan =
static_cast<ThreadPlanStepInRange *>(new_plan_sp.get());
step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
}
} else{
std::cout << "[lldb ghn] don't HasDebugInformation" << std::endl;
// new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
// false, abort_other_plans, bool_stop_other_threads,
// new_plan_status);
new_plan_sp = thread->QueueThreadPlanForStepOut(
abort_other_plans, nullptr, false, bool_stop_other_threads,
eVoteYes, eVoteNoOpinion,
thread->GetSelectedFrameIndex(DoNoSelectMostRelevantFrame),
new_plan_status, m_options.m_step_out_avoid_no_debug);
}
} else if (m_step_type == eStepTypeOver) {
StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
if (frame->HasDebugInformation())
new_plan_sp = thread->QueueThreadPlanForStepOverRange(
abort_other_plans,
frame->GetSymbolContext(eSymbolContextEverything).line_entry,
frame->GetSymbolContext(eSymbolContextEverything),
stop_other_threads, new_plan_status,
m_options.m_step_out_avoid_no_debug);
else{
// new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
// true, abort_other_plans, bool_stop_other_threads, new_plan_status);
new_plan_sp = thread->QueueThreadPlanForStepOut(
abort_other_plans, nullptr, false, bool_stop_other_threads,
eVoteYes, eVoteNoOpinion,
thread->GetSelectedFrameIndex(DoNoSelectMostRelevantFrame),
new_plan_status, m_options.m_step_out_avoid_no_debug);
}
} else if (m_step_type == eStepTypeTrace) {
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
false, abort_other_plans, bool_stop_other_threads, new_plan_status);
} else if (m_step_type == eStepTypeTraceOver) {
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
true, abort_other_plans, bool_stop_other_threads, new_plan_status);
} else if (m_step_type == eStepTypeOut) {
new_plan_sp = thread->QueueThreadPlanForStepOut(
abort_other_plans, nullptr, false, bool_stop_other_threads, eVoteYes,
eVoteNoOpinion,
thread->GetSelectedFrameIndex(DoNoSelectMostRelevantFrame),
new_plan_status, m_options.m_step_out_avoid_no_debug);
} else if (m_step_type == eStepTypeScripted) {
new_plan_sp = thread->QueueThreadPlanForStepScripted(
abort_other_plans, m_class_options.GetName().c_str(),
m_class_options.GetStructuredData(), bool_stop_other_threads,
new_plan_status);
} else {
result.AppendError("step type is not supported");
return;
}
// If we got a new plan, then set it to be a controlling plan (User level
// Plans should be controlling plans so that they can be interruptible).
// Then resume the process.
if (new_plan_sp) {
new_plan_sp->SetIsControllingPlan(true);
new_plan_sp->SetOkayToDiscard(false);
if (m_options.m_step_count > 1) {
if (!new_plan_sp->SetIterationCount(m_options.m_step_count)) {
result.AppendWarning(
"step operation does not support iteration count.");
}
}
process->GetThreadList().SetSelectedThreadByID(thread->GetID());
const uint32_t iohandler_id = process->GetIOHandlerID();
StreamString stream;
Status error;
if (synchronous_execution)
error = process->ResumeSynchronous(&stream);
else
error = process->Resume();
if (!error.Success()) {
result.AppendMessage(error.AsCString());
return;
}
// There is a race condition where this thread will return up the call
// stack to the main command handler and show an (lldb) prompt before
// HandlePrivateEvent (from PrivateStateThread) has a chance to call
// PushProcessIOHandler().
process->SyncIOHandler(iohandler_id, std::chrono::seconds(2));
if (synchronous_execution) {
// If any state changed events had anything to say, add that to the
// result
if (stream.GetSize() > 0)
result.AppendMessage(stream.GetString());
process->GetThreadList().SetSelectedThreadByID(thread->GetID());
result.SetDidChangeProcessState(true);
result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
result.SetStatus(eReturnStatusSuccessContinuingNoResult);
}
} else {
result.SetError(std::move(new_plan_status));
}
}
```
I also tried to modify it, but there is still a problem.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsW0tv47qS_jXMhohhy3FiL7Lw8xwD3elMnHsuZiXQUtnmtEQKJOXE8-sHLOotxbHT3ZjNDRrnKBJZLNbzK7LCtOZ7AfBIRjMyWtyw1BykevwrlbenU6hvtjI8PT7JN7qmLKah5GJPGU2U_B8IDPHmVACE1EiaaqBRFG5pCNt0v-dib7-u6YEdwY4_8hDCygjKxU6qmBkuhR25TQ3VMgYayBBoKEFTIY2bjhP8iAuwI82Ba2p4DJQLag5AtYGkviw39I1HEd1CYEnaAVw4flikJQ0OEPy0fNvZMlWBWxanavtWAWXiRN_Yye4t5AoCE52o_skTnJQwZZcwB4lslxSGK9Kf_m3nO0LVjz3Sn5L-dC7jmInwx9aK8PWggIW9IEnsx_u---d-pfQoeUgXcvkOQWqAeOOp2mtKvPvA0bAMZ-RewKRKOKJ2hAKdRoZ4EyqPoBQPgZKHGVKlVJuQDKdkOA0s_2Q4J8M5JZ5HRjPU0P4gyGhRXdnLR8V-EIe-YDHkbwpiIMKIDPM1npUMQFtup0n-OFzQ2Id38APz3vsLTDbm2SjijYk3KWdvpYyoPongoKSQqbazgtQaS0aFCwMqUWBAWUqbcmiVVEYtkEIbmnJhhp5vqEhj36DgHU8Zf7dkuPwLMpV849o4Skie_y80WXTj7P5M9jRcUJFGUWJUbXW-o8QbZyqz1KZqn8YgzFymIlvETrbz-_hcKIrSCu2_wCxgx9IoY7Fjo_li5awqUw3SlDoj6U2TBES4VEo6PXhCUg0RBAZ9BElxkYvJ2klVDo6Qtb7qO_KwyJ7Jw4JCpKG2ttNIcGCqFKDPw3c_0EbhbjvkNTVrEcI78cb9BgeFaq2r-yW5TuEQbxBFx9gZrZFoSntQhdgKPqx7NQl6k0vE-G9uDisMb06gXBxZxCvCDOGdEu-BeCNNvIceGc0FynVeIXv2p8XqFRqpWlVtvU8cYcVF6F7OTqiJ9YJ447aEenswTW_5Zcusi7QuJeJ5r3XJjlIbgG10kzuqmNiDXdwp4ciiFDRlCmif3uJgy_SHOmhtcF6NINf6QjMuxL6jf0oglwpsDCSvpwQ2geKJgbApn3xmEDGtfZnYuKitpzyxOItTPYgTc8q08AWLxekUF6AY7XdSUZ3xgyLpXRwInPsXzodxzGZrUJUIi6TXZVR3n6wpzm22dplt-c610W0DKH7OyyTwdZFqviKWltU5-bREQ4ZTSkZzFNBIu6cS04DdRK_T1K5i_9esLl8i9kGECK4o8QbW_L59W8z89dM_02_rhf9t_bT0n_71fbZ8sbDC_isXrdmum1zY7loY2ZTwNfK1NihCiow5XtGjRXSizo1R6hb6cVypaYtNgdSE4NIPggy2lcr40oI-P4mYcJBgxyIN5WQ33mIjlzVeUvHd4lRtZJLNrQKKqnRVKvwYoWElFRFvRbwVfbVQlmvK6JYbmlpEbFLBDOSI2JoLiyJEkllC1A72cp2_qJOUDgHqNEmkMk5ebwceORScZABZS7pGyG4JoxisNM0B4l4VgNn_-O09lnJpG1O-3SKWTaPotYyUuXY-oNwl-0rwOLvQDxGdFqniYr8pdnrZgs0o3LDkH6mp2ZZl6CK6RqV1tTtBPEdMbJ6pgDc0OF8nJe2NYSbVlW_4ewecPJc2ulxvY1jwc6UQt3vTnXuwPCJLWcYvB9WhVndCZ1qDsu8zak5sZUrvBF841i73N9OYBdbVOrA7W11YrnRS9D4pU-zPNAwVaP2CMAHBQv375hRvZTSXwsC7oTpwVppvBKuPygDijaH2YnkEdTKHzCBrlL8ejNtSorREtRhbKSjVgngozwBRdWXXKyVjW7W-yqUIv2Gh3cmVjR1OQM2d5HsB1YHmPov9xzpKBhHeVuI-ZtOHWZ88LLqz5vmfKtbfGIVqGBfWEMsjFGx3JVbamVxpA1C3cE6X9Hyu_W0kg5_2TZeUMu8HrMQaq83sROu7W_dwlQniZOvIOLlbc8QbbLNhV6rPaW8u0yjEjLXjwp2tBKlSIAxFup148TPp1l7V_NQJssNbi3E0CXyWPTbFhUFuLkPIxrajm_3BNbIZuKoVJ-OCi305r1wFs3aFrY98JJe0G2Z9ccZ0nZPeWv9jfeGjkHiJStpOcoGWaLaXL2mr_L2ESpaeb6wu5G6nwfhc-IUJt3gshWnFsuJRXSz0tjXjU0l20Wmy32IX6fkRiL05dDLaXPZkoDwkorcd-22umVWlw0XNrlsGVeWkxXnn2Qot0SDYeuqDVXXQw6AEwqhTr9ORMipkOSLjMZnM7MNsRmZTsrwjszEZ97OH6ZRujAIWW0nj-OmKzCZkOSazAZkOyHJFZnMynuObJZkMkeYDkkLis77N0DI1Lb34ieJHi4lRP5VlND66YG4nevMMOqKUcubxFbXrTgdkOibLBzK9q2xhYT-NH8jUcTLFMSMyHpHZkCwnZPJAposutu_JbETGg7Z0e4s0ThCJoDXc53y2dVcPcBVA2IBm_5VCCiV4XEllod5a5BbTsM5WSVNJ283c-VUY01G6lgkPoSkXvmFqD6Zet847iqY2tSYA9uadC7Cj5KEvpB86cX_KlExNa1ITqOZhuqYPLH0tKKuSdJQU7OE9OX_gUvgSHgC0vLJSGJSKtck-36iLApabbkRnmOGBHzBtyHD-ITUyXNb3VQH27aDYXtvayQbM1G77BXfdQDo1gZw7rqjmizyIfQn0hxbkP5ivg_9cL1c634aLfQRroY1Kg7x4aVGleUSadzvlRwV2zZALWi2naAj12j1gYXtR8CiKunm5oYt4tz_wjzTw34CE8PlJ_ki4cBd_jbH1cjS7g0CwltejC_kk3YfvUpsXiODIhMNznXHpkkhyJip0GWwH2P-4GP9xhFZF9FuL8a8U2L9iNEdQV-Sd35NuKkjlD6awTmPuMKBfSDKZR7Si3R-NQngOdX0I-k-8-X-LN41oU5xgXxp0XhULoBl1frNxfT23nTWsa3fZFV9_-07_hAddk0PwBPqXttjhe7_B86q-VqN93u9-t9f9Bp-7Qhsf3cpebXUFnQv0csXNYF02HRM3aOapgnDBDCsLswsj7EVGff7az50Y4u0dipi7m9Hs1sqK5KrrvCzPrXf0DeheGsosk9Qy6TrGQFANhnJDjaRboIwGUhglo4iLPXVllTf-lwZFIzhCVKf7jNeC-oBHZ1tozdVUS2oOzNiVTjRgwo7CDiWVJoZvI8AGg8bdHwiUTOxu4bLei17zoqd6TfSxwWWV2VrPS96ecftjF7tqwmxP_PGTnV7lguuAKWuQlYOUNsRs-VYgU2FrtCUdtEvf4syzg10DCoFp3gnVTfmDirpmVv9mSrij_VZxnFuaTLLVyqv4_JqU54xQXLDz8LNRslbF8knfzKYMckX7zKLohclm4ZtqqVxQb3SvcXlgIoxA-TzsaF9b__jbfS4I1qm5AzR3EZIfoQ1rpUnnFYTTYmdHXr2ewJlNvl7QzptNet0nY7Xr1bP0zlRBxBvgxN4mDYLy2Pd8x8d30Jrts-sgqXpTPS8ujK7puSh_LVzdNYQyahGLVWjI0dre8IvraHUNTNi36gjT1DWbBiyKmiS1LQ5tMLMDYsZF3g1AM-Og9lkf5Bt1sQ1PuL2JFWKcGLqFnVTQpOos59mdty6PYJ3aVpQyptlLax6Qtx9O6IHZTQUHJgKw3HSx-pzqQ9boWdhm5hhdDmSNpDquau7u9DA_F0JTcs8arEytlr1OFzpvvbSzFlvvsAfYJjnALe4hpGCFoumBhfYjlpJ235qdEB6GYZYHUDFtmllXbjM4Oj-oN5piOO3XfetDe60Q6DLYCok_Eqoa3G3ALHg4R5Flmke76U5G1WmbDFGMwfUzu98zH15xwfXhSb7krc2dbWad_v0ZaZs1uUi52H9M_gKEswGTw5vmBXMHaGrgJnzKAkjeCO50l3WtG8Vdr30sQ747UW7yNiGTBxhtbPjABv1tBHHvJnwchpPhhN3A4-DhzhtP7rzB-ObwOPaAjYNxfxQOt7ttMBiNWP_-rj8JJ2OYPNwNbvij1_dG_aE36k8G96NxbzBi9x4Mw3tgYegFO3LXh5jxqBdFx7gn1f6Ga53C42DoTfqDm4htIdL4ZwWeZ8EYfsXz28WNerSTbrfpXpO7fsS10SUZw00Ej6-H7O8JMHXnwU3_5IkuO6HyDvyi-b_6VwU3qYoeD8Yk2ioC_W_PzSHd9gIZE2-FfQHuf7fFHzSskE1NvFW2j-Oj938BAAD__ycF_rc">