@@ -1014,24 +1014,50 @@ def graalvm_vm_arg(java_arg):
1014
1014
agent_args = ' ' .join (graalvm_vm_arg (arg ) for arg in mx_gate .get_jacoco_agent_args () or [])
1015
1015
1016
1016
# We need to make sure the arguments get passed to subprocesses, so we create a temporary launcher
1017
- # with the arguments. We also disable compilation, it hardly helps for this use case
1017
+ # with the arguments.
1018
1018
original_launcher = os .path .abspath (os .path .realpath (launcher ))
1019
1019
if sys .platform != 'win32' :
1020
- coverage_launcher = original_launcher + '.sh'
1021
- preamble = '#!/bin/sh'
1022
- pass_args = '"$@"'
1020
+ coverage_launcher = original_launcher + "_cov"
1021
+ c_launcher_source = coverage_launcher + ".c"
1022
+ exe_arg = f"--python.Executable={ coverage_launcher } "
1023
+ agent_args_list = shlex .split (agent_args )
1024
+ extra_args_c = []
1025
+ for i , arg in enumerate (agent_args_list ):
1026
+ extra_args_c .append (f'new_args[{ i + 3 } ] = "' + arg .replace ("\" " , r"\"" ) + '";' )
1027
+ extra_args_c = ' ' .join (extra_args_c )
1028
+ c_code = dedent (f"""\
1029
+ #include <stdio.h>
1030
+ #include <stdlib.h>
1031
+ #include <unistd.h>
1032
+
1033
+ int main(int argc, char **argv) {{
1034
+ char *new_args[argc + 3 + { len (agent_args_list )} ];
1035
+ new_args[0] = "{ original_launcher } ";
1036
+ new_args[1] = "--jvm";
1037
+ new_args[2] = "{ exe_arg } ";
1038
+ { extra_args_c }
1039
+ for (int i = 1; i < argc; i++) {{
1040
+ new_args[i + 3 + { len (agent_args_list )} ] = argv[i];
1041
+ }}
1042
+ new_args[argc + 3 + { len (agent_args_list )} ] = NULL;
1043
+ execvp("{ original_launcher } ", new_args);
1044
+ perror("execvp failed");
1045
+ return 1;
1046
+ }}
1047
+ """ )
1048
+ with open (c_launcher_source , "w" ) as f :
1049
+ f .write (c_code )
1050
+ compile_cmd = ["cc" , c_launcher_source , "-o" , coverage_launcher ]
1051
+ subprocess .check_call (compile_cmd )
1052
+ os .chmod (coverage_launcher , 0o775 )
1023
1053
else :
1024
1054
coverage_launcher = original_launcher .replace ('.exe' , '.cmd' )
1025
1055
# Windows looks for libraries on PATH, we need to add the jvm bin dir there or it won't find the instrumentation dlls
1026
1056
jvm_bindir = os .path .join (os .path .dirname (os .path .dirname (original_launcher )), 'jvm' , 'bin' )
1027
- preamble = f'@echo off\n set PATH=%PATH%;{ jvm_bindir } '
1028
- pass_args = '%*'
1029
- with open (coverage_launcher , "w" ) as f :
1030
- f .write (f'{ preamble } \n ' )
1031
- exe_arg = quote (f"--python.Executable={ coverage_launcher } " )
1032
- f .write (f'{ original_launcher } --jvm { exe_arg } { agent_args } { pass_args } \n ' )
1033
- if sys .platform != 'win32' :
1034
- os .chmod (coverage_launcher , 0o775 )
1057
+ with open (coverage_launcher , "w" ) as f :
1058
+ f .write (f'@echo off\n set PATH=%PATH%;{ jvm_bindir } \n ' )
1059
+ exe_arg = quote (f"--python.Executable={ coverage_launcher } " )
1060
+ f .write (f'{ original_launcher } --jvm { exe_arg } { agent_args } %*\n ' )
1035
1061
mx .log (f"Replaced { launcher } with { coverage_launcher } to collect coverage" )
1036
1062
launcher = coverage_launcher
1037
1063
return launcher
0 commit comments