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.
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.
Flag this post as spam/abuse.
- 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)
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.