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.

Accepted Reply

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"

Replies

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"

  • A debugging tool. Part of the puzzle is knowing upfront if I can safely read N bytes of memory from a given address, or somehow try/catch reading from memory that can fail with, say, address error when I am reading past the heap, etc. I can drop down to C if that's not easy in Swift.

Add a Comment

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.

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.