func findMemoryBlock(_ address: UnsafeRawPointer) -> MemoryBlock

Given an arbitrary memory address how do I find (in runtime) the nature of memory block it belongs to?

For stack addresses I guess there's some "stack start" and "stack end" of the current thread. For other threads' stacks - I guess I'd have to enumerate all threads to get those ranges. I also found that I can use malloc_size and sometimes it gives me correct result (the size if non zero at least), although it doesn't give me the beginning of the block memory address belongs to. For anything else I have no clue at the moment.

Ideal method I am looking for:

struct MemoryBlock { let type: MemoryBlockType // stack, heap, unmapped, etc let start: UnsafeRawPointer let size: Int let attributes // e.g. red / write }

func findMemoryBlock(_ address: UnsafeRawPointer) -> MemoryBlock

PS. the language doesn't matter (e.g. can be C) so long as this method works in a swift/obj-c app.

Answered by DTS Engineer in 723915022

For debugging purposes only my go-to tool for this is mach_vm_read.

Note that this is a relatively slow call, so it’d be best to tweak your dumpByte abstraction to return a block of bytes.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Given an arbitrary memory address how do I find (in runtime) the nature of memory block it belongs to?

This is not easy. Why do you need to do this?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I want something quite simple:

void dumpByte(const char* address) {
    char v = *address;
    bool success = ......;
    printf("success: %d, %0x\n", success, v);
}

The memory access can either succeed or fail with, say EXC_BAD_ACCESS.

I found this article of yours:

https://developer.apple.com/forums/thread/113742

Could you recommend a sample code to achieve that goal on macOS? This is for debugging purposes and accessing wrong memory in this case if not an error.

Thank you.

Accepted Answer

For debugging purposes only my go-to tool for this is mach_vm_read.

Note that this is a relatively slow call, so it’d be best to tweak your dumpByte abstraction to return a block of bytes.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

It works, thank you!

#include <mach/mach.h>
#include <mach/mach_vm.h>

int safe_memcpy(void* dst, const void* src, size_t size) {
    mach_vm_size_t outSize = 0;
    kern_return_t err = mach_vm_read_overwrite(mach_task_self(), (mach_vm_address_t)src, size, (mach_vm_address_t)dst, &outSize);
    if (err) return err;
    assert(outSize == size);
    return true;
}

void dumpByte(const char* address) {
    unsigned char buffer = 0;
    int err = safe_memcpy(&buffer, address, 1);
    printf("error: %d, byte: %02x\n", err, buffer);
}

Note that this is a relatively slow call, so it’d be best to tweak your dumpByte abstraction to return a block of bytes.

yep, got you.

func findMemoryBlock(_ address: UnsafeRawPointer) -&gt; MemoryBlock
 
 
Q