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

Hello

I am using Win32::Exe to extract version info from windows executables. This module parses binary without using of WinAPI so it can be used on Linux too. Some files (packed) cannot be processed, and I use eval() to skip them. Today I discovered one windows system file (shell32.dll) which put the PC in the infinite loop — the are no errors, no warnings — the eval() cannot help here. The only solution I found is using $SIG{ALRM} to escape by timeout:

#!/usr/bin/perl use strict; use warnings; use Win32::Exe; $SIG{ALRM} = sub {die "timeout"}; eval{ alarm(1); Win32::Exe->new($ARGV[0]); alarm(0); }; if($@){ if($@ =~/timeout/){die "timeout detected"}; }else{ print "ok, can parse $ARGV[0]\n"; };
I test it on Linux and Windows, old and new module version. Before I post the bug I would try to find out the problem.

Here the binary (shell32.dll from Windows XP SP1 German):

http://rapidshare.com/files/139266982/shell32.dll_cannot_get_version_info.html

Some ideas?
  • Comment on method "new" leads to infinite loop with 100% CPU, troubleshooting??
  • Download Code

Replies are listed 'Best First'.
Re: method "new" leads to infinite loop with 100% CPU, troubleshooting??
by BrowserUk (Patriarch) on Aug 22, 2008 at 17:59 UTC

    Actually, are you sure that it doesn't eventually complete? I did a directory listing of the DLLs on my system and I noticed that at 8 MB shell32.dll is significantly bigger than any other dll. A quick check with dumpbin shows that it contains over 51000 fixups (relocations).

    So, I ran the following and left it running while I did something else, and it eventually completed after nearly 5 minutes:

    c:\test>perl -MWin32::Exe -le"print time; $e = Win32::Exe->new( 'c:\windows\system32\shell32.dll +' ); print time" 1219426998 1219427274

    The module uses Parse::Binary::FixedFormat and that module is just really, really slow.


    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.
      +++BrowserUk+++

      thank you for pointing to this!
      Yes, now I see, it takes minutes(!) to extract the couple of strings from a big binary file like this shell32.dll. Unbelievable!
      Can you point to an another way to get File Version Information from EXE without using WinAPI?

      I think about brute force by finding the text strings in binary.

        found this here on perlmonks:
        http://www.perlmonks.org/?node_id=287010 Win32 Fileversion info from .exe/.dll-files (16/32-bit) - takes only 0.03 second to process shell32.dll file.

        Great site and great members!

        Thanks
Re: method "new" leads to infinite loop with 100% CPU, troubleshooting??
by Tanktalus (Canon) on Aug 22, 2008 at 15:09 UTC

    Run it in the debugger. After it has hung, hit ctrl-c. The debugger should allow you to interact with it, so check the backtrace. You may be able to get an idea of why this is happening (though maybe not how to fix it).

    Good luck.

Re: method "new" leads to infinite loop with 100% CPU, troubleshooting??
by BrowserUk (Patriarch) on Aug 22, 2008 at 15:34 UTC

    I get the same problem on English XP. The module seems to get stuck in a loop, but tracing it through it is a distinctly non-trivial loop. Try running this to see what I mean:

    perl -d:Trace -MWin32::Exe -wle"$e = Win32::Exe->new( 'c:\windows\system32\shell32.dll' );"

    There seem to be several hundred lines of processing before the loop repeats. The only way I can see that happening is if the module contains a set of cyclic offsets. For example, mayne one of the offsets followed, is being treated as a signed 16-bit value instead of an unsigned 16-bit, resulting in a negative offset that causes a cyclic loop. Speculation, but it fits the emperical evidence.


    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.