<s> from __future__ import absolute_import , division , print_function , unicode_literals <EOL> import argparse <EOL> import errno <EOL> import logging <EOL> import multiprocessing <EOL> import os <EOL> import resource <EOL> import signal <EOL> import subprocess <EOL> import sys <EOL> import threading <EOL> import time <EOL> import tempfile <EOL> sys . dont_write_bytecode = True <EOL> from benchexec import baseexecutor <EOL> from benchexec . baseexecutor import BaseExecutor <EOL> from benchexec . cgroups import * <EOL> from benchexec import oomhandler <EOL> from benchexec import systeminfo <EOL> from benchexec import util <EOL> _WALLTIME_LIMIT_DEFAULT_OVERHEAD = <NUM_LIT:30> <EOL> _ULIMIT_DEFAULT_OVERHEAD = <NUM_LIT:30> <EOL> _BYTE_FACTOR = <NUM_LIT:1000> <EOL> _LOG_SHRINK_MARKER = "<STR_LIT>" <EOL> _SUDO_ARGS = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> try : <EOL> from subprocess import DEVNULL <EOL> except ImportError : <EOL> DEVNULL = open ( os . devnull , '<STR_LIT:rb>' ) <EOL> def main ( argv = None ) : <EOL> """<STR_LIT>""" <EOL> if argv is None : <EOL> argv = sys . argv <EOL> parser = argparse . ArgumentParser ( <EOL> fromfile_prefix_chars = '<STR_LIT:@>' , <EOL> description = <EOL> """<STR_LIT>""" ) <EOL> resource_args = parser . add_argument_group ( "<STR_LIT>" ) <EOL> resource_args . add_argument ( "<STR_LIT>" , type = util . parse_memory_value , metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> resource_args . add_argument ( "<STR_LIT>" , type = util . parse_timespan_value , metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> resource_args . add_argument ( "<STR_LIT>" , type = util . parse_timespan_value , metavar = "<STR_LIT>" , <EOL> help = '<STR_LIT>' ) <EOL> resource_args . add_argument ( "<STR_LIT>" , type = util . parse_timespan_value , metavar = "<STR_LIT>" , <EOL> help = '<STR_LIT>' ) <EOL> resource_args . add_argument ( "<STR_LIT>" , type = util . parse_int_list , metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> resource_args . add_argument ( "<STR_LIT>" , type = util . parse_int_list , metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> io_args = parser . add_argument_group ( "<STR_LIT>" ) <EOL> io_args . add_argument ( "<STR_LIT>" , metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> io_args . add_argument ( "<STR_LIT>" , default = "<STR_LIT>" , metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> io_args . add_argument ( "<STR_LIT>" , type = util . parse_memory_value , metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> io_args . add_argument ( "<STR_LIT>" , action = "<STR_LIT>" , dest = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> environment_args = parser . add_argument_group ( "<STR_LIT>" ) <EOL> environment_args . add_argument ( "<STR_LIT>" , action = "<STR_LIT>" , default = [ ] , metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> environment_args . add_argument ( "<STR_LIT>" , action = "<STR_LIT>" , dest = "<STR_LIT>" , default = [ ] , <EOL> metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> environment_args . add_argument ( "<STR_LIT>" , metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> environment_args . add_argument ( "<STR_LIT>" , metavar = "<STR_LIT>" , <EOL> help = "<STR_LIT>" ) <EOL> baseexecutor . add_basic_executor_options ( parser ) <EOL> options = parser . parse_args ( argv [ <NUM_LIT:1> : ] ) <EOL> baseexecutor . handle_basic_executor_options ( options ) <EOL> env = { } <EOL> if len ( options . args ) == <NUM_LIT:1> and options . args [ <NUM_LIT:0> ] . startswith ( "<STR_LIT:{>" ) : <EOL> data = eval ( options . args [ <NUM_LIT:0> ] ) <EOL> options . args = data [ "<STR_LIT:args>" ] <EOL> env = data . get ( "<STR_LIT>" , { } ) <EOL> options . debug = data . get ( "<STR_LIT>" , options . debug ) <EOL> if "<STR_LIT>" in data : <EOL> try : <EOL> options . maxOutputSize = int ( data [ "<STR_LIT>" ] ) * _BYTE_FACTOR * _BYTE_FACTOR <EOL> except ValueError : <EOL> options . maxOutputSize = util . parse_memory_value ( data [ "<STR_LIT>" ] ) <EOL> if options . input == '<STR_LIT:->' : <EOL> stdin = sys . stdin <EOL> elif options . input is not None : <EOL> if options . input == options . output : <EOL> parser . error ( "<STR_LIT>" ) <EOL> try : <EOL> stdin = open ( options . input , '<STR_LIT>' ) <EOL> except IOError as e : <EOL> parser . error ( e ) <EOL> else : <EOL> stdin = None <EOL> cgroup_subsystems = set ( options . require_cgroup_subsystem ) <EOL> cgroup_values = { } <EOL> for arg in options . cgroup_values : <EOL> try : <EOL> key , value = arg . split ( "<STR_LIT:=>" , <NUM_LIT:1> ) <EOL> subsystem , option = key . split ( "<STR_LIT:.>" , <NUM_LIT:1> ) <EOL> if not subsystem or not option : <EOL> raise ValueError ( ) <EOL> except ValueError : <EOL> parser . error ( <EOL> '<STR_LIT>' <EOL> . format ( arg ) ) <EOL> cgroup_values [ ( subsystem , option ) ] = value <EOL> cgroup_subsystems . add ( subsystem ) <EOL> executor = RunExecutor ( user = options . user , cleanup_temp_dir = options . cleanup , <EOL> additional_cgroup_subsystems = list ( cgroup_subsystems ) ) <EOL> def signal_handler_kill ( signum , frame ) : <EOL> executor . stop ( ) <EOL> signal . signal ( signal . SIGTERM , signal_handler_kill ) <EOL> signal . signal ( signal . SIGINT , signal_handler_kill ) <EOL> formatted_args = "<STR_LIT:U+0020>" . join ( map ( util . escape_string_shell , options . args ) ) <EOL> logging . info ( '<STR_LIT>' , formatted_args ) <EOL> logging . info ( '<STR_LIT>' , options . output ) <EOL> try : <EOL> result = executor . execute_run ( <EOL> args = options . args , <EOL> output_filename = options . output , <EOL> stdin = stdin , <EOL> hardtimelimit = options . timelimit , <EOL> softtimelimit = options . softtimelimit , <EOL> walltimelimit = options . walltimelimit , <EOL> cores = options . cores , <EOL> memlimit = options . memlimit , <EOL> memory_nodes = options . memoryNodes , <EOL> cgroupValues = cgroup_values , <EOL> environments = env , <EOL> workingDir = options . dir , <EOL> maxLogfileSize = options . maxOutputSize ) <EOL> finally : <EOL> if stdin : <EOL> stdin . close ( ) <EOL> executor . check_for_new_files_in_home ( ) <EOL> exit_code = util . ProcessExitCode . from_raw ( result [ '<STR_LIT>' ] ) <EOL> def print_optional_result ( key ) : <EOL> if key in result : <EOL> print ( key + "<STR_LIT:=>" + str ( result [ key ] ) . replace ( "<STR_LIT>" , '<STR_LIT>' ) ) <EOL> print_optional_result ( '<STR_LIT>' ) <EOL> print ( "<STR_LIT>" + str ( exit_code . raw ) ) <EOL> if exit_code . value is not None : <EOL> print ( "<STR_LIT>" + str ( exit_code . value ) ) <EOL> if exit_code . signal is not None : <EOL> print ( "<STR_LIT>" + str ( exit_code . signal ) ) <EOL> print ( "<STR_LIT>" + str ( result [ '<STR_LIT>' ] ) + "<STR_LIT:s>" ) <EOL> print ( "<STR_LIT>" + str ( result [ '<STR_LIT>' ] ) + "<STR_LIT:s>" ) <EOL> for key in sorted ( result . keys ( ) ) : <EOL> if key . startswith ( '<STR_LIT>' ) : <EOL> print ( "<STR_LIT>" . format ( key , result [ key ] ) ) <EOL> print_optional_result ( '<STR_LIT>' ) <EOL> if '<STR_LIT>' in result : <EOL> for key , value in result [ '<STR_LIT>' ] . items ( ) : <EOL> print ( "<STR_LIT>" . format ( key , value ) ) <EOL> class RunExecutor ( BaseExecutor ) : <EOL> def __init__ ( self , user = None , cleanup_temp_dir = True , additional_cgroup_subsystems = [ ] , <EOL> * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> super ( RunExecutor , self ) . __init__ ( * args , ** kwargs ) <EOL> self . _termination_reason = None <EOL> self . _user = user <EOL> self . _should_cleanup_temp_dir = cleanup_temp_dir <EOL> self . _cgroup_subsystems = additional_cgroup_subsystems <EOL> if user is not None : <EOL> sudo_check = self . _build_cmdline ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:0>' ] ) <EOL> logging . debug ( '<STR_LIT>' , user ) <EOL> p = subprocess . Popen ( sudo_check , stdout = subprocess . PIPE , stderr = subprocess . PIPE ) <EOL> try : <EOL> if p . wait ( ) : <EOL> logging . error ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT:U+0020>' . join ( sudo_check ) , <EOL> p . returncode , <EOL> p . stdout . read ( ) . decode ( ) . strip ( ) , <EOL> p . stderr . read ( ) . decode ( ) . strip ( ) ) <EOL> sys . exit ( '<STR_LIT>' . format ( user ) ) <EOL> finally : <EOL> p . stdout . close ( ) <EOL> p . stderr . close ( ) <EOL> try : <EOL> self . _home_dir = _get_user_account_info ( user ) . pw_dir <EOL> except ( KeyError , ValueError ) as e : <EOL> sys . exit ( '<STR_LIT>' . format ( user , e ) ) <EOL> try : <EOL> self . _home_dir_content = set ( self . _listdir ( self . _home_dir ) ) <EOL> except ( subprocess . CalledProcessError , IOError ) : <EOL> self . _home_dir_content = [ ] <EOL> if self . _home_dir_content : <EOL> logging . warning ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> self . _home_dir , user ) <EOL> self . _init_cgroups ( ) <EOL> def _init_cgroups ( self ) : <EOL> """<STR_LIT>""" <EOL> self . cgroups = find_my_cgroups ( ) <EOL> for subsystem in self . _cgroup_subsystems : <EOL> self . cgroups . require_subsystem ( subsystem ) <EOL> if subsystem not in self . cgroups : <EOL> sys . exit ( '<STR_LIT>' . format ( subsystem ) ) <EOL> self . cgroups . require_subsystem ( CPUACCT ) <EOL> if CPUACCT not in self . cgroups : <EOL> logging . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> self . cgroups . require_subsystem ( FREEZER ) <EOL> if FREEZER not in self . cgroups : <EOL> if self . _user is not None : <EOL> sys . exit ( '<STR_LIT>' <EOL> + '<STR_LIT>' <EOL> + '<STR_LIT>' ) <EOL> else : <EOL> logging . warning ( '<STR_LIT>' ) <EOL> self . cgroups . require_subsystem ( MEMORY ) <EOL> if MEMORY not in self . cgroups : <EOL> logging . warning ( '<STR_LIT>' ) <EOL> else : <EOL> if systeminfo . has_swap ( ) and ( <EOL> not self . cgroups . has_value ( MEMORY , '<STR_LIT>' ) ) : <EOL> logging . warning ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> self . cgroups . require_subsystem ( CPUSET ) <EOL> self . cpus = None <EOL> self . memory_nodes = None <EOL> if CPUSET in self . cgroups : <EOL> try : <EOL> self . cpus = util . parse_int_list ( self . cgroups . get_value ( CPUSET , '<STR_LIT>' ) ) <EOL> except ValueError as e : <EOL> logging . warning ( "<STR_LIT>" , e . strerror ) <EOL> logging . debug ( "<STR_LIT>" , self . cpus ) <EOL> try : <EOL> self . memory_nodes = util . parse_int_list ( self . cgroups . get_value ( CPUSET , '<STR_LIT>' ) ) <EOL> except ValueError as e : <EOL> logging . warning ( "<STR_LIT>" , <EOL> e . strerror ) <EOL> logging . debug ( "<STR_LIT>" , self . memory_nodes ) <EOL> def _build_cmdline ( self , args , env = { } ) : <EOL> """<STR_LIT>""" <EOL> if self . _user is None : <EOL> return args <EOL> result = _SUDO_ARGS + [ self . _user ] <EOL> for var , value in env . items ( ) : <EOL> result . append ( var + '<STR_LIT:=>' + value ) <EOL> return result + [ '<STR_LIT>' ] + args <EOL> def _kill_process ( self , pid , cgroups = None , sig = signal . SIGKILL ) : <EOL> """<STR_LIT>""" <EOL> if self . _user is not None : <EOL> if not cgroups : <EOL> cgroups = find_cgroups_of_process ( pid ) <EOL> pids = cgroups . get_all_tasks ( FREEZER ) <EOL> try : <EOL> if pid == next ( pids ) : <EOL> pid = next ( pids ) <EOL> except StopIteration : <EOL> pass <EOL> finally : <EOL> pids . close ( ) <EOL> self . _kill_process0 ( pid , sig ) <EOL> def _kill_process0 ( self , pid , sig = signal . SIGKILL ) : <EOL> """<STR_LIT>""" <EOL> if self . _user is None : <EOL> super ( RunExecutor , self ) . _kill_process ( pid , sig ) <EOL> else : <EOL> logging . debug ( '<STR_LIT>' , sig , pid ) <EOL> try : <EOL> subprocess . check_call ( args = self . _build_cmdline ( [ '<STR_LIT>' , '<STR_LIT:->' + str ( int ( sig ) ) , str ( pid ) ] ) ) <EOL> except subprocess . CalledProcessError as e : <EOL> logging . debug ( e ) <EOL> def _listdir ( self , path ) : <EOL> """<STR_LIT>""" <EOL> if self . _user is None : <EOL> return os . listdir ( path ) <EOL> else : <EOL> args = self . _build_cmdline ( [ '<STR_LIT>' , '<STR_LIT>' , path ] ) <EOL> return subprocess . check_output ( args , stderr = DEVNULL ) . decode ( '<STR_LIT:utf-8>' , errors = '<STR_LIT:ignore>' ) . split ( '<STR_LIT:\n>' ) <EOL> def _set_termination_reason ( self , reason ) : <EOL> if not self . _termination_reason : <EOL> self . _termination_reason = reason <EOL> def _setup_cgroups ( self , my_cpus , memlimit , memory_nodes , cgroup_values ) : <EOL> """<STR_LIT>""" <EOL> logging . debug ( "<STR_LIT>" ) <EOL> subsystems = [ CPUACCT , FREEZER , MEMORY ] + self . _cgroup_subsystems <EOL> if my_cpus is not None : <EOL> subsystems . append ( CPUSET ) <EOL> subsystems = [ s for s in subsystems if s in self . cgroups ] <EOL> cgroups = self . cgroups . create_fresh_child_cgroup ( * subsystems ) <EOL> logging . debug ( "<STR_LIT>" , cgroups ) <EOL> for ( ( subsystem , option ) , value ) in cgroup_values . items ( ) : <EOL> try : <EOL> cgroups . set_value ( subsystem , option , value ) <EOL> except EnvironmentError as e : <EOL> cgroups . remove ( ) <EOL> sys . exit ( '<STR_LIT>' <EOL> . format ( e . strerror , subsystem , option , value , e . errno ) ) <EOL> logging . debug ( '<STR_LIT>' , <EOL> subsystem , option , value , cgroups . get_value ( subsystem , option ) ) <EOL> if my_cpus is not None : <EOL> my_cpus_str = '<STR_LIT:U+002C>' . join ( map ( str , my_cpus ) ) <EOL> cgroups . set_value ( CPUSET , '<STR_LIT>' , my_cpus_str ) <EOL> my_cpus_str = cgroups . get_value ( CPUSET , '<STR_LIT>' ) <EOL> logging . debug ( '<STR_LIT>' , my_cpus_str ) <EOL> if memory_nodes is not None : <EOL> cgroups . set_value ( CPUSET , '<STR_LIT>' , '<STR_LIT:U+002C>' . join ( map ( str , memory_nodes ) ) ) <EOL> memory_nodesStr = cgroups . get_value ( CPUSET , '<STR_LIT>' ) <EOL> logging . debug ( '<STR_LIT>' , memory_nodesStr ) <EOL> if memlimit is not None : <EOL> limit = '<STR_LIT>' <EOL> cgroups . set_value ( MEMORY , limit , memlimit ) <EOL> swap_limit = '<STR_LIT>' <EOL> if not cgroups . has_value ( MEMORY , swap_limit ) : <EOL> if systeminfo . has_swap ( ) : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> else : <EOL> try : <EOL> cgroups . set_value ( MEMORY , swap_limit , memlimit ) <EOL> except IOError as e : <EOL> if e . errno == errno . ENOTSUP : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> raise e <EOL> memlimit = cgroups . get_value ( MEMORY , limit ) <EOL> logging . debug ( '<STR_LIT>' , memlimit ) <EOL> if MEMORY in cgroups : <EOL> try : <EOL> cgroups . set_value ( MEMORY , '<STR_LIT>' , '<STR_LIT:0>' ) <EOL> except IOError as e : <EOL> logging . warning ( '<STR_LIT>' , e ) <EOL> return cgroups <EOL> def _setup_temp_dir ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _user is None : <EOL> base_dir = tempfile . mkdtemp ( prefix = "<STR_LIT>" ) <EOL> else : <EOL> create_temp_dir = self . _build_cmdline ( [ <EOL> '<STR_LIT>' , '<STR_LIT:-c>' , <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> ] ) <EOL> base_dir = subprocess . check_output ( create_temp_dir ) . decode ( ) . strip ( ) <EOL> temp_dir = os . path . join ( base_dir , "<STR_LIT>" ) <EOL> home_dir = os . path . join ( base_dir , "<STR_LIT>" ) <EOL> if self . _user is None : <EOL> os . mkdir ( temp_dir ) <EOL> os . mkdir ( home_dir ) <EOL> else : <EOL> subprocess . check_call ( self . _build_cmdline ( [ "<STR_LIT>" , "<STR_LIT>" , temp_dir , home_dir ] ) ) <EOL> logging . debug ( "<STR_LIT>" , base_dir ) <EOL> return base_dir , home_dir , temp_dir <EOL> def _cleanup_temp_dir ( self , base_dir ) : <EOL> """<STR_LIT>""" <EOL> if self . _should_cleanup_temp_dir : <EOL> logging . debug ( '<STR_LIT>' ) <EOL> if self . _user is None : <EOL> util . rmtree ( base_dir , onerror = util . log_rmtree_error ) <EOL> else : <EOL> rm = subprocess . Popen ( self . _build_cmdline ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , base_dir ] ) , <EOL> stderr = subprocess . PIPE ) <EOL> rm_output = rm . stderr . read ( ) . decode ( ) <EOL> rm . stderr . close ( ) <EOL> if rm . wait ( ) != <NUM_LIT:0> or rm_output : <EOL> logging . warning ( "<STR_LIT>" , <EOL> base_dir , rm_output ) <EOL> else : <EOL> logging . info ( "<STR_LIT>" , base_dir ) <EOL> def _setup_environment ( self , environments , home_dir , temp_dir ) : <EOL> """<STR_LIT>""" <EOL> if self . _user is not None or environments . get ( "<STR_LIT>" , None ) is not None : <EOL> run_environment = { } <EOL> else : <EOL> run_environment = os . environ . copy ( ) <EOL> run_environment [ "<STR_LIT>" ] = home_dir <EOL> run_environment [ "<STR_LIT>" ] = temp_dir <EOL> run_environment [ "<STR_LIT>" ] = temp_dir <EOL> run_environment [ "<STR_LIT>" ] = temp_dir <EOL> run_environment [ "<STR_LIT>" ] = temp_dir <EOL> for key , value in environments . get ( "<STR_LIT>" , { } ) . items ( ) : <EOL> if key in os . environ : <EOL> run_environment [ key ] = os . environ [ key ] <EOL> for key , value in environments . get ( "<STR_LIT>" , { } ) . items ( ) : <EOL> run_environment [ key ] = value <EOL> for key , value in environments . get ( "<STR_LIT>" , { } ) . items ( ) : <EOL> run_environment [ key ] = os . environ . get ( key , "<STR_LIT>" ) + value <EOL> for key in environments . get ( "<STR_LIT>" , { } ) . items ( ) : <EOL> run_environment . pop ( key , None ) <EOL> logging . debug ( "<STR_LIT>" , environments ) <EOL> return run_environment <EOL> def _setup_output_file ( self , output_filename , args ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> output_file = open ( output_filename , '<STR_LIT:w>' ) <EOL> except IOError as e : <EOL> sys . exit ( e ) <EOL> output_file . write ( '<STR_LIT:U+0020>' . join ( map ( util . escape_string_shell , self . _build_cmdline ( args ) ) ) <EOL> + '<STR_LIT>' + '<STR_LIT:->' * <NUM_LIT> + '<STR_LIT>' ) <EOL> output_file . flush ( ) <EOL> return output_file <EOL> def _setup_cgroup_time_limit ( self , hardtimelimit , softtimelimit , walltimelimit , <EOL> cgroups , cores , pid_to_kill ) : <EOL> """<STR_LIT>""" <EOL> cgroup_hardtimelimit = hardtimelimit if CPUACCT in cgroups else None <EOL> if any ( [ cgroup_hardtimelimit , softtimelimit , walltimelimit ] ) : <EOL> timelimitThread = _TimelimitThread ( cgroups = cgroups , <EOL> hardtimelimit = cgroup_hardtimelimit , <EOL> softtimelimit = softtimelimit , <EOL> walltimelimit = walltimelimit , <EOL> pid_to_kill = pid_to_kill , <EOL> cores = cores , <EOL> callbackFn = self . _set_termination_reason , <EOL> kill_process_fn = self . _kill_process ) <EOL> timelimitThread . start ( ) <EOL> return timelimitThread <EOL> return None <EOL> def _setup_cgroup_memory_limit ( self , memlimit , cgroups , pid_to_kill ) : <EOL> """<STR_LIT>""" <EOL> if memlimit is not None : <EOL> try : <EOL> oomThread = oomhandler . KillProcessOnOomThread ( <EOL> cgroups = cgroups , pid_to_kill = pid_to_kill , <EOL> callbackFn = self . _set_termination_reason , <EOL> kill_process_fn = self . _kill_process ) <EOL> oomThread . start ( ) <EOL> return oomThread <EOL> except OSError as e : <EOL> logging . critical ( "<STR_LIT>" , <EOL> e . errno , e . strerror ) <EOL> return None <EOL> def _setup_ulimit_time_limit ( self , hardtimelimit , cgroups ) : <EOL> """<STR_LIT>""" <EOL> if hardtimelimit is not None : <EOL> if CPUACCT in cgroups : <EOL> ulimit = hardtimelimit + _ULIMIT_DEFAULT_OVERHEAD <EOL> else : <EOL> ulimit = hardtimelimit <EOL> resource . setrlimit ( resource . RLIMIT_CPU , ( ulimit , ulimit ) ) <EOL> def execute_run ( self , args , output_filename , stdin = None , <EOL> hardtimelimit = None , softtimelimit = None , walltimelimit = None , <EOL> cores = None , memlimit = None , memory_nodes = None , <EOL> environments = { } , workingDir = None , maxLogfileSize = None , <EOL> cgroupValues = { } ) : <EOL> """<STR_LIT>""" <EOL> if stdin == subprocess . PIPE : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> elif stdin is None : <EOL> stdin = DEVNULL <EOL> if hardtimelimit is not None : <EOL> if hardtimelimit <= <NUM_LIT:0> : <EOL> sys . exit ( "<STR_LIT>" . format ( hardtimelimit ) ) <EOL> if softtimelimit is not None : <EOL> if softtimelimit <= <NUM_LIT:0> : <EOL> sys . exit ( "<STR_LIT>" . format ( softtimelimit ) ) <EOL> if hardtimelimit and ( softtimelimit > hardtimelimit ) : <EOL> sys . exit ( "<STR_LIT>" ) <EOL> if not CPUACCT in self . cgroups : <EOL> sys . exit ( "<STR_LIT>" ) <EOL> if walltimelimit is None : <EOL> if hardtimelimit is not None : <EOL> walltimelimit = hardtimelimit + _WALLTIME_LIMIT_DEFAULT_OVERHEAD <EOL> elif softtimelimit is not None : <EOL> walltimelimit = softtimelimit + _WALLTIME_LIMIT_DEFAULT_OVERHEAD <EOL> else : <EOL> if walltimelimit <= <NUM_LIT:0> : <EOL> sys . exit ( "<STR_LIT>" . format ( walltimelimit ) ) <EOL> if cores is not None : <EOL> if self . cpus is None : <EOL> sys . exit ( "<STR_LIT>" ) <EOL> if not cores : <EOL> sys . exit ( "<STR_LIT>" ) <EOL> if not set ( cores ) . issubset ( self . cpus ) : <EOL> sys . exit ( "<STR_LIT>" . format ( list ( set ( cores ) . difference ( self . cpus ) ) ) ) <EOL> if memlimit is not None : <EOL> if memlimit <= <NUM_LIT:0> : <EOL> sys . exit ( "<STR_LIT>" . format ( memlimit ) ) <EOL> if not MEMORY in self . cgroups : <EOL> sys . exit ( "<STR_LIT>" ) <EOL> if memory_nodes is not None : <EOL> if self . memory_nodes is None : <EOL> sys . exit ( "<STR_LIT>" ) <EOL> if len ( memory_nodes ) == <NUM_LIT:0> : <EOL> sys . exit ( "<STR_LIT>" ) <EOL> if not set ( memory_nodes ) . issubset ( self . memory_nodes ) : <EOL> sys . exit ( "<STR_LIT>" . format ( list ( set ( memory_nodes ) . difference ( self . memory_nodes ) ) ) ) <EOL> if workingDir : <EOL> if not os . path . exists ( workingDir ) : <EOL> sys . exit ( "<STR_LIT>" . format ( workingDir ) ) <EOL> if not os . path . isdir ( workingDir ) : <EOL> sys . exit ( "<STR_LIT>" . format ( workingDir ) ) <EOL> if not os . access ( workingDir , os . X_OK ) : <EOL> sys . exit ( "<STR_LIT>" . format ( workingDir ) ) <EOL> for ( ( subsystem , option ) , _ ) in cgroupValues . items ( ) : <EOL> if not subsystem in self . _cgroup_subsystems : <EOL> sys . exit ( '<STR_LIT>' <EOL> '<STR_LIT>' . format ( <EOL> option = option , subsystem = subsystem ) ) <EOL> if not self . cgroups . has_value ( subsystem , option ) : <EOL> sys . exit ( '<STR_LIT>' <EOL> . format ( option = option , subsystem = subsystem ) ) <EOL> try : <EOL> return self . _execute ( args , output_filename , stdin , <EOL> hardtimelimit , softtimelimit , walltimelimit , memlimit , <EOL> cores , memory_nodes , <EOL> cgroupValues , <EOL> environments , workingDir , maxLogfileSize ) <EOL> except OSError as e : <EOL> logging . critical ( "<STR_LIT>" , <EOL> e . errno , args [ <NUM_LIT:0> ] , workingDir or '<STR_LIT:.>' , e . strerror ) <EOL> return { '<STR_LIT>' : '<STR_LIT>' , '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , '<STR_LIT>' : <NUM_LIT:0> } <EOL> def _execute ( self , args , output_filename , stdin , <EOL> hardtimelimit , softtimelimit , walltimelimit , memlimit , <EOL> cores , memory_nodes , <EOL> cgroup_values , <EOL> environments , workingDir , max_output_size ) : <EOL> """<STR_LIT>""" <EOL> def preParent ( ) : <EOL> """<STR_LIT>""" <EOL> energy_before = util . measure_energy ( ) <EOL> walltime_before = util . read_monotonic_time ( ) <EOL> return ( walltime_before , energy_before ) <EOL> def postParent ( preParent_result ) : <EOL> """<STR_LIT>""" <EOL> walltime_before , energy_before = preParent_result <EOL> walltime = util . read_monotonic_time ( ) - walltime_before <EOL> energy = util . measure_energy ( energy_before ) <EOL> return ( walltime , energy ) <EOL> def preSubprocess ( ) : <EOL> """<STR_LIT>""" <EOL> os . setpgrp ( ) <EOL> os . nice ( <NUM_LIT:5> ) <EOL> self . _setup_ulimit_time_limit ( hardtimelimit , cgroups ) <EOL> cgroups = self . _setup_cgroups ( cores , memlimit , memory_nodes , cgroup_values ) <EOL> base_dir , home_dir , temp_dir = self . _setup_temp_dir ( ) <EOL> run_environment = self . _setup_environment ( environments , home_dir , temp_dir ) <EOL> outputFile = self . _setup_output_file ( output_filename , args ) <EOL> args = self . _build_cmdline ( args , env = run_environment ) <EOL> timelimitThread = None <EOL> oomThread = None <EOL> pid = None <EOL> returnvalue = <NUM_LIT:0> <EOL> ru_child = None <EOL> self . _termination_reason = None <EOL> throttle_check = systeminfo . CPUThrottleCheck ( cores ) <EOL> swap_check = systeminfo . SwapCheck ( ) <EOL> logging . debug ( '<STR_LIT>' ) <EOL> try : <EOL> pid , result_fn = self . _start_execution ( args = args , <EOL> stdin = stdin , stdout = outputFile , stderr = outputFile , <EOL> env = run_environment , cwd = workingDir , <EOL> cgroups = cgroups , <EOL> parent_setup_fn = preParent , child_setup_fn = preSubprocess , <EOL> parent_cleanup_fn = postParent ) <EOL> with self . SUB_PROCESS_PIDS_LOCK : <EOL> self . SUB_PROCESS_PIDS . add ( pid ) <EOL> timelimitThread = self . _setup_cgroup_time_limit ( <EOL> hardtimelimit , softtimelimit , walltimelimit , cgroups , cores , pid ) <EOL> oomThread = self . _setup_cgroup_memory_limit ( memlimit , cgroups , pid ) <EOL> returnvalue , ru_child , ( walltime , energy ) = result_fn ( ) <EOL> result = { } <EOL> result [ '<STR_LIT>' ] = walltime <EOL> if energy : <EOL> result [ '<STR_LIT>' ] = energy <EOL> self . _get_cgroup_measurements ( cgroups , ru_child , result ) <EOL> finally : <EOL> logging . debug ( '<STR_LIT>' , returnvalue ) <EOL> with self . SUB_PROCESS_PIDS_LOCK : <EOL> self . SUB_PROCESS_PIDS . discard ( pid ) <EOL> if timelimitThread : <EOL> timelimitThread . cancel ( ) <EOL> if oomThread : <EOL> oomThread . cancel ( ) <EOL> cgroups . kill_all_tasks ( self . _kill_process0 ) <EOL> outputFile . close ( ) <EOL> logging . debug ( "<STR_LIT>" ) <EOL> cgroups . remove ( ) <EOL> self . _cleanup_temp_dir ( base_dir ) <EOL> if throttle_check . has_throttled ( ) : <EOL> logging . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> if swap_check . has_swapped ( ) : <EOL> logging . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> _reduce_file_size_if_necessary ( output_filename , max_output_size ) <EOL> if returnvalue not in [ <NUM_LIT:0> , <NUM_LIT:1> ] : <EOL> _get_debug_output_after_crash ( output_filename ) <EOL> result [ '<STR_LIT>' ] = returnvalue <EOL> if self . _termination_reason : <EOL> result [ '<STR_LIT>' ] = self . _termination_reason <EOL> elif memlimit and '<STR_LIT>' in result and result [ '<STR_LIT>' ] >= memlimit : <EOL> result [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> return result <EOL> def _get_cgroup_measurements ( self , cgroups , ru_child , result ) : <EOL> """<STR_LIT>""" <EOL> logging . debug ( "<STR_LIT>" ) <EOL> cputime_wait = ru_child . ru_utime + ru_child . ru_stime if ru_child else <NUM_LIT:0> <EOL> cputime_cgroups = None <EOL> if CPUACCT in cgroups : <EOL> tmp = cgroups . read_cputime ( ) <EOL> tmp2 = None <EOL> while tmp != tmp2 : <EOL> time . sleep ( <NUM_LIT:0.1> ) <EOL> tmp2 = tmp <EOL> tmp = cgroups . read_cputime ( ) <EOL> cputime_cgroups = tmp <EOL> if cputime_wait > <NUM_LIT:0.5> and ( cputime_wait * <NUM_LIT> ) > cputime_cgroups : <EOL> logging . warning ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> cputime_wait , cputime_cgroups ) <EOL> result [ '<STR_LIT>' ] = cputime_wait <EOL> else : <EOL> result [ '<STR_LIT>' ] = cputime_cgroups <EOL> for ( core , coretime ) in enumerate ( cgroups . get_value ( CPUACCT , '<STR_LIT>' ) . split ( "<STR_LIT:U+0020>" ) ) : <EOL> try : <EOL> coretime = int ( coretime ) <EOL> if coretime != <NUM_LIT:0> : <EOL> result [ '<STR_LIT>' + str ( core ) ] = coretime / <NUM_LIT> <EOL> except ( OSError , ValueError ) as e : <EOL> logging . debug ( "<STR_LIT>" , core , e ) <EOL> if MEMORY in cgroups : <EOL> memUsageFile = '<STR_LIT>' <EOL> if not cgroups . has_value ( MEMORY , memUsageFile ) : <EOL> memUsageFile = '<STR_LIT>' <EOL> if not cgroups . has_value ( MEMORY , memUsageFile ) : <EOL> logging . warning ( '<STR_LIT>' ) <EOL> else : <EOL> try : <EOL> result [ '<STR_LIT>' ] = int ( cgroups . get_value ( MEMORY , memUsageFile ) ) <EOL> except IOError as e : <EOL> if e . errno == errno . ENOTSUP : <EOL> logging . critical ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> else : <EOL> raise e <EOL> logging . debug ( <EOL> '<STR_LIT>' , <EOL> result [ '<STR_LIT>' ] , cputime_wait , cputime_cgroups , result . get ( '<STR_LIT>' , None ) ) <EOL> def stop ( self ) : <EOL> self . _set_termination_reason ( '<STR_LIT>' ) <EOL> super ( RunExecutor , self ) . stop ( ) <EOL> def check_for_new_files_in_home ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . _user : <EOL> return None <EOL> try : <EOL> created_files = set ( self . _listdir ( self . _home_dir ) ) . difference ( self . _home_dir_content ) <EOL> except ( subprocess . CalledProcessError , IOError ) : <EOL> created_files = [ ] <EOL> if created_files : <EOL> logging . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> self . _home_dir , '<STR_LIT>' . join ( created_files ) ) <EOL> return created_files <EOL> def _get_user_account_info ( user ) : <EOL> """<STR_LIT>""" <EOL> import pwd <EOL> if user [ <NUM_LIT:0> ] == '<STR_LIT:#>' : <EOL> return pwd . getpwuid ( int ( user [ <NUM_LIT:1> : ] ) ) <EOL> else : <EOL> return pwd . getpwnam ( user ) <EOL> def _reduce_file_size_if_necessary ( fileName , maxSize ) : <EOL> """<STR_LIT>""" <EOL> fileSize = os . path . getsize ( fileName ) <EOL> if maxSize is None : <EOL> logging . debug ( "<STR_LIT>" , fileName , fileSize ) <EOL> return <EOL> if fileSize < ( maxSize + <NUM_LIT> ) : <EOL> logging . debug ( "<STR_LIT>" , fileName , fileSize ) <EOL> return <EOL> logging . warning ( "<STR_LIT>" , fileName , fileSize ) <EOL> util . shrink_text_file ( fileName , maxSize , _LOG_SHRINK_MARKER ) <EOL> def _get_debug_output_after_crash ( output_filename ) : <EOL> """<STR_LIT>""" <EOL> logging . debug ( "<STR_LIT>" ) <EOL> foundDumpFile = False <EOL> with open ( output_filename , '<STR_LIT>' ) as outputFile : <EOL> for line in outputFile : <EOL> if foundDumpFile : <EOL> try : <EOL> dumpFileName = line . strip ( '<STR_LIT>' ) <EOL> outputFile . seek ( <NUM_LIT:0> , os . SEEK_END ) <EOL> with open ( dumpFileName , '<STR_LIT:r>' ) as dumpFile : <EOL> util . copy_all_lines_from_to ( dumpFile , outputFile ) <EOL> os . remove ( dumpFileName ) <EOL> except IOError as e : <EOL> logging . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' , <EOL> dumpFile , e . strerror ) <EOL> break <EOL> try : <EOL> if util . decode_to_string ( line ) . startswith ( '<STR_LIT>' ) : <EOL> logging . debug ( '<STR_LIT>' ) <EOL> foundDumpFile = True <EOL> except UnicodeDecodeError : <EOL> pass <EOL> class _TimelimitThread ( threading . Thread ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , cgroups , kill_process_fn , hardtimelimit , softtimelimit , walltimelimit , pid_to_kill , cores , <EOL> callbackFn = lambda reason : None ) : <EOL> super ( _TimelimitThread , self ) . __init__ ( ) <EOL> if hardtimelimit or softtimelimit : <EOL> assert CPUACCT in cgroups <EOL> assert walltimelimit is not None <EOL> if cores : <EOL> self . cpuCount = len ( cores ) <EOL> else : <EOL> try : <EOL> self . cpuCount = multiprocessing . cpu_count ( ) <EOL> except NotImplementedError : <EOL> self . cpuCount = <NUM_LIT:1> <EOL> self . daemon = True <EOL> self . cgroups = cgroups <EOL> self . timelimit = hardtimelimit or ( <NUM_LIT> * <NUM_LIT> * <NUM_LIT> * <NUM_LIT> * <NUM_LIT:100> ) <EOL> self . softtimelimit = softtimelimit or ( <NUM_LIT> * <NUM_LIT> * <NUM_LIT> * <NUM_LIT> * <NUM_LIT:100> ) <EOL> self . latestKillTime = util . read_monotonic_time ( ) + walltimelimit <EOL> self . pid_to_kill = pid_to_kill <EOL> self . callback = callbackFn <EOL> self . kill_process = kill_process_fn <EOL> self . finished = threading . Event ( ) <EOL> def read_cputime ( self ) : <EOL> while True : <EOL> try : <EOL> return self . cgroups . read_cputime ( ) <EOL> except ValueError : <EOL> time . sleep ( <NUM_LIT:1> ) <EOL> def run ( self ) : <EOL> while not self . finished . is_set ( ) : <EOL> usedCpuTime = self . read_cputime ( ) if CPUACCT in self . cgroups else <NUM_LIT:0> <EOL> remainingCpuTime = self . timelimit - usedCpuTime <EOL> remainingSoftCpuTime = self . softtimelimit - usedCpuTime <EOL> remainingWallTime = self . latestKillTime - util . read_monotonic_time ( ) <EOL> logging . debug ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> self . pid_to_kill , usedCpuTime , remainingCpuTime , <EOL> remainingSoftCpuTime , remainingWallTime ) <EOL> if remainingCpuTime <= <NUM_LIT:0> : <EOL> self . callback ( '<STR_LIT>' ) <EOL> logging . debug ( '<STR_LIT>' , self . pid_to_kill ) <EOL> self . kill_process ( self . pid_to_kill , self . cgroups ) <EOL> self . finished . set ( ) <EOL> return <EOL> if remainingWallTime <= <NUM_LIT:0> : <EOL> self . callback ( '<STR_LIT>' ) <EOL> logging . warning ( '<STR_LIT>' , self . pid_to_kill ) <EOL> self . kill_process ( self . pid_to_kill , self . cgroups ) <EOL> self . finished . set ( ) <EOL> return <EOL> if remainingSoftCpuTime <= <NUM_LIT:0> : <EOL> self . callback ( '<STR_LIT>' ) <EOL> self . kill_process ( self . pid_to_kill , self . cgroups , signal . SIGTERM ) <EOL> self . softtimelimit = self . timelimit <EOL> remainingTime = min ( remainingCpuTime / self . cpuCount , <EOL> remainingSoftCpuTime / self . cpuCount , <EOL> remainingWallTime ) <EOL> self . finished . wait ( remainingTime + <NUM_LIT:1> ) <EOL> def cancel ( self ) : <EOL> self . finished . set ( ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> main ( ) </s>
