Handling System Error: Memory Violation

Posted by MABeatty1978 on 10-Jul-2014 12:44

Is there a way to catch a memory violation and prevent it from killing Progress?

I've got a Progress function that calls a C++ API.  The function sends a request message and the API returns a reply message in a mqmptr..  Problem is the size of the reply message can vary from 0 byes, to 100MB.  

What I was hoping to do was to set the memptr size to a reasonable size that would catch MOST of the messages, in the ball park of 20000b.  Then, if the memptr doesn't have enough memory to hold the reply, bump the memptr size up and try again.  Unfortunately, it just seems that Progress dies on a Memory Violation.  I've been tying to get it in a CATCH, which it does catch, but I can't figure out how to handle the error as Progress dies regardless of the CATCH.

Thank you. 

All Replies

Posted by Garry Hall on 10-Jul-2014 13:30

The AVM does not currently allow you to  catch access violations/segfaults.  The AVM doesn’t handle access violations other than to dump diagnostics (protrace) and exit. For most of the AVM, we try to address the underlying causes of access violations, with the intent that users should never be able to cause a crash using pure ABL. Once you enter DLL-land, the AVM doesn’t protect you from yourself. Protecting this has been mentioned in the past, but is not yet implemented. There are challenges to it: for example, within a DLL, there is no way to prevent the DLL from modifying any writable address in the address space. So your DLL could (inadvertently) write to an address that won’t cause a problem whilst in the DLL, but could cause a crash much later.
 
Is it possible to use an alternative API that will return an error code and required size if the target memptr is not long enough?
 
[collapse]
From: MABeatty1978 [mailto:bounce-MABeatty1978@community.progress.com]
Sent: Thursday, July 10, 2014 1:45 PM
To: TU.OE.Development@community.progress.com
Subject: [Technical Users - OE Development] Handling System Error: Memory Violation
 
Thread created by MABeatty1978

Is there a way to catch a memory violation and prevent it from killing Progress?

I've got a Progress function that calls a C++ API.  The function sends a request message and the API returns a reply message in a mqmptr..  Problem is the size of the reply message can vary from 0 byes, to 100MB.  

What I was hoping to do was to set the memptr size to a reasonable size that would catch MOST of the messages, in the ball park of 20000b.  Then, if the memptr doesn't have enough memory to hold the reply, bump the memptr size up and try again.  Unfortunately, it just seems that Progress dies on a Memory Violation.  I've been tying to get it in a CATCH, which it does catch, but I can't figure out how to handle the error as Progress dies regardless of the CATCH.

Thank you. 

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Frank Meulblok on 11-Jul-2014 04:43

- Does the API provide a way to get the size of the reply ? (most APIs do as it's considered good practice)

- And do you need to allocate the memory for the reply, or does the API library allocate that itself ?

If you need to allocate the memory:

- Call the API to return the expected size

- SET-SIZE a memptr to that size

- Call the API to get the actual reply

- SET-SIZE the memptr to 0 after you're done with it to deallocate the memory used.

If the C++ library allocates the memory:

- Call the API to get the reply

- Call the API to return the expected size (some APIs will return the size and the data in different parameters of the same call)

- SET-SIZE the memptr to the size of the message -> as per documentation " If a MEMPTR variable is returned from a DLL or UNIX shared library routine that also allocates a memory region to it, then the SET-SIZE statement initializes the size of the existing region. The AVM does not allocate a new region. This allows the AVM to perform bounds checking on references to MEMPTR regions allocated outside ABL."

- When you're done with the reply, DO NOT SET-SIZE it back to 0. Instead, there should be an API call to have the library de-allocate it, or it should take care of things behind the scenes.

(If you do de-allocate the memptr while the C++ library still expects it to be allocated, bad things will happen)

Posted by gus on 11-Jul-2014 09:18

another commonly used approach is to pass the buffer size to the called function and then before copying data back, it checks the size. the read() system call for example, takes a file descriptor, buffer address and buffer size. it reads at most the number of bytes that will fit and returns the actual number of bytes transferred.

as for the handling memory violation, when that occurs, it is nearly always too late. the damage has been done and some data has been smashed. continuing from the point of interruption will most likely cause the memory violation to recur. so the 4gl runtime cannot suppress or ignore memory violations.

your only choice is to check the buffer size before it is too late.

This thread is closed