From d1cdf4d3a18b6d8860ea357c6db5f66b4971371f Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Fri, 31 May 2024 18:32:46 +0200 Subject: [PATCH] [EDF30062] : tolerance of crash at exit --- src/Container/SALOME_PyNode.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Container/SALOME_PyNode.py b/src/Container/SALOME_PyNode.py index 312c7bf5d..13e477f16 100644 --- a/src/Container/SALOME_PyNode.py +++ b/src/Container/SALOME_PyNode.py @@ -40,6 +40,8 @@ MY_CONTAINER_ENTRY_IN_GLBS = "my_container" MY_PERFORMANCE_LOG_ENTRY_IN_GLBS = "my_log_4_this_session" +MY_KEY_TO_DETECT_FINISH = "neib av tuot" + class Generic(SALOME__POA.GenericObj): """A Python implementation of the GenericObj CORBA IDL""" def __init__(self,poa): @@ -792,7 +794,7 @@ Looks like a hard crash as returnCode {returnCode} != 0 {banner} """ -def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, keepFilesToReplay ): +def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, keepFilesToReplay, closeEyesOnErrorAtExit = False): """ Equivalent of exec(code,context) but executed in a separate subprocess to avoid to make the current process crash. @@ -805,6 +807,7 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL containerRef (Engines.Container) : Container ref (retrieving the Files to created when keepFilesToReplay is set to False) instanceOfLogOfCurrentSession (LogOfCurrentExecutionSession) : instance of LogOfCurrentExecutionSession to build remotely the reference in order to log information keepFilesToReplay (bool) : if True when something goes wrong during execution all the files to replay post mortem case are kept. If False only error is reported but files to replay are destoyed. + closeEyesOnErrorAtExit (bool) : if True in case of crash of subprocess, if MY_KEY_TO_DETECT_FINISH is displayed at the end of stdout Return: ------- @@ -820,6 +823,14 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL import pickle import subprocess as sp import CORBA + # + def IsConsideredAsOKRun( returnCode, closeEyesOnErrorAtExit , stderr ): + if returnCode == 0: + return True + if not closeEyesOnErrorAtExit: + return False + return stderr[-len(MY_KEY_TO_DETECT_FINISH):] == MY_KEY_TO_DETECT_FINISH + # def InternalExecResistant( code, context, outargsname): orb = CORBA.ORB_init(['']) @@ -830,6 +841,10 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL return os.path.splitext( os.path.basename(fname)[len(EXEC_CODE_FNAME_PXF):] )[0] with tempfile.NamedTemporaryFile(dir=os.getcwd(),prefix=EXEC_CODE_FNAME_PXF,suffix=".py", mode="w", delete = False) as codeFd: codeFd.write( code ) + codeFd.write( """ +import sys +sys.stderr.write({!r}) +sys.stderr.flush()""".format( MY_KEY_TO_DETECT_FINISH ) ) codeFd.flush() codeFileName = os.path.basename( codeFd.name ) contextFileName = "contextsafe_{}.pckl".format( RetrieveUniquePartFromPfx( codeFileName ) ) @@ -849,14 +864,16 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL stderr = stderr.decode() sys.stdout.write( stdout ) ; sys.stdout.flush() sys.stderr.write( stderr ) ; sys.stderr.flush() - if returnCode == 0: + if IsConsideredAsOKRun( returnCode, closeEyesOnErrorAtExit , stderr ): pcklData = instanceOfLogOfCurrentSession._remote_handle.getObj() if len(pcklData) > 0: ret = pickle.loads( pcklData ) context.update( evParams.result ) evParams.destroyOnOK() + if returnCode != 0: + print( "WARNING : Following code has generated non zero return code ( {} ) but considered as OK\n{}".format( returnCode, code ) ) return ret - if returnCode != 0: + else: if keepFilesToReplay: evParams.destroyOnKO( containerRef ) else: @@ -864,10 +881,10 @@ def ExecCrashProofGeneric( code, context, outargsname, containerRef, instanceOfL raise RuntimeError(f"Subprocess launched {evParams.strDependingOnReturnCode(keepFilesToReplay,returnCode)}stdout :\n{stdout}\nstderr :\n{stderr}") def ExecCrashProofWithReplay( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession ): - return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, True) + return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, True, True) def ExecCrashProofWithoutReplay( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession ): - return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, False) + return ExecCrashProofGeneric(code, context, outargsname, containerRef, instanceOfLogOfCurrentSession, False, False) def ExecLocal( code, context, outargsname, containerRef, instanceOfLogOfCurrentSession ): exec( code, context ) -- 2.39.2