[lldb][minidump] write the memory after an unreadable page when saving minidump (#212641)
**Issue**
An internal failing test found a latent bug in lldb's save-core
(minidump writer). When it saved a memory range that had an unreadable
page in it, it:
- stopped at that page and threw away the readable memory after it,
Result: We couldnot get the stack traces from the minidump. in the below
example the **current logic is bailing out at the 6th region and not
writing other 70 regions.**
```
[satyajanga@devgpu011.eag2 ~/fbsource/fbcode (eacbfddefa|remote/master)]$ lldb
(lldb) file /data/users/satyajanga/fbsource/buck-out/v2/art/fbcode/55005549ebc49982/sand/tests/__Coro__/Coro
Current executable set to '/data/users/satyajanga/fbsource/buck-out/v2/art/fbcode/55005549ebc49982/sand/tests/__Coro__/Coro' (x86_64).
(lldb) b coro.cpp:44 Breakpoint 1: where = Coro`::co_main() + 197 at coro.cpp:44, address = 0x00000000002335a5
(lldb) r
Process 3374177 launched: '/data/users/satyajanga/fbsource/buck-out/v2/art/fbcode/55005549ebc49982/sand/tests/__Coro__/Coro' (x86_64)
warning: (x86_64) /data/users/satyajanga/fbsource/buck-out/v2/art/fbcode/55005549ebc49982/sand/tests/__Coro__/__Coro__shared_libs_symlink_tree/libfolly_futures_tree.so unable to locate separate debug file (dwo, dwp). Debugging will be degraded (troubleshoot with https://fburl.com/missing_dwo)
Process 3374177 stopped
* thread #9, name = 'GlobalCPUThread', stop reason = breakpoint 1.1
frame #0: 0x00000000002335a5 Coro`::co_main() at coro.cpp:44
(lldb) script
Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
>>> target = lldb.debugger.GetSelectedTarget()
>>> process = target.GetProcess()
>>> regions = process.GetMemoryRegions()
>>> len(regions)
76
>>> for i in range(len(regions)):
... region = regions[i]
... if not region.IsReadable():
... continue
... base, end = region.GetRegionBase(), region.GetRegionEnd()
... size = end - base
... name = region.GetName() or ""
... error = lldb.SBError()
... data = process.ReadMemory(base, size, error)
... bytes_read = len(data) if data else 0
... if error.Success() and bytes_read == size:
... continue
... print(f" FAILED to read region {i}, {name} ")
...
FAILED to read region 6,
FAILED to read region 8,
FAILED to read region 10,
FAILED to read region 12,
FAILED to read region 15,
FAILED to read region 65, [vvar]
FAILED to read region 66, [vvar_vclock]
>>>
```
**Fix**
Rewrote ReadWriteMemoryInChunks in MinidumpFileBuilder.cpp to: save the
readable bytes, zero-fill the unreadable page, keep going, and record
the exact number of bytes actually written. That keeps the dump aligned
and preserves memory after a hole.
**Test**
Added an lldb API test that builds a memory region with a readable page
followed by an unreadable tail, saves a core of it, and checks the
readable data comes back intact
GitOrigin-RevId: 7f04a40a220e2c741d4ae88a39ed9d4c7c87ff25
4 files changed