2

I'm having a hard time with this problem, but I've narrowed it down to using XML::LibXML after I've done a fork in Perl. I'm running Strawberry Perl 5.12.0 on Windows XP, and XML::LibXML 1.70.

I'm have a script where I need to run several processes concurrently, take the XML output and process the results. If I run this on a Solaris machine, it runs just fine and I have no issues. However, if I run this on Windows, I get a crash window stating that 'perl.exe has encountered a problem and needs to close.'

Here is a sample program that will generate the error:

use strict;
use warnings;
use XML::LibXML;
use Try::Tiny;

my $cmds = ['cmd1', 'cmd2'];
my @pids = ();
foreach my $cmd (@{$cmds}) {

    my $pid = fork();

    if ($pid) {

        # parent
        push (@pids, $pid);
    } elsif ($pid == 0) {

        XML::LibXML->load_xml(string=>'<root />'); # <-- this will crash it
        exit 0;
    }
}

foreach my $ch_pid (@pids) {

    try {

        waitpid($ch_pid, 0);
    } catch {

        carp("Error on waitpid: $!");
    };
}
exit 0;

If I only have one process, or if I don't fork, then it will work successfully. If I remove the load_xml call (and have nothing in the child), then it will work successfully.

Does anyone know what may be causing this and how to fix it?

Joel
  • 3,435
  • 2
  • 23
  • 33

1 Answers1

4

Special considerations need to be made when using XML::LibXML with threads. Some of these (particularly about initially loading the module) will also pertain to forks.

You can try removing the compile time load (the use XML::LibXML; line), and instead load in the module once you have forked:

} elsif ($pid == 0) {
    require XML::LibXML;
    XML::LibXML->load_xml(string=>'<root />');
    exit 0;
}
daxim
  • 39,270
  • 4
  • 65
  • 132
Eric Strom
  • 39,821
  • 2
  • 80
  • 152
  • 2
    When running on Windows, perl's `fork` is actually creating a new thread, so this is even more relevant. – hobbs Nov 03 '11 at 20:29
  • I just tried both of those suggestions, and I still get the same error message. – Joel Nov 03 '11 at 20:48
  • @Joel, since you're using threads anyway, why not avoid `fork` completely? – ikegami Nov 03 '11 at 20:54
  • @ikegami, How stable are threads in Perl, or are they OK to use in production code? I was under the impression that threads in Perl were kind of a hack and should be avoided. I do agree with you, for what I'm doing here threads would be a better solution. – Joel Nov 03 '11 at 21:03
  • 2
    @Joel, They're stable, and there's nothing hackish about them. `fork` is the hackish one as it's not something Windows can do. That's why it's emulated using threads. – ikegami Nov 03 '11 at 21:42
  • @ikegami, Thanks, that worked for me. If you put that up as an answer, I'll accept it. – Joel Nov 03 '11 at 22:22
  • @Joel, It's ok, give it to the other Eric. I was just helping you implement his solution :) – ikegami Nov 04 '11 at 08:18