Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi - tools/technics for tracking propagated access violation

Even if it sounds strange, I believe that everybody encountered this kind of issue when working on big applications with lots of custom components. An AV is generated somewhere but the application is continuing with the execution and the error is raised some when later. I'm not talking about multi thread application. Just about generic single thread application.

I'm struggling to find an error which is raised randomly and even I'm using MadExcept/AQT, debugging dcus and breakpoints, but I can not find exact the steps when it is raised, and from where it gets raised. Error is propagating, and it is raising on an TWinControl destroy(the Delphi standard TPageControl) sometimes, other times when opening an dataset(which is opened and close several times before with the same SQL). So the stack gets corrupted and I can not use it in this case.

I know the question is too localized, but I'm asking you what other alternatives exists to track such kind of errors.

like image 887
RBA Avatar asked Jun 18 '13 08:06

RBA


2 Answers

I'd start with using some other memory managers to see if you can force the usage pattern of your application into breaking sooner.

FastMM can be run with FullDebugMode (be sure to put the according DLL with your application EXE). A few important things it can do:

  • fill memory with patterns (like Arioch 'The suggested)
  • check for modifications to blocks after they have been freed
  • log memory leaks upon application termination
  • callback upon certain events so you can log stuff

In the past I've written 2 blog posts about FastMM, I know I should write more about it and other memory managers.

  • Delphi – FastMM: Using FastMM4 for debugging your memory allocations – part 1: Introduction
  • Delphi – Using FastMM4 part 2: TDataModule descendants exposing interfaces, or the introduction of a TInterfacedDataModule

Edit: Nice article about other memory managers Memory Manager Investigations by SO user Eric Grange.

For documentation purposes some other memory managers (most of them don't apply to your case, but I have not yet found a post including them all):

In multi-threaded environments, these can be nice:

  • ScaleMM
  • SynScaleMM (based on ScaleMM)
  • TBBMM
  • TopMM
  • Upcoming multithreaded MM

In a EXE/DLL setup, you might want to try FastShareMem.

In his ScaleMM repository, André Mussche did test quite a few other memory managers.

NB: +1; good question, and I should find some time to write a follow up blog post on Delphi memory managers(:

like image 140
Jeroen Wiert Pluimers Avatar answered Nov 01 '22 23:11

Jeroen Wiert Pluimers


Logging to files can change the results, so I recommend the GExperts debugger which writes messages to an output window in real-time. Write a wrapper function so that you can dump to a file if you want, control what gets logged (loglevel filters), etc..

Put logging in the Initialization/Finalization of all units. I've found that "out of the blue" errors often happen during finalization. ex: you close a database connection, but that object has already been freed by something else. D'oh!

Also put logging in event handlers of any components, as well as the destructors of those components. This will show you if you're getting events firing after the components have been destroyed.

As a last resort, you may have to "gut" the program, removing all code that you wrote, in "chunks". Save the code somewhere, delete event handlers on form1, compile and test. If the error goes away, put back the event handlers and delete half of them, re-test. Continue until you narrow it down sufficiently, and the culprit should be identified by process of elimination.

like image 3
Chris Thornton Avatar answered Nov 01 '22 22:11

Chris Thornton