Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a dump of entire memory for iOS application running in debug mode in XCode

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.

like image 421
rojarand Avatar asked May 30 '20 06:05

rojarand


People also ask

How do I debug an app in Xcode?

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.

What is the size of a process dump file?

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.

How do you debug high CPU usage?

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.

What is the difference between ProcDump and debugdiag?

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.


1 Answers

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:

  • Copy and save following python script to your Mac. Let's name it mem.py
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)
  • Stop execution of an application on a breakpoint

In lldb window

  • Enter: script

  • Import the python script: exec(open('/absolute/path/to/mem.py').read())

  • Enter: processAllMemoryRegions()

enter image description here

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.

like image 118
rojarand Avatar answered Oct 12 '22 11:10

rojarand