<font size=2 face="sans-serif">I have experimented with the GetMemoryRegionInfo
approach on the internal APIs already, it has some positives and negatives.</font>
<br>
<br><font size=2 face="sans-serif">- GetMemoryRegionInfo is unimplemented
for Linux and Mac core dumps. That's not necessarily a bad thing as it
could be implemented the "right" way. (As Jim said GetMemoryRegionInfo
would have to return the right thing for an unmapped region.) Interestingly
when I've worked on Windows core dumps before I've seen that MiniDump,
with the right flags, will deliberately insert a region in the middle of
the memory ranges to represent the unmapped space, on 64 bit it's quite
a large section.</font>
<br>
<br><font size=2 face="sans-serif">- Using GetMemoryRegionInfo to iterate
might be quite expensive if there are many small memory regions.</font>
<br>
<br><font size=2 face="sans-serif">- One reason I hadn't looked at just
exposing an SBGetMemoryRegionInfo is that it wouldn't match a lot of the
SB API's at the moment (for example for Threads and Sections) which tend
work by having GetNumXs() and GetXAtIndex() calls. Iterating with SBGetMemoryRegionInfo
would be non-obvious to the user of the API since it doesn't match the
convention. It would need to be documented in the SBGetMemoryRegionInfo
API.</font>
<br>
<br><font size=2 face="sans-serif">- I've found the only way to reliably
filter out inaccessible memory is to do a test read and check the error
return code. I'm pretty sure I've seen some that are readable via a memory
read but marked read=false, write=false, execute=false. (I can't remember
the exact case now off the top of my head, but I think it might have been
allocated but uncommitted memory or similar.)</font>
<br>
<br><font size=2 face="sans-serif">- Using GetMemoryRegionInfo over a remote
connection on Linux and Mac worked well but seemed to coalesce some of
the memory regions together. It also only allows for read/write/exec attributes
to be passed. That's a shame as a live process can often tell you more
about what the region is for. The remote command memory map looks like
it sends back XML so it might be possible to insert custom properties in
there to give more information but I'm not sure how safe it is to do that,
I don't know the project quite well enough to understand all the use cases
for the protocol.</font>
<br>
<br><font size=2 face="sans-serif">- Extended infomation /proc/pid/maps
marking a region as [stack] would be lost. All you would get is read/write/exec
info. (That said supporting everything every platform can provide might
be a bit much.)</font>
<br>
<br><font size=2 face="sans-serif">- LLDB's ReadMemory implementations
seem to return 0's for missing memory that should be accessible. It might
be nice to include whether the memory is backed by real data or not in
the API. (For example Linux core files can be missing huge pages depending
on the setting of /proc/PID/coredump_filter or files can simply be truncated.)</font>
<br>
<br><font size=2 face="sans-serif">I could implement the GetMemoryRegionInfo
iteration mechanism pretty quickly and it would actually fit my purposes
as far as providing all the addresses you can sensibly access. </font>
<br>
<br><font size=2 face="sans-serif">I'm quite keen to provide a patch but
don't want to provide one that is at odds with how the rest of lldb works
or provides data that's only useful to me so I'm quite keen to get a bit
of feedback on what the preferred approach would be. It could be that providing
both SBGetMemoryRegionInfo and the SBGetNumMemoryRegions/SBGetMemoryRegionAtIndex
pair is the right solution.</font>
<br>
<br><font size=2 face="sans-serif">Would a patch also need to provide a
command to dump this information as it can be awkward to have data that's
only accessible via the API?</font>
<br><font size=1 face="Arial"><br>
</font>
<table width=650 style="border-collapse:collapse;">
<tr height=8>
<td width=465 style="border-style:none none none none;border-color:#000000;border-width:0px 0px 0px 0px;padding:0px 0px;"><font size=3 color=#8f8f8f face="Arial"><b>Howard
Hellyer</b></font><font size=1 face="Arial"><br>
IBM Runtime Technologies, IBM Systems</font>
<td width=184 style="border-style:none none none none;border-color:#000000;border-width:0px 0px 0px 0px;padding:0px 0px;">
<div align=right><font size=1 face="Arial"><br>
</font></div></table>
<br>
<br>
<br><tt><font size=2>Greg Clayton <gclayton@apple.com> wrote on 12/05/2016
19:09:49:<br>
<br>
> From: Greg Clayton <gclayton@apple.com></font></tt>
<br><tt><font size=2>> To: Howard Hellyer/UK/IBM@IBMGB</font></tt>
<br><tt><font size=2>> Cc: lldb-dev@lists.llvm.org</font></tt>
<br><tt><font size=2>> Date: 12/05/2016 19:10</font></tt>
<br><tt><font size=2>> Subject: Re: [lldb-dev] Listing memory regions
in lldb</font></tt>
<br><tt><font size=2>> <br>
> We have a way internally with:<br>
> <br>
> virtual Error<br>
> lldb_private::Process::GetMemoryRegionInfo (lldb::addr_t
<br>
> load_addr, MemoryRegionInfo &range_info);<br>
> <br>
> This isn't expose via the public API in lldb::SBProcess. If you <br>
> want, you can expose this. We would need to expose a <br>
> SBMemoryRegionInfo and the call could be:<br>
> <br>
> namespace lldb<br>
> {<br>
> class SBProcess<br>
> {<br>
> SBError GetMemoryRegionInfo (lldb::addr_t
load_addr, <br>
> SBMemoryRegionInfo &range_info);<br>
> };<br>
> }<br>
> <br>
> then you would call this API with address zero and it would return
a<br>
> SBMemoryRegionInfo with an address range and if that memory is read/<br>
> write/execute. On MacOSX we always have a page zero at address 0 for<br>
> 64 bit apps so it would respond with:<br>
> <br>
> [0x0 - 0x100000000) read=false, write=false, execute=false<br>
> <br>
> Then you call the function again with the end address of the previous
range. <br>
> <br>
> I would love to see this functionality exported through our public
<br>
> API. Let me know if you are up for making a patch. If you are, you
<br>
> might want to quickly read the following web page to see the rules
<br>
> that we apply to anything going into our public API:<br>
> <br>
> </font></tt><a href="http://lldb.llvm.org/SB-api-coding-rules.html"><tt><font size=2>http://lldb.llvm.org/SB-api-coding-rules.html</font></tt></a><tt><font size=2><br>
> <br>
> <br>
> Greg<br>
> <br>
> > On May 12, 2016, at 6:20 AM, Howard Hellyer via lldb-dev <lldb-<br>
> dev@lists.llvm.org> wrote:<br>
> > <br>
> > I'm working on a plugin for lldb and need to scan the memory
of a <br>
> crashed process. Using the API to read chunks of memory and scan <br>
> (via SBProcess::Read*) for what I'm looking for is easy but I <br>
> haven't been able to find a way to find which address ranges are <br>
> accessible. The SBProcess::Read* calls will return an error on an
<br>
> invalid address but it's not an efficient way to scan a 64 bit address
space. <br>
> > <br>
> > This seems like it blocks simple tasks like scanning memory for
<br>
> blocks allocated with a header and footer to track down memory <br>
> leaks, which is crude but traditional, and ought to be pretty quick
<br>
> to script via the Python API. <br>
> > <br>
> > At the moment I've resorted to running a python script prior
to <br>
> launching my plugin that takes the output of "readelf --segments",
/<br>
> proc/<pid>/maps or "otool -l" but this isn't ideal.
On the <br>
> assumption that I'm not missing something huge I've looked at <br>
> whether it is possible to extend LLDB to provide this functionality
<br>
> and it seems possible, there are checks protecting calls to read <br>
> memory that use the data that would need to be exposed. I'm working
<br>
> on a prototype implementation which I'd like to deliver back at some<br>
> stage but before I go too far does this sound like a good idea? <br>
> > Howard Hellyer<br>
> > IBM Runtime Technologies, IBM Systems <br>
> > <br>
> > <br>
> > _______________________________________________<br>
> > lldb-dev mailing list<br>
> > lldb-dev@lists.llvm.org<br>
> > </font></tt><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev"><tt><font size=2>http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev</font></tt></a><tt><font size=2><br>
> <br>
</font></tt>