def run_and_trace( base_path: str, session_name_prefix: str, ros_events: List[str], kernel_events: List[str], package_name: str, node_names: List[str], additional_actions: Union[List[Action], Action] = [], ) -> Tuple[int, str]: """ Run a node while tracing. :param base_path: the base path where to put the trace directory :param session_name_prefix: the session name prefix for the trace directory :param ros_events: the list of ROS UST events to enable :param kernel_events: the list of kernel events to enable :param package_name: the name of the package to use :param node_names: the names of the nodes to execute :param additional_actions: the list of additional actions to prepend :return: exit code, full generated path """ session_name = append_timestamp(session_name_prefix) full_path = os.path.join(base_path, session_name) if not isinstance(additional_actions, list): additional_actions = [additional_actions] launch_actions = additional_actions # Add trace action launch_actions.append( Trace( session_name=session_name, append_timestamp=False, base_path=base_path, events_ust=ros_events, events_kernel=kernel_events, )) # Add nodes for node_name in node_names: n = Node( package=package_name, executable=node_name, output='screen', ) launch_actions.append(n) ld = LaunchDescription(launch_actions) ls = LaunchService() ls.include_launch_description(ld) exit_code = ls.run() return exit_code, full_path
def __init__( self, *, session_name: str, append_timestamp: bool = False, base_path: Optional[str] = None, events_ust: List[str] = names.DEFAULT_EVENTS_ROS, events_kernel: List[str] = names.DEFAULT_EVENTS_KERNEL, context_names: List[str] = names.DEFAULT_CONTEXT, profile_fast: bool = True, **kwargs, ) -> None: """ Create a Trace. :param session_name: the name of the tracing session :param append_timestamp: whether to append timestamp to the session name :param base_path: the path to the base directory in which to create the session directory, or `None` for default :param events_ust: the list of ROS UST events to enable :param events_kernel: the list of kernel events to enable :param context_names: the list of context names to enable :param profile_fast: `True` to use fast profiling, `False` for normal (only if necessary) """ super().__init__(**kwargs) if append_timestamp: session_name = path.append_timestamp(session_name) self.__session_name = session_name self.__base_path = base_path or path.get_tracing_directory() self.__events_ust = events_ust self.__events_kernel = events_kernel self.__context_names = context_names self.__profile_fast = profile_fast self.__logger = logging.get_logger(__name__) self.__ld_preload_actions: List[LdPreload] = [] # Add LD_PRELOAD actions if corresponding events are enabled if self.has_profiling_events(self.__events_ust): self.__ld_preload_actions.append( LdPreload(self.LIB_PROFILE_FAST if profile_fast else self.LIB_PROFILE_NORMAL) ) if self.has_ust_memory_events(self.__events_ust): self.__ld_preload_actions.append( LdPreload(self.LIB_MEMORY_UST) )
def __perform_substitutions(self, context: LaunchContext) -> None: self.__session_name = perform_substitutions(context, self.__session_name) if self.__append_timestamp: self.__session_name = path.append_timestamp(self.__session_name) self.__base_path = perform_substitutions(context, self.__base_path) \ if self.__base_path else path.get_tracing_directory() self.__events_ust = [ perform_substitutions(context, x) for x in self.__events_ust ] self.__events_kernel = [ perform_substitutions(context, x) for x in self.__events_kernel ] self.__context_fields = \ { domain: [perform_substitutions(context, field) for field in fields] for domain, fields in self.__context_fields.items() } \ if isinstance(self.__context_fields, dict) \ else [perform_substitutions(context, field) for field in self.__context_fields] # Add LD_PRELOAD actions if corresponding events are enabled if self.has_libc_wrapper_events(self.__events_ust): self.__ld_preload_actions.append(LdPreload(self.LIB_LIBC_WRAPPER)) if self.has_pthread_wrapper_events(self.__events_ust): self.__ld_preload_actions.append( LdPreload(self.LIB_PTHREAD_WRAPPER)) if self.has_dl_events(self.__events_ust): self.__ld_preload_actions.append(LdPreload(self.LIB_DL)) # Warn if events match both normal AND fast profiling libs has_fast_profiling_events = self.has_profiling_events( self.__events_ust, True) has_normal_profiling_events = self.has_profiling_events( self.__events_ust, False) # In practice, the first lib in the LD_PRELOAD list will be used, so the fast one here if has_fast_profiling_events: self.__ld_preload_actions.append(LdPreload(self.LIB_PROFILE_FAST)) if has_normal_profiling_events: self.__ld_preload_actions.append(LdPreload( self.LIB_PROFILE_NORMAL)) if has_normal_profiling_events and has_fast_profiling_events: self.__logger.warning( 'events match both normal and fast profiling shared libraries')
def __init__( self, *, session_name: str, append_timestamp: bool = False, base_path: str = path.DEFAULT_BASE_PATH, events_ust: List[str] = names.DEFAULT_EVENTS_ROS, events_kernel: List[str] = names.DEFAULT_EVENTS_KERNEL, profile_fast: bool = True, **kwargs, ) -> None: """ Constructor. :param session_name: the name of the tracing session :param append_timestamp: whether to append timestamp to the session name :param base_path: the path to the base directory in which to create the session directory :param events_ust: the list of ROS UST events to enable :param events_kernel: the list of kernel events to enable :param profile_fast: `True` to use fast profiling, `False` for normal (only if necessary) """ super().__init__(**kwargs) if append_timestamp: session_name = path.append_timestamp(session_name) self.__session_name = session_name self.__base_path = base_path self.__events_ust = events_ust self.__events_kernel = events_kernel self.__profile_fast = profile_fast self.__ld_preload_action = None if self.has_profiling_events(events_ust): profile_lib_name = self.PROFILE_LIB_FAST if profile_fast else self.PROFILE_LIB_NORMAL profile_lib_path = self.get_shared_lib_path(profile_lib_name) if profile_lib_path is not None: self.__ld_preload_action = SetEnvironmentVariable( 'LD_PRELOAD', profile_lib_path, )