def attach(args): def _find_dead_pids_host(host, pids): dead_pids = [] _establish_default_terminal() _ensure_scheduler_exists('jobs') for pid in pids: if not default_terminal.is_pid_alive(pid): host_path = '.'.join(hops.list_hops()) if host: host_path += '.' + host dead_pids.append('{host}:{pid}'.format(host=host_path or 'localhost', pid=pid)) return dead_pids def _find_dead_pids(pid_dict): # Check the status of all provided PIDs dead_pids = [] for host, pids in pid_dict.iteriterms(): # Establish a connection per each process dead_pids.extend(_find_dead_pids_host(host, pids)) return dead_pids def _parse_group_pids(expr): pid_dict = {} for app_instance in re.finditer('((?:(\w+):)?(\d+))', expr): host = app_instance.group(2) pid = int(app_instance.group(3)) if pid_dict.has_key(host): pid_dict[host] += [pid] else: pid_dict[host] = [pid] args_string = ' '.join(args) # Verify command syntax if len(args) < 1 or not re.match('(?:(?:\w+:)?\d+|\s)+', args_string): raise errors.BadArgsError( 'attach', 'attach [<host>:]<pid>[ [<host>:]<pid> [...]]') # Group by host pid_dict = _parse_group_pids(args_string) # Check the status of all provided PIDs dead_pids = _find_dead_pids(pid_dict) # Stop if all processes are alive if len(dead_pids) != 0: raise errors.CommandFailedError( 'attach', 'Invalid PIDs provided: {0}'.format(' ,'.join(dead_pids))) # Launch GDB and attach to PIDs session_manager, msgs = _attach_pids(pid_dict) # Initialize the debugging session return debug_session.init_debugging_mode(session_manager, msgs)
def end_sessions(args): # Verify command syntax if len(args) != 0: raise errors.BadArgsError( 'ls', 'This command does not accept arguments' ) _kill_all() return modes.offline, None
def _ensure_valid_sessions_selected(cmd): '''Verifies if all selected sessions are still alive''' non_existing_sessions = [ id for id in selected_sessions if not session_manager.exists(id) ] if non_existing_sessions: raise errors.BadArgsError( cmd, 'Cannot proceed. Dead session(s): {0}.'. format(', '.format(non_existing_sessions)) )
def quit(args): '''Exit scimitar''' # Verify command syntax if len(args) != 0: raise errors.BadArgsError( 'ls', 'This command does not accept arguments' ) _kill_all() return modes.quit, None
def list_jobs(args): # Verify command syntax if args: raise errors.BadArgsError('jobs', 'This command does not accept arguments.') _establish_default_terminal() _ensure_scheduler_exists('jobs') items = csssi.ls_user_jobs(default_terminal) jobs_str = '\t'.join(items) return modes.offline, jobs_str
def list_sessions(args): '''Lists all active sessions.''' # Verify command syntax if len(args) != 0: raise errors.BadArgsError( 'ls', 'This command does not accept arguments' ) pretty_session_list = _ls_out() if not pretty_session_list: return modes.debugging, 'ls: Empty. No sessions are alive.' return modes.debugging, 'Sessions:\n' + pretty_session_list
def message_history(args): '''Prints the selected sessions' history records at index args[0]''' _ensure_sessions_selected('history') index = -1 if len(args) == 1: try: index = -int(args[0]) except ValueError: raise errors.BadArgsError( 'history', 'history[ <index>]' ) if index > history_length: raise errors.BadArgsError( 'history', 'Selected record does not exist in the history' ) results = [] for tag in selected_sessions: # Output header results.append('~~~ Scimitar - Session: {} ~~~'.format(tag)) try: ind_rec, cout, tout, lout = sessions_history[tag][index] if ind_rec: # Check the type of indicator if ind_rec[0] == mi.indicator_error: results.append(format_error(ind_rec[1])) elif ind_rec[0] == mi.indicator_exit: session_manager.remove(tag) sessions_history.remove(tag) results.append(format_error('Session {} died.', tag)) else: results.append(cout) else: results.append(''.join([cout, tout, lout])) except IndexError: results.append(format_error('Scimitar: Record does not exist')) return modes.debugging, '\n'.join(results)
def select_session(args): '''Mark the provided sessions as selected''' # Verify command syntax if not args: raise errors.BadArgsError( 'select', 'select all | none | <session id>[ <session id>[ ...]]' ) if args: if args[0] == 'all': global selected_sessions selected_sessions = sorted(session_manager.list_session_tags()) return modes.debugging, 'Selected session(s) #{0}\n{1}'.format( ', '.join(selected_sessions), _ls_out() ) elif args[0] == 'none': global selected_sessions selected_sessions = [] return modes.debugging, 'No sessions selected'.format( ', '.join(selected_sessions), _ls_out() ) non_existing_sessions = [ id for id in args if not session_manager.exists(id) ] if non_existing_sessions: raise errors.BadArgsError( 'select', 'Session(s) {0} do not exist.'. format(', '.join(non_existing_sessions)) ) global selected_sessions selected_sessions = args return modes.debugging, 'Selected session(s) #{0}\n{1}'.format( ', '.join(selected_sessions), _ls_out() )
def unhop(args): # Verify command syntax if len(args) > 1: raise errors.BadArgsError('unhop', 'unhop[ <number of hops to remove>].') n_hops_to_remove = 1 if len(args) == 1: try: n_hops_to_remove = int(args[0]) except ValueError: raise errors.BadArgsError('unhop', 'unhop[ <number of hops to remove>].') try: for _ in range(n_hops_to_remove): hops.remove_last() except console.NoHopsError: raise errors.CommandFailedError( 'unhop', 'No more hops currently exist. Nothing can be removed') _establish_default_terminal(reestablish=True) return modes.offline, None
def job(args): # Verify command syntax if len(args) > 2: raise errors.BadArgsError('job', 'job[ <job_id> | <auto>[ <app>]]') # Basic checks _establish_default_terminal() _ensure_scheduler_exists('job') # If job name is not provided then probably only one job is active if len(args) == 0 or args[0] == 'auto': try: job_id = csssi.detect_active_job(default_terminal) # No active jobs except csssi.NoActiveJobError: raise errors.CommandFailedError( 'job', 'No active user jobs found. Cannot proceed.') # More than one job is active except csssi.MoreThanOneActiveJobError: raise errors.CommandFailedError( 'job', 'Found more than one job. Cannot proceed.') # Job Id provided else: job_id = args[0] # In case app name is provided app = args[1] if len(args) == 2 else None # Hosts and PIDs will be stored here pid_dict = None # List job nodes and processes try: pid_dict = csssi.ls_job_pids(default_terminal, job_id, app) # Job does not exist except csssi.InvalidJobError: raise errors.CommandFailedError( 'job', '{0} does not seem to be a valid job id'.format(job_id)) # Cannot determine app except csssi.NoRunningAppFoundError: raise errors.CommandFailedError( 'job', 'No application name lookup pattern provided and automatic MPI application detection did not succeed. Ensure job {0} is actually running a distributed application and provide the application name' .format(job_id)) # Launch GDB and attach to PIDs session_manager, msgs = _attach_pids(pid_dict) # Initialize the debugging session return debug_session.init_debugging_mode(session_manager, msgs)