I have an application running in debug mode in Xcode. I want to inspect entire memory of application (stack and heap). I know that I can use lldb for making dumps. I use following command:
(lldb) memory read --outfile filename address
eg.
(lldb) memory read --outfile /tmp/mem-dump.txt --force --count 10000 0x000000010d051000
, but I need specify start address and size of a memory. I do not know how to find regions of memory that my app occupies to make a dump. Is there possibility to find address space of a memory? Maybe other way to make a dump (not using lldb) exist? I do not use jailbroken device.
Then using the simulator alone (not Xcode) click on the AppName to let it run. Then go into Xcode and do Debug > Attach to process by PID. Then type in the name of your App, and click Attach. Then press the Pause icon in Xcode Debug Navigator.
Each process dump will take space in the disk approximately the same size the process uses in memory (column Commit Size in Task Manager). For example, if the w3wp.exe process memory usage is ~1 GB, then the size of a dump file will be around 1 GB.
Both tools below - ProcDump and DebugDiag - work similarly: they can attach themselves as debuggers to a process, then, when the machine is on high-CPU, collect one or more memory dump (s) from that specific process. Note that the tools won't "know" what process is consuming the CPU unless we dig deeper in the performance counters.
If using ProcDump, it easier if we are sure ahead of time what's the culprit - the process that is "eating" much CPU. Both tools need administrative rights to be run. DebugDiag is the preferred tool, since it automates some steps, adds more explicit context, and includes automated memory dump analysis capabilities too.
Use lldb python script bridging interface. It allows to access memory region information and memory data itself, even if application runs on a physical device not on a simulator. No changes to an application required.
To access memory:
import lldb
def processAllMemoryRegions():
process = lldb.debugger.GetSelectedTarget().GetProcess()
memoryRegionInfoList = process.GetMemoryRegions()
numberOfMemoryRegions = memoryRegionInfoList.GetSize()
memoryRegionIndex = 0
while (memoryRegionIndex < numberOfMemoryRegions):
memoryRegionInfo = lldb.SBMemoryRegionInfo()
success = memoryRegionInfoList.GetMemoryRegionAtIndex(memoryRegionIndex, memoryRegionInfo)
if success:
print("Processing: "+str(memoryRegionIndex+1)+"/"+str(numberOfMemoryRegions))
processOneMemoryRegion(process, memoryRegionInfo)
else:
print("Could not get memory at index: "+str(memoryRegionIndex))
memoryRegionIndex = memoryRegionIndex+1
def processOneMemoryRegion(process, memoryRegionInfo):
begAddressOfMemoryRegion = memoryRegionInfo.GetRegionBase()
endAddressOfMemoryRegion = memoryRegionInfo.GetRegionEnd()
if memoryRegionInfo.IsReadable():
print("Beg address of a memory region: "+stringifyMemoryAddress(begAddressOfMemoryRegion))
print("End address of a memory region: "+stringifyMemoryAddress(endAddressOfMemoryRegion))
error = lldb.SBError()
regionSize = endAddressOfMemoryRegion-begAddressOfMemoryRegion
memoryData = process.ReadMemory(begAddressOfMemoryRegion, regionSize, error)
if error.Success():
#do something with memoryData (bytearray) eg. save it to file
pass
else:
print("Could not access memory data.")
else:
print("Memory region is not readable.")
def stringifyMemoryAddress(memoryAddress):
return '0x{:016x}'.format(memoryAddress)
In lldb window
Enter: script
Import the python script: exec(open('/absolute/path/to/mem.py').read())
Enter: processAllMemoryRegions()
You are done.
You can read memory with process.ReadMemory
function. Check sample sniped above.
You can also try launching script execution with :
(lldb) command script import ~/path/to/script.py
It is described here and here, ... but in my case this leads to XCode freeze. It is described here
Code tested on Xcode 11.3.1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With