1diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp 2index e3707365a9c3..c4a9c82f3c63 100644 3--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp 4+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp 5@@ -38,6 +38,8 @@ public: 6 7 size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, 8 lldb_private::Status &error) override; 9+ size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, 10+ size_t size, Status &error) override; 11 12 private: 13 fvc_t *m_fvc; 14@@ -185,6 +187,7 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 15 // iterate through a linked list of all processes 16 // allproc is a pointer to the first list element, p_list field 17 // (found at offset_p_list) specifies the next element 18+ lldb::addr_t prev = 0; 19 for (lldb::addr_t proc = 20 ReadPointerFromMemory(FindSymbol("allproc"), error); 21 proc != 0 && proc != LLDB_INVALID_ADDRESS; 22@@ -195,6 +198,8 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 23 char comm[fbsd_maxcomlen + 1]; 24 ReadCStringFromMemory(proc + offset_p_comm, comm, sizeof(comm), error); 25 26+ bool interesting = false; 27+ 28 // iterate through a linked list of all process' threads 29 // the initial thread is found in process' p_threads, subsequent 30 // elements are linked via td_plist field 31@@ -231,6 +236,7 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 32 // NB: dumppcb can be LLDB_INVALID_ADDRESS if reading it failed 33 pcb_addr = dumppcb; 34 thread_desc += " (crashed)"; 35+ interesting = true; 36 } else if (oncpu != -1) { 37 // if we managed to read stoppcbs and pcb_size, use them to find 38 // the correct PCB 39@@ -239,13 +245,27 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 40 else 41 pcb_addr = LLDB_INVALID_ADDRESS; 42 thread_desc += llvm::formatv(" (on CPU {0})", oncpu); 43+ interesting = true; 44 } 45 46 ThreadSP thread_sp{ 47 new ThreadFreeBSDKernel(*this, tid, pcb_addr, thread_desc)}; 48 new_thread_list.AddThread(thread_sp); 49 } 50+ 51+ if (interesting) { 52+ printf("pid %d is interesting\n", pid); 53+ if (prev != 0) { 54+ printf("will link %d to %d\n", prev, proc); 55+ if (!WritePointerToMemory(prev + offset_p_list, proc, error)) 56+ assert(0 && "write failed"); 57+ } 58+ prev = proc; 59+ } 60 } 61+ printf("last: %d\n", prev); 62+ if (!WritePointerToMemory(prev + offset_p_list, 0, error)) 63+ assert(0 && "write failed"); 64 } else { 65 const uint32_t num_threads = old_thread_list.GetSize(false); 66 for (uint32_t i = 0; i < num_threads; ++i) 67@@ -295,6 +315,18 @@ size_t ProcessFreeBSDKernelFVC::DoReadMemory(lldb::addr_t addr, void *buf, 68 return rd; 69 } 70 71+size_t ProcessFreeBSDKernelFVC::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, 72+ size_t size, Status &error) { 73+ ssize_t rd = 0; 74+ rd = fvc_write(m_fvc, vm_addr, buf, size); 75+ printf("fvc_write(%p, %p, %d) -> %d\n", vm_addr, buf, size, rd); 76+ if (rd < 0 || static_cast<size_t>(rd) != size) { 77+ error = Status::FromErrorStringWithFormat("Writing memory failed: %s", GetError()); 78+ return rd > 0 ? rd : 0; 79+ } 80+ return rd; 81+} 82+ 83 const char *ProcessFreeBSDKernelFVC::GetError() { return fvc_geterr(m_fvc); } 84 85 #endif // LLDB_ENABLE_FBSDVMCORE 86