Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

When I call a sub from my main script, everything runs fine until I come to the last line of the sub which is just
"return 0;" (0 for no error, else error code would have been returned before).

Why the hell do I get a "Dr. Watson" or Crash of perl.exe when executing this statement? I don't know, what happens internally, when returning from a sub, but I can't understand why such a thing can cause this error. In all other skripts, modules, subs and so on I never saw this before.

Can the (huge) amount of memory used in the sub be a reason for the crash?

I have another sub bound with my $write_address_sub = sub {....}; is this sub, which will be called a lot. A possible reason?

Thanks for any help, I really can't understand, what's going on. :-(
System: Win NT 4.0 Server, SP6

Replies are listed 'Best First'.
Re: Dr. Watson when
by jbert (Priest) on Jan 09, 2002 at 16:48 UTC

    Any Dr. Watson (or coredump/segfault on a Unix box) in perl is a bug in the perl interpreter or in any loaded DLLs/XS modules. You should not be able to write a script which would cause this.

    Having said that, no software is bug free and one of the best ways of getting it to fail is to use too much memory.

    Hmm...I attempted to do a quick example of how perl handles memory exhaustion gracefully and ended up causing a segfault on perl 5.6.0 (un-upgraded install on Red Hat 7.2) with the following:

    sub big { $line = shift; $size = length $line; print "Size is [$size]\n"; $line = $line x $size; big( $line ); } big( "12" );
    Running with a 3-char string to start causes different behaviour (big allocations, box slows down with memory use, perl finally prints "Out of memory!" and exits cleanly), which is more what I expected.

    I really should go and grab a more recent perl and if this is fixed and/or big into the allocator and see why it doesn't like big powers of two. But I'm sure someone here will happily beat me to it :-)

      I'll add a little to this. One can abuse unpack to cause a core dump, but that is probably not what is happening here.

      The easiest way to get a "Dr. Watson" w/ Perl is to use fork (under Win32). So, if you are doing that, you might want to look at (tye)Re: How to multiprocess in Win32?.

      The original seeker mentioned using lots of memory. Under Win32, if you run out of swap space, a dialogue pops up telling you that you are running low on memory. Once that happens, somewhere a call to malloc() (etc.) has failed. Many things don't check for failure of malloc() and many things that do check don't deal well with the failure anyway. So once you see that dialogue, just about any program, and indeed the operating system itself, is suspect and may fail in unusual ways.

      Even if we assume that Perl is perfect at remaining sane in the face of a failed malloc(), the Win32 libraries that Perl uses certainly aren't perfect in that respect and so Perl could certainly "Dr. Watson" after the "low memory" dialogue appeared.

      But if you haven't seen the "low memory" dialogue, then Perl using lots of memory should not be a reason for a "Dr. Watson".

              - tye (but my friends call me "Tye")
Re: Dr. Watson when
by Trimbach (Curate) on Jan 09, 2002 at 16:23 UTC
    The Perl code you're citing is completely legal under normal circumstances, and shouldn't be the source of a crash. I say "normal circumstances" because, like you said, if you do something wacky like an infinite loop or something your program can blow up at any line of code... it might not even compile. You said it uses a "huge" amount of memory, well, that's probably it. Try re-writing your code so it doesn't use so much memory (for example, iterate over each line in a file one at a time rather than trying to suck the whole file into memory at once.)

    You might also check your Perl version and make sure that's up-to-date.

    Gary Blackburn
    Trained Killer

Re: Dr. Watson when
by milk (Initiate) on Jan 15, 2002 at 19:55 UTC
    Thanks for all the help I got!
    I tried all the suggestions and rearranged the source. Nothing seems to help, but I was able to reduce the problem to one line

         undef (%addresses);

    When this line is called, I meet Dr. Watson. :-(
    Is this a known error (which a haven't found) or are there any other possibilities to get rid off the variable?
      A found a solution, but it is quite strange.

      If I put a  sleep 10; before and after the  undef, it works!
      Are there known any timing problems of perl?