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

In the following code taken from exetype.pl,

# read IMAGE_DOS_HEADER structure read EXE, $record, 64; ($magic,$offset) = unpack "Sx58L", $record; #print "$offset\n"; die "$ARGV[0] is not an MSDOS executable file.\n" unless $magic == 0x5a4d; # "MZ" # read signature, IMAGE_FILE_HEADER and first WORD of IMAGE_OPTIONAL_H +EADER seek EXE, $offset, 0; read EXE, $record, 4+20+2; ($signature,$size,$magic) = unpack "Lx16Sx2S", $record; ### Line +39
if you run it with the print "$offset\n" commented out, (against the wperl.exe from the 5.12.0 build), then you get this error:
perl-5.12.0\win32>..\miniperl.exe -I..\lib \perl64\bin\exetype.pl ..\w +perl.exe 'x' outside of string in unpack at \perl64\bin\exetype.pl line 39.

which comes down to that the read on line 38 has failed to read enough (26) chars. Probably, because the preceding seek has gone to the wrong place.

But, if you uncomment the print "$offset\n"; line to work out where the seek is going, you get this error:

perl-5.12.0\win32>..\miniperl.exe -I..\lib \perl64\bin\exetype.pl ..\w +perl.exe 240 Use of uninitialized value $subsys in hash element at \perl64\bin\exet +ype.pl line 52. Use of uninitialized value $subsys in concatenation (.) or string at \ +perl64\bin\exetype.pl line 52. ..\wperl.exe uses the UNKNOWN() subsystem.

which means that the seek & read have now succeeded. Just because you printed the value of $offset.

Thoughts? A bug in miniperl.exe?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
RIP an inspiration; A true Folk's Guy

Replies are listed 'Best First'.
Re: Here's strange for you!
by almut (Canon) on Apr 13, 2010 at 17:10 UTC
    ...seek & read have now succeeded. Just because you printed the value of $offset.

    Do you get the same effect when you avoid implicit stringification (and the associated caching of the PV value — do a Devel::Peek dump before and after the print) by writing

    print $offset, "\n";

    instead of

    print "$offset\n";

    Don't really know why this would influence seek's behaviour, but for the moment that's the only normal side effect of your print that I can think of...

      The problem is, not too many tools are available at that point during the build.

      What I've determined so far is:

      • The problem only occurs when running exetype.pl with miniperl.exe.
      • Quoting the variables $offset & $size that contain unpacked numeric values entirely fixes the problem:
        # <perl>/win32/bin/exetype.pl ... 37: seek EXE, "$offset", 0; ... 43:die "Optional header is neither in NT32 nor in NT64 format" 44: unless ("$size" == 224 && $magic == 0x10b) || # ... 45: ("$size" == 240 && $magic == 0x20b); # ...

        Nmake test is still running, but is sufficiently far through that I don;t expect (extra) failures now.

      • Using 0+$offset & 0+$size doesn't effect a cure.

      My speculation is that unpack in miniperl is setting SvIOK when it shouldn't be.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        The problem is, not too many tools are available at that point during the build

        Do you have gdb? You could set a breakpoint on pp_seek and call sv_dump on the sv.

        My speculation is that unpack in miniperl is setting SvIOK when it shouldn't be.

        But IOK should be set for unpack L. Maybe it's some bad combo of IOK and pIOK.