#1 2014-06-24 21:58:25

avista
Member
Registered: 2014-01-06
Posts: 63

AV in SynCommons Exception Code

We are having a strange problem when raising an exception in an Interface Based Method call. 

Unfortunately, we have not been able to reproduce this in a sample application.  The error occurs consistently when the code is called from the IDE and we are also using the latest mORMot build. 

When the service method is called, a standard exception is generated:

function TServiceApi.AccountLookup(const Account: string; out aAccountData: TAccountData): Boolean;
begin
   raise Exception.Create(‘Test Exception’);
end;

Which causes the following AV in SynCommons.pas:

http://www.tiikoni.com/tis/view/?id=10fa80a

and the corresponding stack trace:

http://www.tiikoni.com/tis/view/?id=04ce3be

Notes:

  • TAccountData is a packed record with simple types

  • It only happens when the app is run inside the IDE

  • We are using Delphi XE2 Update 4 Hotfix 1

  • We've run FastMM4 in full debug mode with memory overwrite checking, and then with interface checking and it hasn't reported any problems

We suspect it’s an edge case that the SynCommons.LogExcept() routine isn’t handling or is due to some memory corruption with record based parameters, as we’ve eliminated calls to our custom code, but of course we can't prove this.

At this point, we’re at the end of our rope and can’t figure out what the problem is, so we need some guidance. 

Do you have any ideas about why this may be occurring or how to find the problem?  We could provide TeamViewer access to the machine if necessary.

Thanks in advance.

Offline

#2 2014-06-24 22:48:01

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: AV in SynCommons Exception Code

Those exceptions are catch so can be ignored.

It will never harm in production.

Offline

#3 2014-06-24 23:17:25

avista
Member
Registered: 2014-01-06
Posts: 63

Re: AV in SynCommons Exception Code

To confirm, I'm not talking about the standard exception that's raised, I'm talking about the AV that happens after it. 

This happens in one developer's IDE, but not in mine (with the same OS version, Delphi version, project options, etc.).  It makes testing impossible, because the AV keeps happening repeatedly until the application is terminated.

Offline

#4 2014-06-25 07:34:58

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: AV in SynCommons Exception Code

Yes, the AV occurs within the stack trace discovery loop.
The IsBadReadPtr() API should prevent those AV, but sounds like if it is somewhat broken.

In fact, there are several ways to get the stack trace.
Everything is already clearly stated in the documentation, I guess.

See TSynLogFamily.StackTraceUse property:

  /// how stack trace shall be computed
  TSynLogStackTraceUse = (stManualAndAPI,stOnlyAPI,stOnlyManual);
...
    /// how the stack trace shall use only the Windows API
    // - the class will use low-level RtlCaptureStackBackTrace() API to retrieve
    // the call stack: in some cases, it is not able to retrieve it, therefore
    // a manual walk of the stack can be processed - since this manual call can
    // trigger some unexpected access violations or return wrong positions,
    // you can disable this optional manual walk by setting it to stOnlyAPI
    // - default is stManualAndAPI, i.e. use RtlCaptureStackBackTrace() API and
    // perform a manual stack walk if the API returned no address (or <3)
    property StackTraceUse: TSynLogStackTraceUse read fStackTraceUse write fStackTraceUse;

You could set

TSynLog.Family.StackTraceUse := stOnlyAPI;

to force using the RtlCaptureStackBackTrace() API in debug mode, which should prevent of having such unexpected AV in the IDE.

Offline

#5 2014-06-25 15:50:53

avista
Member
Registered: 2014-01-06
Posts: 63

Re: AV in SynCommons Exception Code

Thanks for clearing that up, it is a big relief.

Everything is already clearly stated in the documentation, I guess.

Perhaps you didn't mean it this way, but that statement suggests to me that if I had only RTFM, it would have been obvious what the problem was.

I think for most developers, encountering an AV isn't something that inspires them to say to themselves "Gee, I just encountered an AV.  Perhaps this is supposed to happen and maybe there's an option to turn it off in the documentation." wink

The process goes more like this:

- "Uh oh, I encountered an AV!  Obviously it must be something I did wrong!"
- Find the code where the AV is occurring and try to understand what it's doing.
- See that the bug is occurring in the framework your using, but still think it's your fault.
- Spend a bunch of time debugging the problem trying to find the bug.

So in this case, I think it's reasonable to assume that scouring the documentation for an AV is not something one would be expected to do. smile

Might I respectfully suggest that since it's possible for that code to create unexpected AVs, that the default be set to

TSynLog.Family.StackTraceUse := stOnlyAPI;

One of my colleagues had this to say:

We can try that, but it concerns me that there is ever an A/V.  For me it erodes my confidence in the stability of the framework.

I'm sure you can see how this option sounds experimental, and code that is expected to "sometimes cause AVs" doesn't sound particularly stable.

I chose this framework after having invested a lot of time reading the forums and the documentation.  I also sincerely appreciate your responsiveness and the help you've provided to date.  The fact that it has so many unit tests also added confidence to my decision.  However, convincing others on my team that this was the route to go after this issue became more difficult.

Last edited by avista (2014-06-26 03:13:29)

Offline

#6 2014-06-25 20:23:18

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,272
Website

Re: AV in SynCommons Exception Code

avista wrote:

Might I respecfully suggest that since it's possible for that code to create unexpected AVs, that the default be set to

TSynLog.Family.StackTraceUse := stOnlyAPI;

But, from experiment on production, we found out that:
- stOnlyAPI sometimes delivers less accurate and complete stack trace;
- RtlCaptureStackBackTrace() is not available in all Windows versions (<XP);
- stManualAndAPI was found to be very stable and efficient, for worldwide customers.

We understand your concern.
Such AV could be very annoying during debugging, even if they have no impact.

TSynLogFamily.StackTraceUse is now set to stOnlyAPI within the Delphi IDE.
See http://synopse.info/fossil/info/15968dbd9c1a872f8

Thanks for the feedback!
smile

Offline

Board footer

Powered by FluxBB