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

Most worthy Monks-

When using Win32::OLE in XP SP2 and ActiveState perl (5.8.8), forking always results in a null pointer exception on the death of the child thread. Example:
use strict; use warnings; use Win32::OLE; Win32::OLE->Option(Warn => 3); my $pid = fork; if($pid == ){ sleep 5; exit; } warn "Waiting on $pid"; waitpid($pid, 0);


This will throw an error of the type:
The instruction at "0xsomeaddr" referenced memory at "0x00000000". The memory could not be "written".

Does anyone know of a workaround for this problem? It's thrown a real wrench in my port of our VB reporting application.

Replies are listed 'Best First'.
Re: Win32::OLE and fork causes null pointer exception
by erroneousBollock (Curate) on Nov 15, 2007 at 15:12 UTC
    fork() on Win32 is emulated using threads.

    threads.pm clones all non-shared variables into new threads.

    When they go out of scope, their destructors are called as usual. That can cause bad things to happen for resources like filehandles and Win32 resource handles.

    Does anyone know of a workaround for this problem?
    Don't use fork() on Win32 under any circumstances. Use threads directly.

    -David

      Ok, so with Threads the same problem exists:

      use strict; use warnings; use Thread; use Win32::OLE; Win32::OLE->Option(Warn => 3); my $thread = Thread->new(\&TEST_THREAD, ("arg1", "agr2")); my $rc = $thread->eval; print $rc; print "\nI'm ending now.\n"; sub TEST_THREAD{ my ($arg1, $arg2) = (@_); return "$arg1\t$arg2"; }


      Using threads does throw a more informative error to STDERR though, in addition to the null pointer exception:
      Free to wr0ng pool lbaXXXX not XXXXXX during global destruction.
      where XXXX and XXXXXX are both hex values.

      So it looks like you were right about it being a problem with the global destructor...Is there no way to use Win32::OLE with a multi-threaded script?

      I tried moving the use statement for Win32::OLE into TEST_THREAD without any success. If I comment out the use statement for Win32::OLE, the script runs without error.
        Try require rather than use, either:
        • in the new Thread, or
        • in the main thread below the call to threads->new.

        If it doesn't work at all (once we've tried all the standard work-arounds), I'd say you could call it a bug in Win32::OLE.

        -David