def __do_ccg_wf(self, task, start_task_num=1, end_task_num=4): ##################################### ## Task - Generate geolookup table ## ##################################### task.set_progress(start_task_num, end_task_num) if not self.__generate_geolookup_table(): self.__error_exit("Failed to generate lookup tables...") return ########################## ## Task - CCG ## ########################## task.set_progress(start_task_num + 1, end_task_num) for file in os.listdir(os.path.join(self.__consts['ccg_lib'], "src")): if os.path.isdir( os.path.join(self.__consts['ccg_lib'], "src", file)): shutil.rmtree(os.path.join(self.__consts['ccg_lib'], "src", file), onerror=del_rw) else: os.remove(os.path.join(self.__consts['ccg_lib'], "src", file)) self.__console_msg("Generating C code.") builder = promises.TargetWrapper("Build All") task.set_progress(start_task_num, end_task_num) retval = yield builder.wait_on_execute() if retval is not 0: self.__error_exit("Failed to generate C code.") return obj_dir = GPS.Project.root().object_dirs() ############################## ## Task - post processing ## ############################## self.__console_msg("Post-processing CCG output.") retval, output = yield self.__post_ccg(obj_dir=obj_dir) if retval is not 0: self.__error_exit("Failed to post-process CCG output.") return task.set_progress(start_task_num + 2, end_task_num) ######################################## ## Task - build project documentation ## ######################################## self.__console_msg("Building project documentation.") gnatdoc = promises.TargetWrapper("gnatdoc") retval = yield gnatdoc.wait_on_execute( extra_args=["-P", GPS.Project.root().file().path, "-l"]) if retval is not 0: self.__error_exit("Failed to generate project documentation.") return task.set_progress(start_task_num + 3, end_task_num)
def run_gnatcov_with_instrumentation_wf(self, main_name): # Get the executable to analyze exe = str(GPS.File(main_name).executable_path) # Build the coverage runtime p = promises.TargetWrapper("GNATcov Build Coverage Runtime") r = yield p.wait_on_execute(quiet=True) if r is not 0: GPS.Console("Messages").write("GNATcov runtime build failed ", mode="error") return # Install the coverage runtime p = promises.TargetWrapper("GNATcov Install Coverage Runtime") r = yield p.wait_on_execute(quiet=True) if r is not 0: GPS.Console("Messages").write("GNATcov runtime build failed ", mode="error") return # Run GNATcov with instrumentation on it p = promises.TargetWrapper("Run GNATcov with instrumentation") r = yield p.wait_on_execute(exe, quiet=True) if r is not 0: GPS.Console("Messages").write("GNATcov run failed ", mode="error") return # Build the instrumented main p = promises.TargetWrapper("GNATcov Build Instrumented Main") r = yield p.wait_on_execute(quiet=True) if r is not 0: GPS.Console("Messages").write("Can't build the project with " + "the GNATcov switches", mode="error") return # Go to the object directory before executing the instrumented main: we # want to produce the trace file in the object dir and not in the # project's root directory obj_dir = GPS.Project.root().object_dirs()[0] GPS.cd(obj_dir) # Build the instrumented main p = promises.ProcessWrapper(cmdargs=[exe]) r = yield p.wait_until_terminate() # Generate and display the GNATcov Coverage Report p = promises.TargetWrapper("Generate GNATcov Instrumented Main Report") r = yield p.wait_on_execute(exe, quiet=True)
def build_main(main_name): """ Try to launch the 'Build Main' build target with the given :param str main_name:. Set __build_succeed to True when the build succeed and to False otherwise. """ if WorkflowButtons.__needs_build.get(main_name) is None: WorkflowButtons.__needs_build[main_name] = True if not WorkflowButtons.__needs_build[main_name]: WorkflowButtons.__build_succeed = True return if not main_name: WorkflowButtons.__display_error("Main is not specified") WorkflowButtons.__build_succeed = False return # Build the executable builder = promises.TargetWrapper("Build Main") r0 = yield builder.wait_on_execute(main_name) if r0 is not 0: WorkflowButtons.__build_succeed = False return WorkflowButtons.__needs_build[main_name] = False WorkflowButtons.__build_succeed = True
def build_main(main_name): """ Try to launch the 'Build Main' build target with the given :param str main_name:. Set __build_succeed to True when the build succeed and to False otherwise. """ if not WorkflowButtons.__needs_build: WorkflowButtons.__build_succeed = True return if not main_name: WorkflowButtons.__display_error("Main is not specified") WorkflowButtons.__build_succeed = False return # Build the executable builder = promises.TargetWrapper("Build Main") r0 = yield builder.wait_on_execute(main_name) if r0 is not 0: WorkflowButtons.__build_succeed = False return WorkflowButtons.__needs_build = False WorkflowButtons.__build_succeed = True # Reconnect to the hooks to know if we can skip the 'Build Main' # BuildTarget next time. WorkflowButtons.__connect_hooks()
def gnatfuzz_generate_workflow(self, task): """The 'gnatfuzz generate' workflow""" p = promises.TargetWrapper("gnatfuzz generate") r = yield p.wait_on_execute() if r != 0: GPS.Console("Messages").write("gnatfuzz generate returned nonzero", mode="error") return
def run_gnatcov_with_instrumentation_wf(self, main_name): # Get the executable to analyze exe = str(GPS.File(main_name).executable_path) # Don't build/install the GNATcov runtime if a prebuilt one has been # specified. if not prebuilt_runtime_path: # Build the coverage runtime p = promises.TargetWrapper("GNATcov Build Coverage Runtime") r = yield p.wait_on_execute(quiet=True) if r != 0: GPS.Console("Messages").write("GNATcov runtime build failed ", mode="error") return # Install the coverage runtime p = promises.TargetWrapper("GNATcov Install Coverage Runtime") r = yield p.wait_on_execute(quiet=True) if r != 0: GPS.Console("Messages").write("GNATcov runtime build failed ", mode="error") return else: GPS.Console().write("\nPrebuilt runtime is used: %s\n" % prebuilt_runtime_path) # Run GNATcov with instrumentation on it p = promises.TargetWrapper("Run GNATcov with instrumentation") r = yield p.wait_on_execute(exe, quiet=True) if r != 0: GPS.Console("Messages").write("GNATcov instrumentation failed ", mode="error") return # Build the instrumented main p = promises.TargetWrapper("GNATcov Build Instrumented Main") r = yield p.wait_on_execute(quiet=True) if r != 0: GPS.Console("Messages").write("Can't build the project with " + "the GNATcov switches", mode="error") return self.run_instrumented_main_wf(main_name, True)
def gnatfuzz_analyze_file_workflow(self, task): """Workflow for 'gnatfuzz analyze'.""" # Launch the analyze target in the background p = promises.TargetWrapper("gnatfuzz analyze file") r = yield p.wait_on_execute() if r != 0: self.error("gnatfuzz analyze returned nonzero") return self.process_analyze_messages()
def __emu_debug_wf(self, main_name): """ Workflow to debug a program under the emulator. """ # STEP 1.0 get main name if main_name is None: self.__error_exit(msg="Main not specified.") return # STEP 1.5 Build it log("Building Main %s..." % main_name) builder = promises.TargetWrapper("Build Main") r0 = yield builder.wait_on_execute(main_name) if r0 is not 0: self.__error_exit(msg="Build error.") return binary = GPS.File(main_name).executable_path.path log("... done.") # STEP 2 Switch to the "Debug" perspective To have GNATemu console in # the debugger perspective. GPS.MDI.load_perspective("Debug") # STEP 2 load with Emulator debug_port = GPS.Project.root().get_attribute_as_string( package="Emulator", attribute="Debug_Port") # TODO: remove this fall-back once GNATemulator supports the # new 'Debug_Port' attribute (Fabien's task) if debug_port == "": debug_port = "1234" self.run_gnatemu( ["--freeze-on-startup", "--gdb=%s" % debug_port, binary]) log("... done.") # STEP 3 launch the debugger debugger_promise = promises.DebuggerWrapper( GPS.File(binary), remote_target="localhost:" + debug_port, remote_protocol="remote") # block execution until debugger is free r3 = yield debugger_promise.wait_and_send(block=True) if not r3: self.__error_exit("Could not initialize the debugger.") return log("... done.")
def run_gnatcov_wf(self, main_name): # Set the build mode to 'gnatcov' if it's not set yet and force # the rebuild of the selected main in that case. if GPS.get_build_mode() != "gnatcov": GPS.set_build_mode("gnatcov") WorkflowButtons.force_rebuild_main() # Build the selected main yield WorkflowButtons.build_main(main_name) # Get the executable to analyze exe = str(GPS.File(main_name).executable_path) # Run GNATcov on it p = promises.TargetWrapper("Run under GNATcov") r = yield p.wait_on_execute(exe) if r is not 0: return # Generate and display the GNATcov Coverage Report p = promises.TargetWrapper("Generate GNATcov Main Report") r = yield p.wait_on_execute(exe)
def run_gnatcov_wf(self, main_name): # Build the project with GNATcov switches p = promises.TargetWrapper("GNATcov Build Main") r = yield p.wait_on_execute() if r is not 0: GPS.Console("Messages").write("Can't build the project with " + "the GNATcov switches", mode="error") return # Get the executable to analyze exe = str(GPS.File(main_name).executable_path) # Run GNATcov on it p = promises.TargetWrapper("Run under GNATcov") r = yield p.wait_on_execute(exe) if r is not 0: GPS.Console("Messages").write("GNATcov run failed ", mode="error") return # Generate and display the GNATcov Coverage Report p = promises.TargetWrapper("Generate GNATcov Main Report") r = yield p.wait_on_execute(exe)
def __build_and_run_wf(main_name): """ Workflow that builds and run the program designated by :param straight main_name:. """ # Build the executable yield WorkflowButtons.build_main(main_name) if not WorkflowButtons.__build_succeed: return # Run it exe = GPS.File(main_name).executable_path runner = promises.TargetWrapper("Run Main") yield runner.wait_on_execute(str(exe))
def run_gnatemu(args, in_console=True): command = GNATemulator.generate_gnatemu_command( GNATemulator.get_gnatemu_name(), args) GPS.Console("Messages").write("Running in emulator: %s\n" % (' '.join(command))) # - We open GNATemu in a console by default. # - If specified, we use the BuildTarget for running GNATemu instead. # - Don't close the console when GNAtemu exits so we have time to see # the results # - GNATemu should be in the task manager if in_console: yield Console_Process(command=command, force=True, close_on_exit=False, task_manager=True, manage_prompt=False) else: builder = promises.TargetWrapper("Run GNATemulator") yield builder.wait_on_execute(extra_args=args)
def build(main_name): """ Generator to build the program. """ if main_name is None: GNATemulator.__error_exit(msg="Main not specified") return # STEP 1.5 Build it log("Building Main %s..." % main_name) builder = promises.TargetWrapper("Build Main") r0 = yield builder.wait_on_execute(main_name) if r0 is not 0: GNATemulator.__error_exit(msg="Build error.") raise RuntimeError("Build failed.") log("... done.")
def __emu_wf(self, main_name): """ Workflow to build and run the program in the emulator. """ if main_name is None: self.__error_exit(msg="Main not specified") return # STEP 1.5 Build it log("Building Main %s..." % main_name) builder = promises.TargetWrapper("Build Main") r0 = yield builder.wait_on_execute(main_name) if r0 is not 0: self.__error_exit(msg="Build error.") return log("... done.") # STEP 2 load with Emulator self.run_gnatemu([GPS.File(main_name).executable_path.path])
def __build_and_run_all_wf(self, main_name): """ Workflow that calls "Build All" and then runs all the executables sequentially. """ # Build All builder = promises.TargetWrapper("Build All") r0 = yield builder.wait_on_execute() if r0 is not 0: return # Call "Run Main Number ..." on each main i = 1 while True: run_action = GPS.Action("Run Main Number %i" % (i)) if not run_action.exists(): break run_action.execute_if_possible() yield promises.wait_tasks() i += 1
def __debug_wf(self, main_name): """ Workflow to build, flash and debug the program on the real board. """ # Return with a warning message if we are still processing a previously # launched workflow. if self.__is_busy: self.__display_message(("Warning: 'Debug on Board' " "already being executed"), mode="error") return # Reset the connection if still alive self.__reset_all() # Tell GPS that we can't run another workflow until we finish # the one that is currently running. self.__is_busy = True # Check if we have a main to debug if main_name is None: self.__error_exit(msg="Main not specified") return # Build the executable builder = promises.TargetWrapper("Build Main") r0 = yield builder.wait_on_execute(main_name) if r0 is not 0: self.__reset_all() return # Check that the settings are correctly set to debug on board success = self.__verify_settings(for_debug=True) if not success: self.__error_exit(msg="Could not connect to the board.") return # Switch directly to the "Debug" perspective so that the # connection tool console is still visible when spawning the debugger. GPS.MDI.load_perspective("Debug") # Launch the connection tool, if any if self.__connector: # Launch the connection tool with its associated console cmd = self.__connector.get_command_line() self.__display_message("Launching: %s" % (' '.join(cmd))) try: self.__connection = promises.ProcessWrapper(cmd) self.__connection.lines.subscribe(self.__display_message) output = yield self.__connection.wait_until_match( self.__get_connection_detection_regexp(), 120000) if output is None: self.__error_exit(msg="Could not connect to the board.") return except Exception: self.__error_exit("Could not connect to the board.") return # Spawn the debugger on the executable and load it self.__display_message("Launching debugger.") exe = GPS.File(main_name).executable_path debugger_promise = promises.DebuggerWrapper( exe, remote_target=self.__remote_target, remote_protocol=self.__remote_protocol) # Load the executable yield debugger_promise.wait_and_send( cmd='load "%s"' % (exe), block=True) # Reset the board yield debugger_promise.wait_and_send( cmd="monitor reset halt", block=True) # Not busy anymore self.__is_busy = False
def __flash_wf(self, main_name): """Workflow to build and flash the program on the board. """ # Return with a warning message if we are still processing a previously # launched workflow. if self.__is_busy: self.__display_message( msg="Warning: 'Flash to Board' already being executed", mode="error") return self.__is_busy = True # Check if we have a main to flash if main_name is None: self.__error_exit(msg="Could not find the name of the main.") return # Build the executable builder = promises.TargetWrapper("Build Main") r0 = yield builder.wait_on_execute(main_name) if r0 is not 0: self.__reset_all() return # Check that the settings are correctly set to flash the board success = self.__verify_settings() if not success: self.__error_exit(msg="Could not flash the board.") return # Get the executable path exe = GPS.File(main_name).executable_path.path # Retrieve the load address of the executable with objdump self.__display_message("Retrieving the load address.") cmd = ["%s-objdump" % (self.__target), exe, "-h"] self.__display_message(' '.join(cmd)) try: con = promises.ProcessWrapper(cmd) except Exception: self.__error_exit("Could not launch executable %s" % (cmd[0])) return # We want to match the line after # the Algn to get the first load address. output = yield con.wait_until_match("Algn\n.+") if output is None: self.__error_exit("%s returned an error." % (cmd[0])) return # We know that the first LMA is at index 5. self.__load_address = "0x%s" % (output.split()[5]) self.__display_message("Load address is: %s" % (self.__load_address)) # Create the flashable binary with objcopy self.__display_message("Creating the binary (flashable) image.") binary = exe + ".bin" cmd = ["%s-objcopy" % (self.__target), "-O", "binary", exe, binary] self.__display_message(' '.join(cmd)) try: con = promises.ProcessWrapper(cmd) except Exception: self.__error_exit("Could not launch executable %s." % (cmd[0])) return status, output = yield con.wait_until_terminate() if status != 0: # Show output in the Messages view on error self.__display_message(output) self.__error_exit("%s returned an error." % (cmd[0])) return # Flash the binary and wait until it completes cmd = self.__get_flashing_command_line(binary) self.__display_message("Flashing image to board...") self.__display_message(' '.join(cmd)) try: con = promises.ProcessWrapper(cmd) con.lines.subscribe(self.__display_message) output = yield con.wait_until_match( self.__get_flashing_complete_regexp(), 120000) if output is None: self.__error_exit(msg="Could not flash the executable.") con.terminate() return except Exception: self.__error_exit("Could not connect to the board.") return self.__display_message(("Flashing complete. " "You may need to reset (or cycle power).")) # Not busy anymore self.__is_busy = False
def run_instrumented_main_wf(self, main_name, generate=False): exe = str(GPS.File(main_name).executable_path) # Go to the object directory before executing the instrumented main: we # want to produce the trace file in the object dir and not in the # project's root directory obj_dir = GPS.Project.root().object_dirs()[0] GPS.cd(obj_dir) # Clean the previous trace file if it exists (the run can fails and # then the trace file will not be overwritten: it will show outdated # data) srctrace_filename = os.path.join(obj_dir, exe + ".srctrace") try: os.remove(srctrace_filename) except FileNotFoundError: pass # Run the instrumented main (through GNATemulator for cross targets) # it will generate the new trace file. target = GPS.get_target() if target == "": cmdargs = [exe] p = promises.ProcessWrapper(cmdargs) GPS.Console().write(' '.join(cmdargs)) status, output = yield p.wait_until_terminate(show_if_error=True) if status != 0: GPS.Console("Messages").write( "Failed to execute main with status " + str(status)) else: # Launch the instrumented executable through GNATemulator cmdargs = GPS.BuildTarget( "Run GNATemulator").get_expanded_command_line() cmdargs.append(exe) GPS.Console().write(' '.join(cmdargs) + "\n") gnatemu_promise = promises.ProcessWrapper(cmdargs=cmdargs) status, output = yield gnatemu_promise.wait_until_terminate( show_if_error=True) # Put the output in a file and use 'gnatcov extract-base64-trace' # to retrieve the traces information from it out_filename = os.path.join(obj_dir, exe + ".out") with open(out_filename, "w") as f: f.write(output) extract_trace_cmd = [ "gnatcov", "extract-base64-trace", out_filename, srctrace_filename ] GPS.Console().write(' '.join(extract_trace_cmd) + "\n") status = GPS.Process(extract_trace_cmd).wait() if status != 0: GPS.Console().write( "Could not extract traces info from executable's output", mode="error") if status == 0 and generate: # Generate and display the GNATcov Coverage Report p = promises.TargetWrapper( "Generate GNATcov Instrumented Main Report") yield p.wait_on_execute(exe, quiet=True) return status