Memory (read) access violation handling in C

Discussion in 'C Programming' started by Bit byte, Jun 18, 2006.

  1. Bit byte

    Bit byte Guest

    I have a structure defined like this:

    struct foo
    {
    unsigned int magic ;
    void *mydata ;
    };



    I have macros and defines like this :

    #define MAGIC (0xFABF00D)
    #define ISVALID_PTR(ptr) if(ptr)((ptr)->magic == MAGIC) ? 1 : 0) \ else 0

    When a "bad pointer" - ( an arbitrary integer for example) is passed to
    the macro, my library crashes (as one may well expect).

    I am providing this C interface into another language, where there is a
    great possibility of misuse and integers may be passed (accidentally) to
    my functions, which use this validation macro above. I want my library
    to be robust in the presence of such errors - in otherwords, I need to
    be able to handle memory (READ) access violations gracefully and to be
    able to recover from them - it is fairly trivial to do this in C++, but
    I can't seem to find a way to do this in C.

    Any solutions ?
     
    Bit byte, Jun 18, 2006
    #1
    1. Advertisements

  2. Bit byte

    pete Guest

    That macro can't do anything.
    It's part of an if statement, so it has no value,
    and the statement has no side effects.
    I would write that, this way:

    #define ISVALID_PTR(ptr) (ptr != NULL && ptr -> magic == MAGIC)
     
    pete, Jun 18, 2006
    #2
    1. Advertisements

  3. There's no way in C to test whether a pointer is valid. You can
    easily test whether a pointer is null, but if it's non-null garbage,
    any attempt even to look at its value invokes undefined behavior.

    <OT>I'm surprised that C++ provides a way to detect this; I would have
    thought it also says this is undefined behavior.</OT>
     
    Keith Thompson, Jun 18, 2006
    #3
  4. Bit byte

    spibou Guest

    An arbitrary integer may happen to have a valid value for a pointer. So
    I
    don't think that there is a completely reliable way to check whether a
    pointer
    points to garbage. But if your concern is to check whether a pointer
    points
    to an area of memory from which your programme is not allowed to read
    then the only possible **non-standard/non-portable** solution I can
    think of is the following: it may be that your operating system sends
    some
    specific signal to a programme if it tries to read from memory it is
    not
    supposed to access. If this is the case then you should be able to do
    something
    useful using the signal() function. So I would suggest that you check
    your
    operating system's documentation.
     
    spibou, Jun 18, 2006
    #4
  5. Not in standard C, the topic here. However, the conversion from
    pointer types to (suitable) integers is nonnormatively "intended to
    be consistent with the addressing structure of the execution
    environment" and on all or nearly so platforms even indeterminate or
    dangling pointers do give _some_ value which can usefully be analyzed
    but only in a platform-dependent way.
    Standard C++ does not. It does however provide syntax and mechanism
    for exceptions, and _some_ implementations which are able to catch
    invalid memory accesses, or other 'hardware' faults like zerodivide,
    choose to have them raise platform-defined exceptions -- which can
    then be handled using basically standard constructs.

    _On these platforms_ using (standard C) signal() to establish a
    handler for SIGSEGV or similar is very likely to work as well.

    As already noted this is only a half-measure; on almost all systems it
    is trivial to construct, and often easy to get by accident, pointer
    values which don't cause an immediate fault but are nonetheless
    invalid and when used cause horribly bad results. (I once had a really
    bad Heisenbug of this type; if the program was run under the debugger
    the invalid pointer it used happened to be benign, but if run without
    the debugger it got a different invalid pointer which caused a crash.)

    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Jun 26, 2006
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.