Application Exception - Intermittent in C11 app

Hi
Having the occasional issue with Application Exceptions on an app created by C11.1.
Messages like these appear.
I cannot reproduce it but a couple of users have it occurring intermittently.
Any clues on how to intercept it?
image

Thanks
Paul

Iā€™d recommend shipping your application with the debug build of the clarion runtime (Clarion11\bin\debug\ClaRUN.dll) and building your application with Debug info >= min and ā€œAdd line Number informationā€ parameter on.


The next time your application throws an exception, it should have detailed info where your exception took place.

2 Likes

Install the Clarion debugger as the system debugger on the machines that are seeing the issue, you could then examine the memory (locateoffset) when this window appears and you might be able to workout what api call is happening without the source clw, in my experience its usually a pointer error, ie not got the right address(somevar) or *parameterprototype. You can drop the source code file in question onto the machine where this happens in case you have a few api calls within the procedure but then you are sharing the code which you might not want to do?

If you have debugview in your code and the machine has internet access you can run debugview from the internet \live.sysinternals.com\tools\Dbgview.exe and then see what the debugoutput string is.

Something to watch out for with some Windows apiā€™s is MS uses Long Pointers (memory addresses) which point/link to other Long Pointers (memory addresses). In the pic, the memory addresses which are highlighted in the red boxes are all LPā€™s to LPā€™s and I cant work out why MS have done it this way.

ConvertSidToStringSidA function (sddl.h) - Win32 apps | Microsoft Docs

[in] Sid

A pointer to the SID structure to be converted.

[out] StringSid

A pointer to a variable that receives a pointer to a null-terminated SID string. To free the returned buffer, call the LocalFree function.

This might also be useful if you want to explore the stack? This is supposedly how Clarion handles its stack, which may be relevant if you are not using Pascal or C as the passing convention, it depends on if this access violation is a windows api call failing and what you prototyped in the module(ā€˜someapiā€™).

TopSpeed / Clarion / JPI - x86 calling conventions - Wikipedia

Iā€™ve been debating whether to sell this as an addon, its a template which makes it easy to prototype parameters basically.

The red box is a bug in C11, its the drop down part which should be attached to the Data Type: Byte bit of the template window on the right.

Read this post

2 Likes

Thanks for the replies. Lots of good knowledge there. I will pass it on and see whether it gets us to point B.
Cheers
Paul :slight_smile:

I think the two most common sources for those in my experience are (a) trying to access an object that has not yet been instantiated in that context, or (b) failing to return a value from a procedure that is prototyped to return a string.

Iā€™d say that missing/incorrect project defines cause more hair loss than anything else.

(c) Accessing disposed data.
Always check IF NOT object &= NULL THEN and set object &= NULL after DISPOSE. n.b. this last one is already done for you, but i prefer to both in the same code that is responsible for object &= NEW

Neither of those 2 suggestions is necessary.

If you pass a null reference to DISPOSE(), it will ignore it.
When you pass a reference to DISPOSE(), the reference gets nulled.

 PROGRAM
 
StringRef &STRING

  MAP
  END
  
  CODE
   
   StringRef &= NEW STRING(20)
   DISPOSE(StringRef)
   MESSAGE(CHOOSE(StringRef &= NULL,'StringRef is now null','StringRef is NOT NULL'))
   DISPOSE(StringRef)
   MESSAGE('The world did not end, and ' & CHOOSE(StringRef &= NULL,'StringRef is still null after DISPOSE','StringRef is NOT NULL'))
2 Likes

Perhaps Ericā€™s statement was ambiguous and you read it not as intended?

I think it was intended to be read as two separate things:

  1. Always check IF NOT object &= NULL THEN

ie. check object before using it

  1. and set object &= NULL after DISPOSE

this is a good idea especially for things like strings where the dispose does not zero the size (and yes I know we have had this conversation lots of times before but it bears repeating)

   StringRef &= NEW STRING(20)
   DISPOSE(StringRef) 
   message('after dispose the size is ' & size(StringRef))    ! size still 20
   stringRef &= null
   message('after setting to null the size is ' & size(StringRef))  ! size now 0
2 Likes