in reply to Re: Problem enumerating a foreach loop using Win32::OLE->GetObject
in thread Problem enumerating a foreach loop using Win32::OLE->GetObject


Thanks for the info.

The hang is caused by the reading of the collection
$val = Win32::OLE::Enum->All($col) or $ok = 0;

Here is where the script locks/hangs.

I have tried to eval and alarm. Nothing is breaking
out if the commands hangs.
eval { local $SIG{ALRM} = sub { warn "ALARM FOR GET EXEC QUERY: \"$quer +y\" L: \"" . __LINE__ . "\" F: \"" . __FILE__ . "\"\n" }; # NB: \n re +quired alarm 5; $val = Win32::OLE::Enum->All($col) or $ok = 0; alarm 0; }; if($@) { $ret = $@; print "ERR: \"$ret\"\n"; $err = 1; $ret = "timeout while QUERY: \"$query\" wmi on + machine $host"; return($err, $ret); }


any suggestions on howto eval/jail this line, then
breakout/throw error in case the time/condition is met?

Only certain machines are causing the hang/lock. Most
of the machines breeze past within 5 seconds.

So iterating 5000 plus machines then hanging on a random
is a PITA.

TIA, Joe

Replies are listed 'Best First'.
Re^3: Problem enumerating a foreach loop using Win32::OLE->GetObject
by Discipulus (Canon) on Apr 12, 2018 at 19:42 UTC
    Hello again,

    you must try to isolate your problem. I admit that, for me, reading the expose of your question result to be a bit difficult. Also the code you show is not so perlish and lacks of use strict; use warnings; Anyway, wat I found is:

    > Only certain machines are causing the hang/lock.

    You have not to eval/jail (as you say) the function: you are outside perl domain. Infact you are dealing with something similar to a complex system call: microsoft stuff are well known to return (or not return) weird behaviours. You know if you are used to work with these things.

    If a remote call fails or hangs is not useful to wrap in eval and wait 300 seconds to have back a 255 error or something else, equally unuseful. Better try to whatch $^E that is last operating system error or even better check first if the machine is reachable. Programatically or manually check the Event Viewer in the remote machine to spot some (rare) useful entries.

    Other sparse hints: the problem maight be at RPC level (i'm in guess mode now..) try some command line version using wmic to confirm both versions hangs; wmi connection can be set to use a timeout, like in $os.options.Timeout=[timespan]::FromSeconds(30) or similar. There are here around WMI Diagnosis Utility and WMIdiag. Build a list of hanging machines and look at them carefully (what if remote service is stopped? ram cpu?)

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      Discipulus

      Thank you for the information


      What is your amazon wishlist? PM me and
      ill fulfill an item.


      As you pointed out, windows is a pain when
      returning errors. It appears the os will
      allow the process to hang without any
      reaper collection, which is a shame.

      FYI: I'm using activestate perl with very
      very little issue.

      How I solved the issue.

      I created a batch file that loops/start min
      each ip address which points to the perl script.
      If the perl script hangs, only the one instance
      to the ip will halt. Not the entire script.
      Since I insert a record into a mysql table
      instead of a flat file, double feed/line
      errors are not an issue.


      Below is the intel.bat load file
      @echo off for /f "tokens=1,2 delims=:" %%a in ('time /t') do set "variable1=%%a" + & set "variable2=%%b" for /f "tokens=1" %%a in ("%variable2%") do set "mn=%%a" set hr=%variable1% set time=%date:~10,4%-%date:~4,2%-%date:~7,2%-%hr%-%mn% title SINGLE AUP -s=2 - %time% - %username% - %1 start /min cmd /c "perl intel-bug.pl -s=3 -misc=1 -z=%1" SET count=0 FOR /f "tokens=*" %%G IN ('"tasklist | find /i "cmd.exe""') DO (ca +ll :s_do_sums "%%G") GOTO :next :s_do_sums set /a count+=1 goto :eof :next ping 127.0.0.1 -n 3 -w 1000 > NUL rem echo %count% if %count% GEQ 100 Timeout /t 30 if %count% GEQ 75 Timeout /t 20 if %count% GEQ 50 Timeout /t 10 :end



      Thanks again,

      Joe