Sign in to follow this  
Followers 0
rbhkamal

How to tell if the process crashed

6 posts in this topic

#1 ·  Posted (edited)

I'm facing this dilemma and have no idea how to workaround this problem.

I wrote a script (a long one) a year ago which controls VirtualBox and sold it off to few customers... the problem now is the new version of VirtualBox crashes.

To be specific, the script launches vboxmanage.exe which works fine most of the time but , with the new version of VBOX, crashes in certain cases. If the same command is run again, it works.

So... how do I tell if vboxmanage.exe finished executing properly or crashed?

Below is the function which is used to call vboxmanage.exe, its pretty much a wrapper around the run() method.

THANKS :mellow:

; #FUNCTION# ====================================================================================================================
; Name...........: __VboxMng_exec
; Description ...: Executes vboxmanage.exe and waits for the process to quit. It also retrieves stdout and stderr
; Syntax.........: __VboxMng_exec ($p_sParams
;                                   , ByRef $P_stdOut
;                                   , ByRef $p_stdErr
;                                   , [$p_iWindowFlag = @SW_HIDE] )
;
; Parameters ....: $p_sParams   - The parameters to be passed to vboxmanage.exe
;   $P_stdOut - [OUT] Will contain a string that has the output of stdOut
;   $p_stdErr - [OUT] Will contain a string that has the output of stdErr
;            $p_iWindowFlag - Visible window flag [@SW_HIDE , @SW_MINIMIZE , @SW_MAXIMIZE ]
;
; Return values .: Success  - 0
;   Failure     - < 0
;
; Author ........: Ribhi Kamal
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func __VboxMng_exec($p_sParams, ByRef $P_stdOut, ByRef $p_stdErr, $p_iWindowFlag = @SW_HIDE, $p_bUpdateCache = True)
    __event_start("__VboxMng_exec")
    Local $l_iRc = 0, $l_iErrBit = 0;
    
    If Not $__bVboxMng_Initilized Then
        __event_msg( 8 , "VBoxManage not initialized yet!" )
        $l_iRc = BitOR( $l_iRc , 2 ^ $l_iErrBit , $__iVboxMng_NEGATIVE_ERROR )
    EndIf
    
    $l_iErrBit += 1
    
    If $l_iRc == 0 Then
        If $p_bUpdateCache Then
            $__sVboxMng_Cache_STDOUT = ""
            $__sVboxMng_Cache_STDERR = ""
            $__sVboxMng_Cache_CMD = $__sVboxMng_exe & $__sVboxMng_Params & " " & $p_sParams
        EndIf
    EndIf
    

    $P_stdOut = ""
    $p_stdErr = ""

    Local $l_sPid
    If $l_iRc == 0 Then
        __event_msg( 2 , $__sVboxMng_exe & $__sVboxMng_Params & " " & $p_sParams )
        $l_sPid = Run($__sVboxMng_exe & $__sVboxMng_Params & " " & $p_sParams, '', $p_iWindowFlag, $STDERR_CHILD + $STDOUT_CHILD)
        If @error Then
            __event_msg( 8 , "Failed to run Vboxmanage.exe with error: " & @error )
            $l_iRc = BitOR( $l_iRc , 2 ^ $l_iErrBit , $__iVboxMng_NEGATIVE_ERROR )
        EndIf
    EndIf
    
    $l_iErrBit += 1
    
    If $l_iRc == 0 Then
        While 1
            Sleep(10)
            $P_stdOut = $P_stdOut & StdoutRead($l_sPid)
            If @error Then ExitLoop
        WEnd
        
        While 1
            Sleep(10)
            $p_stdErr = $p_stdErr & StderrRead($l_sPid)
            If @error Then ExitLoop
        WEnd
        
        StdioClose($l_sPid) ;Just incase, make sure that all IO is closed
        
        If $p_bUpdateCache Then
            $__sVboxMng_Cache_STDOUT = $P_stdOut
            $__sVboxMng_Cache_STDERR = $p_stdErr
        EndIf
    EndIf
    
    __event_end($l_iRc)
    Return $l_iRc
EndFunc ;==>__VboxMng_exec
Edited by rbhkamal

"When the power of love overcomes the love of power, the world will know peace"-Jimi Hendrix

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I don't know but it looks like I found a solution... I need someone to verify this for me please.

I simply need to get the return code, if its negative then something wrong happened

; Return handle of given PID
Func _ProcessGetHandle($iPID)
    Local Const $PROCESS_QUERY_INFORMATION = 0x0400
    Local $avRET = DllCall("kernel32.dll", "ptr", "OpenProcess", "int", $PROCESS_QUERY_INFORMATION, "int", 0, "int", $iPID)
    If @error Then
    Return SetError(1, 0, 0)
    Else
    Return $avRET[0]
    EndIf
EndFunc ;==>_ProcessGetHandle

; Close process handle
Func _ProcessCloseHandle($hProc)
    Local $avRET = DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc)
    If @error Then
    Return SetError(1, 0, 0)
    Else
    Return 1
    EndIf
EndFunc ;==>_ProcessCloseHandle

; Get process exit code from handle
Func _ProcessGetExitCode($hProc)
    Local $t_ExitCode = DllStructCreate("int")
    Local $avRET = DllCall("kernel32.dll", "int", "GetExitCodeProcess", "ptr", $hProc, "ptr", DllStructGetPtr($t_ExitCode))
    If @error Then
    Return SetError(1, 0, 0)
    Else
    Return DllStructGetData($t_ExitCode, 1)
    EndIf
EndFunc ;==>_ProcessGetExitCode

[EDIT]: Thanks to PsaltyDS for sharing his code

Edited by rbhkamal

"When the power of love overcomes the love of power, the world will know peace"-Jimi Hendrix

Share this post


Link to post
Share on other sites

With an avatar like yours, you were sure to attract attention of Penguins!


This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

Yes yes.... I wasn't sure why a Penguin exist on this non-Penguiny forum until you mentioned coolness


"When the power of love overcomes the love of power, the world will know peace"-Jimi Hendrix

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I don't know but it looks like I found a solution... I need someone to verify this for me please.

I simply need to get the return code, if its negative then something wrong happened

I'd be very interested whether 'GetExitCodeProcess' actually returns an exit code for a crashed process - my guess is no, and it would return 0 because the exit code variable wasn't written to.

More than likely it won't set an exit code for a crashed process, and will return with a failure as the API return value (which isn't checked in PsaltyDS's function). It would be wiser to add a check to see if $avRET[0]=0, which means the API call failed. When that happens, you should check 'GetLastError', which will probably give you a system error code if the process you were trying to get the Exit code from terminated (ERROR_PROCESS_ABORTED could be returned, for example - but there are a few other possibilities).

*edit: I tested a few ways of forcefully crashing an application (using 'Advanced Process Termination'), and sometimes I got a 0 return, sometimes I get a weird value like 3221225477, but in neither case did I get a failure on the API call. Interesting. But seeing as how these were forced crashes, I don't know what an actual crash situation would return for the application you're interested in.

Edited by Ascend4nt

Share this post


Link to post
Share on other sites

I see... maybe the best way is to modify the source for VboxManage.exe (OSE) and force it to print on exit "Exiting with <error code>." That way If I don't see that message in the output, the command will have to run again.

Thanks for the help


"When the power of love overcomes the love of power, the world will know peace"-Jimi Hendrix

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0