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

I'm having some trouble getting the debugger to work with fork:
$ echo $TERM xterm $ perl -d test.pl Loading DB routines from perl5db.pl version 1.33 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(des.pl:3): our $DEBUG = 1; + + DB<1> c
At this point I get a bunch of xterm windows popping up with title "Daughter Perl debugger [pid=xxx->yyy]test.pl" and contents of the window saying: message "sh: 1: 3: Bad file descriptor". The original window is generally a mess complaining that it doesn't know how to create a new TTY -- which is obviously false as it created them (and indeed created exactly the right number of them corresponding to the forks). Any ideas?

Replies are listed 'Best First'.
Re: Spawned debugger xterms say "sh: 1: 3: Bad file descriptor" (source)
by tye (Sage) on Aug 11, 2013 at 22:47 UTC
    Any ideas?

    Read the source!

    =head3 C<xterm_get_fork_TTY> This function provides the C<get_fork_TTY> function for X windows. If +a program running under the debugger forks, a new <xterm> window is open +ed and the subsidiary debugger is directed there. The C<open()> call is of particular note here. We have the new C<xterm +> we're spawning route file number 3 to STDOUT, and then execute the C<t +ty> command (which prints the device name of the TTY we'll want to use for + input and output to STDOUT, then C<sleep> for a very long time, routing this + output to file number 3. This way we can simply read from the <XT> filehandle + (which is STDOUT from the I<commands> we ran) to get the TTY we want to use. Only works if C<xterm> is in your path and C<$ENV{DISPLAY}>, etc. are properly set up. =cut sub xterm_get_fork_TTY { ( my $name = $0 ) =~ s,^.*[/\\],,s; open XT, qq[3>&1 xterm -title "Daughter Perl debugger $pids $name" -e sh -c 'tt +y 1>&3;\ sleep 10000000' |]; # Get the output from 'tty' and clean it up a little. my $tty = <XT>; chomp $tty;

    The redirections look kosher to me. And it seems likely that they at least used to work. My first guess would be a bug in dash (there have been plenty of those) if your /bin/sh is a link to dash. My second guess is that your version of xterm is closing FD 3 before spawning the requested command.

    - tye        

      Indeed, sh is linked to dash:
      $ ls -al `which sh` lrwxrwxrwx 1 root root 4 Mar 1 2012 /bin/sh -> dash
      Actually, I don't need all these forked debuggers opening up since I'm not debugging the (trivial) forked processes. (UPDATE: I discovered that  DB<1> undef $DB::inhibit_exit allows me to do this.)

      I suppose I could go into the source and change it to use bash instead of dash (in the guise of sh) and see if that at least forks working debuggers.

Re: Spawned debugger xterms say "sh: 1: 3: Bad file descriptor"
by Loops (Curate) on Aug 11, 2013 at 18:03 UTC

    It appears that your error message is coming from the shell "sh:", not perl. Ar you using system() in test.pl? Is it calling a script that is missing the #! bang line? Probably you need to share test.pl for someone to be sure of the problem you're hitting.

      OK, here's a stripped down example that does the same thing (produces 3 child debugger windows with the same kind of titles and message that I described previously):
      $ ls -al eko -rwxr-xr-x 1 jabowery jabowery 30 Aug 11 13:38 eko $ cat eko #!/usr/bin/perl print shift; $ cat test.pl our $DEBUG = 1; for (1..3){ unless(open($fh{$_},"-|")){ print `./eko $_`; exit(0); } } for(keys %fh){ my $fh=$fh{$_}; my $s=join '',<$fh>; print STDERR "$_: $s\n" if $DEBUG; close $fh; } $ perl test.pl 1: 1 3: 3 2: 2 $ perl -d test.pl Loading DB routines from perl5db.pl version 1.33 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(test.pl:1): our $DEBUG = 1; + + DB<1> c Debugged program terminated. Use q to quit or R to restart, use o inhibit_exit to avoid stopping after program termination, h q, h R or h o to get additional info. Debugged program terminated. Use q to quit or R to restart, use o inhibit_exit to avoid stopping after program termination, h q, h R or h o to get additional info. Debugged program terminated. Use q to quit or R to restart, use o inhibit_exit to avoid stopping after program termination, h q, h R or h o to get additional info. ######### Forked, but do not know how to create a new TTY. ######### Since two debuggers fight for the same TTY, input is severely entang +led. I know how to switch the output to a different window in xterms, OS/ +2 consoles, and Mac OS X Terminal.app only. For a manual switch, put +the name of the created TTY in $DB::fork_TTY, or define a function DB::get_fork_TTY() returning this. On UNIX-like systems one can get the name of a TTY for the given win +dow by typing tty, and disconnect the shell from TTY by sleep 1000000. + + DB<1> ######### Forked, but do not know how to cr +eate a new TTY. ######### Since two debuggers fight for the same TTY, input is severely entang +led. I know how to switch the output to a different window in xterms, OS/ +2 consoles, and Mac OS X Terminal.app only. For a manual switch, put +the name of the created TTY in $DB::fork_TTY, or define a function DB::get_fork_TTY() returning this. On UNIX-like systems one can get the name of a TTY for the given win +dow by typing tty, and disconnect the shell from TTY by sleep 1000000. + + DB<1> ######### Forked, but do not know how to cr +eate a new TTY. ######### Since two debuggers fight for the same TTY, input is severely entang +led. I know how to switch the output to a different window in xterms, OS/ +2 consoles, and Mac OS X Terminal.app only. For a manual switch, put +the name of the created TTY in $DB::fork_TTY, or define a function DB::get_fork_TTY() returning this. On UNIX-like systems one can get the name of a TTY for the given win +dow by typing tty, and disconnect the shell from TTY by sleep 1000000. + + DB<1>