How to determine the wrong memory address?

I was wondering if there is a way to identify the wrong memory address on a specific platform (for x86 64 bit for my case). I need it to catch the program long before it plays out the address and throws a SIGILL / SIGSEGV error.


source to share

4 answers

In general, you cannot. An invalid address looks the same as a valid one. The only invalid address recognized is NULL


So be sure (write your code) that your pointers are valid or NULL

before you use them. Always . There is no way around this.

You can use tools to detect places where your pointers might be invalid (e.g. uninitialized, already freed, etc.), but that's not what you asked for.



You can see all the memory mappings of the current process in the file /proc/self/maps

. Just open this file and process its contents: each line starts with two hexadecimal numbers separated by a character -

, which are the addresses that the process can access.

All memory addresses that appear in your process are there, but some of them may not have read, write or execute permissions; if you need to check them, you will also need to read and parse the next field.

An example of the contents of this file:

$ cat /proc/self/maps
00400000-0040c000 r-xp 00000000 08:01 24340229                           /bin/cat
0060b000-0060c000 r--p 0000b000 08:01 24340229                           /bin/cat
0060c000-0060d000 rw-p 0000c000 08:01 24340229                           /bin/cat
0253e000-0255f000 rw-p 00000000 00:00 0                                  [heap]
7f050d97e000-7f050d97f000 rw-p 00000000 00:00 0 
7fff9509e000-7fff950bf000 rw-p 00000000 00:00 0                          [stack]
7fff951fe000-7fff95200000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]




You can use the function mincore

. See Description here .

If the address does not match the virtual address space of the process, it mincore

will return an error.

This is not 100%, as memory can be mapped to the virtual address space of the process, but not committed (no physical pages are allocated). This will catch most of your pointers to garbage, if not all.

You can read more about memory mapping using a function mmap

in here



If specifically prevention SIGSEGV

is your goal, remember that you can catch segfaults with signal

. You don't have to wait to do this from a usage point of view (where it's presumably too late) - you can override the handler temporarily SIGSEGV

, run all the addresses you want to check with a simple identification routine (read the target value, write it down), and then - if the handler never encountered any errors - restore the original handler and move on to the section of code that needs to know that all addresses it receives are safe ("safe") to dereference. If not, you can pick up or return your error to the caller.

However, you can't tell at all if the address is actually valid or not, because the underlying system has probably allocated some things around the actual objects you requested with malloc

, and accessing those areas most likely won't cause the program to crash - as far as reading memory reads, these addresses are also effectively "valid" even if they are not a C object. But if all you have to do is, for example, make sure that reading an external buffer does not crash your code. it is not an obstacle to overcome.



All Articles