labath added inline comments.

================
Comment at: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp:1354
+  auto region_it = llvm::find_if(m_mem_region_cache, [](const auto &pair) {
+    return pair.first.GetExecutable() == MemoryRegionInfo::eYes;
+  });
----------------
jankratochvil wrote:
> Finding arbitrary address would not be safe if LLDB supports [[ 
> https://lldb.llvm.org/status/projects.html#non-stop-debugging | non-stop mode 
> if implemented ]]. It also makes the address a bit non-deterministic. IIRC 
> GDB is using executable's e_entry (="_start" if it exists). But I do not have 
> any strong reason for that.
> 
Lldb also uses the program entry point for the "call mmap(...)" approach of 
allocating memory. That is a pretty good choice when one needs to find a line 
of code that will not be executed during normal program operation (not stop or 
otherwise). However:
- here we don't need that requirement (for all-stop mode, anyway), as we're not 
calling any function (even mmap can execute a fair amount of code). We're just 
executing a single instruction.
- technically, there's nothing preventing the application from unmapping the 
entry point address, or reusing it for something else. If I wanted a foolproof 
solution, I'd still need to implement a fallback algorithm (as well as the code 
to search for the entry point, as we right now don't have anything that 
lldb-server could use).

Given that, it seems better to just go for the more complete solution straight 
away. It's true that this makes the address harder to predict (I'm trying not 
to use the word nondeterministic, because that's not really it), but such is 
life. And coming up with a non-stop-compatible solution for this is so 
complicated that I'd leave this for some other time (worst case: we disable 
this feature, or force a temporary stop of all threads).


================
Comment at: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp:1400
+                            .ToError())
+    return std::move(Err);
+
----------------
DavidSpickett wrote:
> Is it possible that the page we find is executable but not writeable and is 
> this part intended to handle that?
> (maybe this is a silly question, the code had to be written into that page in 
> the first place I guess)
Ptrace bypasses normal write-protection checks (~all code is not writable these 
days, and we wouldn't be able to set breakpoints otherwise), so checking for 
writable addresses would not be useful.


================
Comment at: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp:1404
+
+  int req = SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP : PTRACE_CONT;
+  if (llvm::Error Err =
----------------
DavidSpickett wrote:
> Could you add a comment here explaining this? Like "either we single step 
> just syscall, or continue then hit a trap instruction after the syscall"
> (if I have that right)
> 
> The description for PTRACE_SINGLESTEP confused me a bit with "next entry to":
> > Restart the stopped tracee as for PTRACE_CONT, but arrange for
> > the tracee to be stopped at the next entry to or exit from a
> > system call, or after execution of a single instruction,
> > respectively.
> 
> But I assume what happens here is you step "syscall" and then the whole mmap 
> call happens, then you come back. Instead of getting kept before the mmap 
> actually happens.
> 
> 
Yes, that's exactly what happens. Ptrace can't step "into" the kernel. The 
reason that description is confusing is because it a description of both 
PTRACE_SINGLESTEP *and* PTRACE_SYSCALL, with the latter stopping before the 
syscall.

I've considered using a sequence of two PTRACE_SYSCALLs to avoid the trap 
instruction requirement, but it wasn't clear to me that this would help in any 
way (and it would make the code longer).


================
Comment at: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp:1419
+  uint64_t result = reg_ctx.ReadRegisterAsUnsigned(syscall_data.Result, 
-ESRCH);
+  uint64_t errno_threshold =
+      (uint64_t(-1) >> (64 - 8 * m_arch.GetAddressByteSize())) - 0x1000;
----------------
DavidSpickett wrote:
> What does this calculation do/mean? (0x1000 is 4k which is a page size maybe?)
This is the linux syscall convention for returning errors. The fact that it 
matches the page size is probably not accidental, though it was not strictly 
necessary.

I've added a short comment to elaborate.


================
Comment at: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp:1421
+      (uint64_t(-1) >> (64 - 8 * m_arch.GetAddressByteSize())) - 0x1000;
+  if (result > errno_threshold) {
+    return llvm::errorCodeToError(
----------------
DavidSpickett wrote:
> For these ifs, are you putting {} because the return is split over two lines? 
> I think it would compile without but is this one of the exceptions to the 
> coding standard? (if clang-format isn't doing this for you that is)
clang-format never adds new tokens -- it just reformats existing ones.

Regarding the coding standard, this is in a fairly grey area. I could invoke 
the "braces should be used when a single-statement body is complex enough that 
it becomes difficult to see where the block containing the following statement 
began" rule and say this statement is "complex enough" (I think it was even 
more complex when I've first written it). I'm sure some people wouldn't 
consider it complex, but I think it's better to err on the side of adding more 
braces (I generally add braces for all multi-line statements).


================
Comment at: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp:1444
+    prot |= PROT_EXEC;
+
+  llvm::Expected<uint64_t> Result =
----------------
jankratochvil wrote:
> Some sanity check 'permissions' does not have set a bit which 
> NativeProcessLinux::AllocateMemory does not understand?
A new permission flag seems fairly unlikely, but sure, why not..


================
Comment at: 
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp:1249
+  case llvm::Triple::x86:
+    return MmapData{192, 91};
+  case llvm::Triple::x86_64:
----------------
DavidSpickett wrote:
> What's the source for these numbers?
There are plenty of ways to find this -- internet is full of linux system call 
tables. I just preprocessed a file referencing SYS_MMAP/MUNMAP constants. :P

I also added a note about the file they can be found in 
(/usr/include/asm/unistd.h)


================
Comment at: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:2346
+
+  const lldb::addr_t size = packet.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+  if (size == LLDB_INVALID_ADDRESS)
----------------
DavidSpickett wrote:
> (assuming this packet type is supported by GDB already) Does it also use hex 
> for the size field? I ask because I came across some file loading packets 
> that were hex for lldb, int for gdb.
> 
> Obviously we don't have a hard requirement to match but if we're adding 
> something new might as well.
This isn't adding a completely new packet (you'll notice the patch does not 
include any clientside changes). This packet is already supported by 
debugserver, and I believe it is an lldb addition -- I did not come across 
anything like it in the gdb docs.

However, I would be interested to hear about the protocol mismatches you've 
found.


================
Comment at: 
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:2366
+    }
+  }
+
----------------
DavidSpickett wrote:
> Is no permissions here a valid packet? (as long as mmap doesn't mind I guess 
> it is)
Yeah, you can do that in theory -- permissions can be later changed with 
mprotect(2). Lldb does not make any use of that though.


================
Comment at: lldb/test/API/lang/c/stepping/TestStepAndBreakpoints.py:23
     @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr17932')
-    @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr14437")
     @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24777")
----------------
DavidSpickett wrote:
> DavidSpickett wrote:
> > This test now passes *because* we have the ability to allocate memory, 
> > correct? (I thought it was a stray change at first)
> Actually shouldn't this be an expected failure on non x86 linux?
This is a funny one. The reason this test fails is because of the stop-id check 
on line 148 (IIRC). Without this feature lldb will allocate memory by finding 
and calling the mmap libc function. This seems to mess up the "expression stop 
id" counter. So it's a real bug, but not one that is likely to cause problems 
for most people.

However, you're right that this "bug" is not "fixed" only on x86.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D89124

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

Reply via email to