How can I disable an error 157, Access Violation, for a small block of code?

How can I disable an error 157, Access Violation, for a small block of code?

Imagen de qolin

 

I have a procedure FRED that is given an argument which is supposed to be a memory address. The job of FRED is to test the value held at that address, and do something if the value meets certian criteria. I am well versed in using C_PTR and C_F_POINTER to convert the address into a Fortran pointer that I can then test in vanilla Fortran code.

My problem is that sometimes the address supplied is invalid, and any attempt to look at its contents causes "forrtl: severe (157): Program Exception - access violation".

I want to find a way to either (a) detect that the address is invalid, and avoid using it; or (b) disable the error 157 for the body of FRED, and re-enable it before FRED returns.

I have been playing around with SIGNAL and SIGNALQQ for a few hours now, without success. The help system for these routines is pretty comprehensive, but alas it omits (what to me, appear to be) vital details. Eg. the entry for SIGNALQQ says:  

SIGNALQQ installs the function func as the handler for a signal of the type specified by sig. If you do not install a handler, the system by default terminates the program with exit code 3 when an interrupt signal occurs.​

Which is fine as far as it goes, but it doesn't tell you how to reverse the effect of a previous call to SIGNALQQ, i.e. how to do not install a handler​, or how to uninstall one, so as to reset things as they were before the call. 

Please, can anyone share some example code that might do this? Or point me at some way to detect that a memory address is invalid? The help entry for "Using SIGNALQQ" mentions a sample program called GETEPTRS, but my installation doesn't have this. I am using VS2012 and Composer XE 2013, version 13.1.3.198.

 Qolin

publicaciones de 13 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.
Imagen de jimdempseyatthecove

If FRED is receiving an invalid pointer (pointing to address not assigned to virtual memory space, or to protected address of virtual memory space), then you will observe the fault. However, the fact that FRED receives such pointers means there is a strong likelihood that FRED is receiving pointers into arbitrary positions into mapped memory space, meaning the pointee may not be a bonified object, it also may be an incorrect object or whatnot (code, random stack location, unallocated memory, freed memory, more...). FRED won't know this and may do something under false pretense/assumption. You will need to assert the validity of these pointers in the callers to FRED.

A good starting place would be to look at the stack traceback after the error to find the caller (you will need to enable this when you compile your code). A second thing you can do is, assuming FRED is checking something specific. Something like, in front of the piece of code that you wish to monitor with FRED, is to tell FRED a valid range of addresses (e.g. objects, lists, arrays, etc...) and then for FRED to maintain a list of these. Later when FRED receives the pointer to check, FRED can compare the pointer to the valid range of objects. If not in range, report the incidence (and a convenient place to put a break point), or ignore the test, and return your default value for invalid object.

Jim Dempsey

 

www.quickthreadprogramming.com
Imagen de qolin

Thanks Jim.

Alas I am not in a position to check the things you suggest. The caller of FRED is not available to me and I cannot do anything intelligent before FRED is given the nasty address. Hence I need a way for FRED to avoid the problem for itself. The valid range of addresses it should work with are (of course) the limits of memory for the process at that moment, but I don't think I can relyably enquire these, and even if I did, can I depend on that range being entirely legal throughout? 

There are WIndow's API's that you can call with a memory address to test if the memory at that address (or a range of memory starting at that address) - see IsBadCodePtr, IsBadWritePtr, etc.

Imagen de qolin

Thanks Ian. This is exactly the sort of thing I was looking for...

...However the page at http://msdn.microsoft.com/en-us/library/windows/desktop/aa366716(v=vs.85).aspx contains some extremely persuasive advice that these function should not be used. Sigh...

Imagen de iliyapolak

isBadCodePtr is not recommended by Microsoft instead you can call GetLastError() function which should provide some info  about the error(access violation).AFAIK isBadCodePtr in debug build can be used to signal assertion and into debugger hopefully on access violation exception so you could inspect the memory address and reconstruct the call stack.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366712(v=vs.85).aspx

Quote:

qolin wrote:
However the page at http://msdn.microsoft.com/en-us/library/windows/desktop/aa366716(v=vs.85).aspx contains some extremely persuasive advice that these function should not be used. Sigh

Well, not really.  The discussion there is about the potential for race conditions associated with another thread in the process changing the attributes of the page being queried, in between the call to IsBad*Ptr and the page being accessed or whatever.  The perspective being taken is that the relevant code doing the testing absolutely must not crash (perhaps because it is system critical component and/or someone might actively exploit that race condition in a security critical program).

a) Are you operating in a multiple thread scenario?

b) Assuming you are, do you care if there is a relatively finite chance that the test fails?  At the moment, your program definitely crashes.  In future, it has a chance of crashing (unless someone is deliberately trying to bring your process down, in which case I think you are already stuffed).

The fundamental problem is that you've got a bad parameter being passed in.  In that context this is just a band aid.

The alternative, as discussed in the MSDN articles, is to implement structured exception handling.  I've never done that from Fortran code.  I'm not even sure how you would go about it.

 

Imagen de Steve Lionel (Intel)

Structured Exception Handling is not available from Fortran. There isn't a way to "turn off" access violations, but you can try to be defensive against it. If it is a zero pointer being passed in, that is pretty easy to check with the LOC() intrinsic. If it is some random value, then you can't reliably test for it.

Steve
Imagen de iliyapolak

Still if you are puzzled by the error you can insert in your code isBadCodePtr() function and compile your code as a debug build and set your default debugger to windbg.Thus on every occurrence on the access violation error you will be presented with detailed windbg analysis of that exception.

Imagen de jimdempseyatthecove

A rough guess for valid address:

a) It does not occupy an address within the first page of Virtual Memory (0:4K, 0:4M).
b) It is not an address in the O/S address space (e.g. above 2GB on Win32, or 3GB, or ??? on Windows x64)
c) Try to obtain the size of the process early, one of the qualifiers is if it resides within this space.
d) Early on, use some of the C heap functions to obtain the limits of the the heap.

Note, applications can extend and/or add on heaps later on. The debugging heap functions may be able to detect this.

This still will not protect from a junk point going into FRED that points within the acceptable addresses, and then FRED taking an erronious action based on what the pointer points to.

Jim Dempsey

www.quickthreadprogramming.com
Imagen de iliyapolak

>>>This still will not protect from a junk point going into FRED that points within the acceptable addresses, and then FRED taking an erronious action based on what the pointer points to.>>>

Very true.

Imagen de qolin

 

My thanks to everyone who contributed. I think I now have as much information as I am going to get to sort out this problem. 

Kind regards

Qolin

 

Imagen de iliyapolak

@qolin

​If you need an assistance with debugger setup or usage feel free to ask.

Inicie sesión para dejar un comentario.