Fun with Cryptic Errors!

The Perl program:

#! /usr/bin/perl

use IO::Socket::INET;
my $client = IO::Socket::INET->new(PeerAddr => 'www.google.com',
                                   PeerPort => 80,
                                   Proto    => 'TCP',
                                   Type     => SOCK_STREAM)
        or die "Couldn't connect: $!";
close $client;
print "Success\n";

The output:

Couldn't connect: No such file or directory at ./program line 5.

What’s the problem?

Here’s a hint: The program was run on a minimal, bare-bones Debian system.

Give up?

The problem is the Proto => 'TCP' parameter in the constructor. Internally, the IO::Socket::INET module uses getprotobyname() to look up the code associated with the string ‘TCP’. getprotobyname() does the lookup by finding the corresponding line in the file /etc/protocols. That file is contained in the netbase Debian package, which is not part of a minimal, bare-bones installation (like the one you get in a pbuilder environment).

Of course, it wouldn’t have taken me half an hour to figure this out if only the error message had specified which file could not be found. The fact that the script runs fine on any sane Debian system doesn’t help matters.

2 Responses

  1. This sounds like a job for strace.

    Also, I was expecting the problem to be the space after the hashbang.

  2. I suppose wading through strace might’ve turned it up a bit faster, but I would’ve needed to install it on the system first. I only figured out what was going on when I took out the Proto parameter to see what would happen, and the warnings about giving undefined values to getprotobyname revealed what was going on.

    If the problem had been in the hashbang line, it wouldn’t have gotten as far as starting Perl. Whitespace between the #! and the interpreter is optional. I also vaguely remember hearing that at one time BSD checked if the first four bytes of a file were “#! /” to determine if it’s a script.

Comments are closed.