#139 Recursive destructors call stack crashes

resolved
closed-out-of-date
nobody
htdig (103)
5
2002-12-23
2002-10-04
Anonymous
No

On Mac OS X, I was htdig'ing a web site that contains mail
archives for a couple of years for over a dozen mailing lists.

After running over an hour or two, it crashed with a segfault.

./rundig: line 36: 28321 Segmentation fault $BINDIR/htdig -a -u

running it in gdb shows why:

Program received signal EXC_BAD_ACCESS, Could not access
memory.
0x90004918 in free_list_remove_ptr ()
(gdb) bt
#0 0x90004918 in free_list_remove_ptr ()
#1 0x00072954 in operator delete(void*) () at HtRegex.cc:104
#2 0x00073654 in operator delete[](void*) () at HtRegex.cc:104
#3 0x0001c4d8 in DictionaryEntry::~DictionaryEntry() (this=
0x6301c0,
__in_chrg=6652832) at Dictionary.cc:26
#4 0x0001c508 in DictionaryEntry::~DictionaryEntry() (this=
0x6301c0,
__in_chrg=6652832) at Dictionary.cc:29
#5 0x0001c508 in DictionaryEntry::~DictionaryEntry() (this=
0x6aa4b0,
__in_chrg=

<snip>

#6523 0x0001c508 in DictionaryEntry::~DictionaryEntry() (this=
0xc8da10,
__in_chrg=6652832) at Dictionary.cc:29
#6524 0x0001c704 in Dictionary::~Dictionary() (this=0xbffff884,
__in_chrg=2) at Dictionary.cc:65
#6525 0x000078f0 in Retriever::~Retriever() (this=0xbffff880,
__in_chrg=2) at Retriever.cc:95
#6526 0x0000df1c in main (ac=5, av=0xbffffae0) at htdig.cc:377
#6527 0x00001c3c in _start (argc=5, argv=0xbffffae0, envp=
0xbffffaf8) at
/SourceCache/Csu/Csu-45/crt.c:267
#6528 0x00001abc in start ()
(gdb) Quit

6,500 deep call stack! That's kinda ugly. I love LISP and
recursion too, but ouch, I don't think any of the AI programs I've
written have recursed that deeply. Not everything *needs* to be
recursive. A linear loop can be just as fast (doing a bit more
accounting, but no call overhead, and uses *WAY* less memory)

[ej:~/htdig-3.1.6/htlib] ej% diff Dictionary.cc.orig Dictionary.cc
25a26,27
> DictionaryEntry *victim;
>
28,29c30,35
< if (next)
< delete next;
---
> while (next) {
> victim = next;
> next = victim->next;
> victim->next = NULL;
> delete victim;
> }

I noticed that the release() method is likewise recursive, and prolly
destructors for other linked objects. All could / should take this
change.

Granted, I might have been able to avoid the crash by doing a
`ulimit stacksize`, but I prefer the memory-bounded algorithm
anyways. By casual observation, it is faster.

Anyways, hope you consider taking this fix/change and applying it
to the other objects & methods in the source.

Thanks,
-ej
Eugenio Jarosiewicz
ej0@mac.com

Discussion

  • Lachlan Andrew

    Lachlan Andrew - 2002-12-23

    Logged In: YES
    user_id=663373

    Thanks Eugenio. The 3.2.0b4 snapshots have an iterative
    destructor similar to the one you propose, and have for some time.

     
  • Lachlan Andrew

    Lachlan Andrew - 2002-12-23
    • status: open --> closed-out-of-date
     

Log in to post a comment.