1

I have a deadline. I am googling, I am code reading, I neeed help ...

My Application is throwing an EStackOverFlow. It requires an overnight test to hit the error, so I need some good ideas or it will take a long time to track down.

I tried last night with MAD Except, but that didn't catch it, presumably because there was no stack for it to do so. I was running from the IDE so I broke execution and looked at the Call Stack, but it was filled with MAD except details (I have contacted the author, but there is a big time difference between us).

There are no (deliberately) recursive recursive routines. No OnChange handlers (which might accidentaly change the component which they monitor, thus calling themselves recursively). No large data structures (which might be passed on the stack as parameters).

My first thought is to turn off MAD Except, but I can't wait another 12 or 16 hours for a crash.

Unattended, the program is doing some database access when timers expire every 30 seconds or every hour, so I have set those to 1 second, hoping to hasten the crash. Hmm, can I reduce the stack size in order to hasten the crash? If so, how?

What else can I do? I have wrapped my applications main file, where forms are created and the application is run, in Try ... Except.

Is there some point, such as the message handling loop, where I can check the stack size and see if it is growing "too large"? (if so, can you give details?)

Any other suggestion? Thanks in advance

(p.s the code is far too large to post)

Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551
  • 1
    You can set maximum stack size in linker options (or $MAXSTACKSIZE) (for executables). – Sertac Akyuz Sep 20 '12 at 02:43
  • +1 I have set it to the minimum allowed. For XE2 this is 65536. I hope that the problem will occur sooner now. – Mawg says reinstate Monica Sep 20 '12 at 03:08
  • 1
    look at "array of type" fields in classes and search for "While" and "repeat" loops, that's where I found most issues in the past... –  Sep 20 '12 at 04:02
  • 1
    The JCLDebug Unit(from the JCL) allows you to get the stack. You could use that to check the stack size. – awmross Sep 20 '12 at 04:23
  • 1
    That is weird - but i'd tried some Profiler. Suspecting infinite recursion i'd expect top used procedures to be those participating in that dance macabre – Arioch 'The Sep 20 '12 at 05:45
  • @awmross To try never hurts, but i'd not expect it. All stack tracers are more or less the same. Jedi CodeLib, mORMot logger, Eureka, madExcept.... more or less the same. If one of those was killed by SO, then probably all the rest would too. – Arioch 'The Sep 20 '12 at 05:46

2 Answers2

1

AS. Profiler approach i noted above might give you result by sheer luck (if there is some stray branch leading you to rare but instant-fast leak. Say, among 100 case variants there is the only one leading to infinite recursion). However if there is steady cumulative leak, that takes all night to accumulate itself, then profiler results would not be distinguishable from normal work.

I thought a bit. Current hypothesis is that stack tracers fail for there is no stack left. Let's hold it. Then we shall throw exception before stack is over, yes ? So i'd try this sequence:

1) i'd set stack tracer to log full stack trace including line numbers. It can be done in JCL tracers used by Delphi IDE, and i think madExcept can too.

2) i'd like to know the current stack size. For example Determining Stack Space with Visual Studio

3) i'd keep regularly checking used stack space. For example What is a safe Maximum Stack Size or How to measure use of stack?

Note: since we hardly know which thread has caused this - if i had few threads, i'd try to use all of those. I just don't know how would application react if some auxiliary thread fail with SO, can it be intercepted and logged or the whole app would be blown up just for one thread

4) ~ every 5 minutes i'd log current stack usage - just to see the pattern, if it is steadily slowly goring, or is it some rare but severe codepath. If several thread - then several log files one per thread It would also allow to estimate the "normal" stack usage.

5) if stack usage raises above 80% (i think your "normal" usage todl above would not exceed it, won't it?) i'd raise manual exception, some special class that would not be caught until thread/application top level, and at top level maybe even do something complex, like halting the app into debugger and awaking you so you can remotely connect and check the internal status of sick yet not deceased yet app.

Community
  • 1
  • 1
Arioch 'The
  • 15,799
  • 35
  • 62
1

The most the common stackoverflow problem is function calling itself, try to avoid it, or at least limit it.

You say you use a timer, are you calling Application.ProcessMessages inside your timer event? if you have a lots messages in queue, incase if its another WM_TIMER, this could cause stackoverflow.

Darkerstar
  • 924
  • 1
  • 8
  • 17