jingham added a comment.

In D87868#2309260 <https://reviews.llvm.org/D87868#2309260>, @clayborg wrote:

> In D87868#2308515 <https://reviews.llvm.org/D87868#2308515>, @labath wrote:
>
>> That sounds like a plan. FWIW, here's the implementation I hacked up today:
>>
>>   Status NativeProcessLinux::AllocateMemory(size_t size, uint32_t 
>> permissions,
>>                                             lldb::addr_t &addr) {
>>     PopulateMemoryRegionCache();
>>     auto region_it = llvm::find_if(m_mem_region_cache, [](const auto &pair) {
>>       return pair.first.GetExecutable() == MemoryRegionInfo::eYes;
>>     });
>>     if (region_it == m_mem_region_cache.end())
>>       return Status("No executable memory region found!");
>>     addr_t exe_addr = region_it->first.GetRange().GetRangeBase();
>>   
>>     NativeThreadLinux &thread = *GetThreadByID(GetID());
>>     assert(thread.GetState() == eStateStopped);
>>   
>>     int prot = PROT_NONE;
>>     if (permissions & ePermissionsReadable)
>>       prot |= PROT_READ;
>>     if (permissions & ePermissionsWritable)
>>       prot |= PROT_WRITE;
>>     if (permissions & ePermissionsExecutable)
>>       prot |= PROT_EXEC;
>>   
>>     NativeRegisterContextLinux &reg_ctx = thread.GetRegisterContext();
>>     DataBufferSP registers_sp;
>>     reg_ctx.ReadAllRegisterValues(registers_sp);
>>     uint8_t memory[2];
>>     size_t bytes_read;
>>     ReadMemory(exe_addr, memory, 2, bytes_read);
>>   
>>     reg_ctx.SetPC(exe_addr);
>>     reg_ctx.WriteRegisterFromUnsigned(lldb_rax_x86_64, SYS_mmap);
>>     reg_ctx.WriteRegisterFromUnsigned(lldb_rdi_x86_64, 0);
>>     reg_ctx.WriteRegisterFromUnsigned(lldb_rsi_x86_64, size);
>>     reg_ctx.WriteRegisterFromUnsigned(lldb_rdx_x86_64, prot);
>>     reg_ctx.WriteRegisterFromUnsigned(lldb_r10_x86_64,
>>                                       MAP_ANONYMOUS | MAP_PRIVATE);
>>     reg_ctx.WriteRegisterFromUnsigned(lldb_r8_x86_64, -1);
>>     reg_ctx.WriteRegisterFromUnsigned(lldb_r9_x86_64, 0);
>>     WriteMemory(exe_addr, "\x0f\x05", 2, bytes_read);
>>     PtraceWrapper(PTRACE_SINGLESTEP, thread.GetID(), nullptr, nullptr);
>>     int status;
>>     ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, 
>> thread.GetID(),
>>                                                    &status, __WALL);
>>     assert((unsigned)wait_pid == thread.GetID());
>>     addr = reg_ctx.ReadRegisterAsUnsigned(lldb_rax_x86_64, -ESRCH);
>>   
>>     WriteMemory(exe_addr, memory, 2, bytes_read);
>>     reg_ctx.WriteAllRegisterValues(registers_sp);
>>   
>>     if (addr > -4096)
>>       return Status(-addr, eErrorTypePOSIX);
>>     return Status();
>>   }
>>
>> It needs more error handling, and generalization to non-x86 architectures, 
>> but it actually works, and is enough to make all but one test pass 
>> (TestBitfields.py seems to fail due to some data corruption -- quite 
>> puzzling).
>
> Very cool. That seems simple enough to allow us to try this out, at least on 
> unix variants. Does PTRACE_SINGLESTEP cause _only_ the current thread to 
> single step and keep all other threads paused? We can't allow any other 
> threads making any progress when the process is briefly resumed in a 
> multi-threaded process.
>
> This nice thing is lldb-server _is_ compiled natively for each system so we 
> can rely on system headers for the sys call numbers if they are available. So 
> looks like this could be made to work. Did you also do the deallocate memory? 
> I ran a few expressions and I am not sure that we ever use the deallocate 
> memory packets to debugserver on mac, so it might not be needed.

We deallocate memory when we remove the space we've made for expression result 
variables and the like after running expressions.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87868/new/

https://reviews.llvm.org/D87868

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to