Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5349c66

Browse files
authored
[lldb] [Process/FreeBSDKernel] List threads in correct order (llvm#178306)
In FreeBSD, allproc is a prepend list and new processes are appended at head. This results in reverse pid order, so we first need to order pid incrementally then print threads according to the correct order. Before: ``` Process 0 stopped * thread #1: tid = 101866, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff8015882f780, flags=259) at sched_ule.c:2448:26, name = '(pid 12991) dtrace' thread #2: tid = 101915, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff80158825780, flags=259) at sched_ule.c:2448:26, name = '(pid 11509) zsh' thread #3: tid = 101942, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff80142599000, flags=259) at sched_ule.c:2448:26, name = '(pid 11504) ftcleanup' thread llvm#4: tid = 101545, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff80131898000, flags=259) at sched_ule.c:2448:26, name = '(pid 5599) zsh' thread llvm#5: tid = 100905, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff80131899000, flags=259) at sched_ule.c:2448:26, name = '(pid 5598) sshd-session' thread llvm#6: tid = 101693, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff8015886e780, flags=259) at sched_ule.c:2448:26, name = '(pid 5595) sshd-session' thread llvm#7: tid = 101626, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff801588be000, flags=259) at sched_ule.c:2448:26, name = '(pid 5592) sh' ... ``` After: ``` (lldb) thread list Process 0 stopped * thread #1: tid = 100000, 0xffffffff80bf9322 kernel`sched_switch(td=0xffffffff81abe840, flags=259) at sched_ule.c:2448:26, name = '(pid 0) kernel' thread #2: tid = 100035, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff801052d9780, flags=259) at sched_ule.c:2448:26, name = '(pid 0) kernel/softirq_0' thread #3: tid = 100036, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff801052d9000, flags=259) at sched_ule.c:2448:26, name = '(pid 0) kernel/softirq_1' thread llvm#4: tid = 100037, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff801052d8780, flags=259) at sched_ule.c:2448:26, name = '(pid 0) kernel/softirq_2' thread llvm#5: tid = 100038, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff801052d8000, flags=259) at sched_ule.c:2448:26, name = '(pid 0) kernel/softirq_3' thread llvm#6: tid = 100039, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff801052d7780, flags=259) at sched_ule.c:2448:26, name = '(pid 0) kernel/softirq_4' thread llvm#7: tid = 100040, 0xffffffff80bf9322 kernel`sched_switch(td=0xfffff801052d7000, flags=259) at sched_ule.c:2448:26, name = '(pid 0) kernel/softirq_5' ... ``` Signed-off-by: Minsoo Choo <[email protected]>
1 parent 4f2db80 commit 5349c66

1 file changed

Lines changed: 21 additions & 11 deletions

File tree

lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list,
162162
int32_t offset_td_name = ReadSignedIntegerFromMemory(
163163
FindSymbol("thread_off_td_name"), 4, -1, error);
164164

165-
// fail if we were not able to read any of the offsets
165+
// Fail if we were not able to read any of the offsets.
166166
if (offset_p_list == -1 || offset_p_pid == -1 || offset_p_threads == -1 ||
167167
offset_p_comm == -1 || offset_td_tid == -1 || offset_td_plist == -1 ||
168168
offset_td_pcb == -1 || offset_td_oncpu == -1 || offset_td_name == -1)
@@ -174,29 +174,39 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list,
174174
ReadSignedIntegerFromMemory(FindSymbol("dumptid"), 4, -1, error);
175175
lldb::addr_t dumppcb = FindSymbol("dumppcb");
176176

177-
// stoppcbs is an array of PCBs on all CPUs
178-
// each element is of size pcb_size
177+
// stoppcbs is an array of PCBs on all CPUs.
178+
// Each element is of size pcb_size.
179179
int32_t pcbsize =
180180
ReadSignedIntegerFromMemory(FindSymbol("pcb_size"), 4, -1, error);
181181
lldb::addr_t stoppcbs = FindSymbol("stoppcbs");
182182

183183
// from FreeBSD sys/param.h
184184
constexpr size_t fbsd_maxcomlen = 19;
185185

186-
// iterate through a linked list of all processes
187-
// allproc is a pointer to the first list element, p_list field
188-
// (found at offset_p_list) specifies the next element
186+
// Iterate through a linked list of all processes. New processes are added
187+
// to the head of this list. Which means that earlier PIDs are actually at
188+
// the end of the list, so we have to walk it backwards. First collect all
189+
// the processes in the list order.
190+
std::vector<lldb::addr_t> process_addrs;
189191
for (lldb::addr_t proc =
190192
ReadPointerFromMemory(FindSymbol("allproc"), error);
191193
proc != 0 && proc != LLDB_INVALID_ADDRESS;
192194
proc = ReadPointerFromMemory(proc + offset_p_list, error)) {
195+
process_addrs.push_back(proc);
196+
}
197+
198+
// Processes are in the linked list in descending PID order, so we must walk
199+
// them in reverse to get ascending PID order.
200+
for (auto proc_it = process_addrs.rbegin(); proc_it != process_addrs.rend();
201+
++proc_it) {
202+
lldb::addr_t proc = *proc_it;
193203
int32_t pid =
194204
ReadSignedIntegerFromMemory(proc + offset_p_pid, 4, -1, error);
195205
// process' command-line string
196206
char comm[fbsd_maxcomlen + 1];
197207
ReadCStringFromMemory(proc + offset_p_comm, comm, sizeof(comm), error);
198208

199-
// iterate through a linked list of all process' threads
209+
// Iterate through a linked list of all process' threads
200210
// the initial thread is found in process' p_threads, subsequent
201211
// elements are linked via td_plist field
202212
for (lldb::addr_t td =
@@ -214,7 +224,7 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list,
214224
ReadCStringFromMemory(td + offset_td_name, thread_name,
215225
sizeof(thread_name), error);
216226

217-
// if we failed to read TID, ignore this thread
227+
// If we failed to read TID, ignore this thread.
218228
if (tid == -1)
219229
continue;
220230

@@ -224,7 +234,7 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list,
224234
thread_desc += thread_name;
225235
}
226236

227-
// roughly:
237+
// Roughly:
228238
// 1. if the thread crashed, its PCB is going to be at "dumppcb"
229239
// 2. if the thread was on CPU, its PCB is going to be on the CPU
230240
// 3. otherwise, its PCB is in the thread struct
@@ -233,8 +243,8 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list,
233243
pcb_addr = dumppcb;
234244
thread_desc += " (crashed)";
235245
} else if (oncpu != -1) {
236-
// if we managed to read stoppcbs and pcb_size, use them to find
237-
// the correct PCB
246+
// If we managed to read stoppcbs and pcb_size, use them to find
247+
// the correct PCB.
238248
if (stoppcbs != LLDB_INVALID_ADDRESS && pcbsize > 0)
239249
pcb_addr = stoppcbs + oncpu * pcbsize;
240250
else

0 commit comments

Comments
 (0)