user157426
user157426

Reputation: 23

How can I prevent (not react to) a segmentation fault?

I am not trying to handle a segmentation fault. I understand how exception handling works, more or less. I would rather not have the fault in the first place. What I want to do is call a function or perform an operation that returns a value telling me whether or not that particular memory location/block is accessible, without actually accessing it and getting the fault.

That is, I would like a C function to probe an address in Linux and/or Mac OS X before actually accessing it. Something like:

result = probe_memory(address,length)

where result is

 0 = writable
 1 = read-only
-1 = nonexistent

or something along those lines.

Is there anything like that in Linux and/or Mac OS X?

Upvotes: 2

Views: 1320

Answers (3)

user703016
user703016

Reputation: 37945

I believe something more or less like the following should work:

int probe_memory(void *address, size_t length) {
    int result, fd[2];

    pipe(fd);  /* Remember to check for errors! */

    errno = 0;
    result = write(fd[1], address, length);

    if (result < 0 || (size_t)result != length || errno == EFAULT) {
        result = 0;
    } else {
        result = 1;
    }

    close(fd[0]);
    close(fd[1]);

    return result;
}

This is a partial solution to your problem, as this code does not check for page protection.

The basic idea is to let the OS read length bytes from address through the call to write. If the memory is not accessible, it will return EFAULT without triggering a segfault.

Jonathan Leffler wrote a fully worked up implementation in his Stack Overflow Questions repository.

Upvotes: 3

You could use mincore(2) and you could read sequentially and parse /proc/self/maps, see proc(5).

Notice that Linux is not designed to give such mapping information quickly. It is well known that emulating application paging (like GNU/Hurd external pagers...) is slow. (e.g. by some low-level, processor specific, SIGSEGV handler).

If your only purpose is to give backtrace information on SIGSEGV, you could use Ian Taylor's libbacktrace from GCC source code.

As some comments said, perhaps you want valgrind.

Upvotes: 1

Steve Barnes
Steve Barnes

Reputation: 28360

You forgot in your list of responses - writeable but in use by the OS/something critical/is actually memory mapped self destruct, etc.

Your best bet is to try to make you code bullet proof a part of which is you only write to locations that you own.

An allocate, check, copy, modify will probably end up being quicker, more reliable, portable and more maintainable that trying to twist the OS(es) arm into giving the information needed and much more so than trying to check it yourself.

Upvotes: 0

Related Questions