Thanks for checking. I also realized there’s no safe location even on Linux because of:
Why memory mappings (like
[heap],[stack]) differ1. Address Space Layout Randomization (ASLR)
- This is the main reason.
- ASLR randomizes the base addresses of memory regions (heap, stack, libraries, etc.) for each process.
- It’s a security feature that helps prevent certain kinds of attacks (like buffer overflows leading to shellcode execution).
That said julia always maps in at 0x00400000 except it’s seemingly down to Julia 1.0 but not on Windows.
Which is unlike for e.g. cat where its binary address (and everything) in randomized:
shell> cat /proc/self/maps
562f08592000-562f08594000 r--p 00000000 08:02 108790662 /usr/bin/cat
562f08594000-562f08598000 r-xp 00002000 08:02 108790662 /usr/bin/cat
562f08598000-562f0859a000 r--p 00006000 08:02 108790662 /usr/bin/cat
562f0859a000-562f0859b000 r--p 00007000 08:02 108790662 /usr/bin/cat
562f0859b000-562f0859c000 rw-p 00008000 08:02 108790662 /usr/bin/cat
562f39845000-562f39866000 rw-p 00000000 00:00 0 [heap]
My next thought, can I map a page in at a known address (on Linux, but preferably on all platforms the same one). I think I can technically but would it likely interfere with Julia’s operation? Might Julia or libc ask for that address, or do programs usually just ask for pages and the kernel gives you a free address?
I’m not sure I can do this on Windows, or FreeBSD (or other more security obsessed BSD), but on some address at least on Windows, and fixed one on Linux (I’m just not sure if it’s advised in Julia, for fixed, even if I always can):
MAP_FIXED
Don't interpret addr as a hint: place the mapping at exactly that address. addr must be suitably aligned: for most architectures a multiple of the page size is sufficient; however, some architectures may impose additional restrictions. If the memory region specified by addr and length overlaps pages of any existing mapping(s), then the overlapped part of the existing mapping(s) will be discarded. If the specified address cannot be used, mmap() will fail. Software that aspires to be portable should use the MAP_FIXED flag with care, keeping in mind that the exact layout of a process's memory mappings is allowed to change significantly between Linux versions, C library versions, and operating system releases. Carefully read the discussion of this flag in NOTES! MAP_FIXED_NOREPLACE (since Linux 4.17) This flag provides behavior that is similar to MAP_FIXED with respect to the addr enforcement, but differs in that MAP_FIXED_NOREPLACE never clobbers a preexisting mapped range. If the requested range would collide with an existing mapping, then this call fails with the error EEXIST. This flag can therefore be used as a way to atomically (with respect to other threads) attempt to map an address range: one thread will succeed; all others will report failure. Note that older kernels which do not recognize the MAP_FIXED_NOREPLACE flag will typically (upon detecting a collision with a preexisting mapping) fall back to a “non- MAP_FIXED” type of behavior: they will return an address that is different from the requested address. Therefore, backward-compatible software should check the returned address against the requested address.