@@ -37,7 +37,7 @@ def main():
37
37
38
38
39
39
def compile_user_program (options ):
40
- wrapper_source , tar_source = get_wrapper_tar_source (options )
40
+ wrapper_source , tar_source , wrapper_cpp_source = get_wrapper_code (options )
41
41
compiler_stdout = ""
42
42
executable_source = ""
43
43
@@ -67,8 +67,9 @@ def compile_user_program(options):
67
67
+ sanitizer2_sanitizer_args
68
68
+ ["-o" , executable ],
69
69
options ,
70
- wrapper_source = sanitizer2_wrapper_source ,
71
- debug_wrapper_file = "tmp_dcc_sanitizer2.c" ,
70
+ wrapper_C_source = sanitizer2_wrapper_source ,
71
+ wrapper_cpp_source = wrapper_cpp_source ,
72
+ debug_C_wrapper_file = "tmp_dcc_sanitizer2.c" ,
72
73
)
73
74
with open (executable , "rb" ) as f :
74
75
(
@@ -115,7 +116,8 @@ def compile_user_program(options):
115
116
+ sanitizer_args
116
117
+ ["-o" , options .object_pathname ],
117
118
options ,
118
- wrapper_source = wrapper_source ,
119
+ wrapper_C_source = wrapper_source ,
120
+ wrapper_cpp_source = wrapper_cpp_source ,
119
121
print_stdout = not compiler_stdout ,
120
122
)
121
123
@@ -142,8 +144,8 @@ def compile_user_program(options):
142
144
143
145
144
146
# customize wrapper source for a particular sanitizer
145
- def update_wrapper_source (sanitizer , sanitizer_n , wrapper_source , tar_source , options ):
146
- wrapper_source = wrapper_source .replace ("__SANITIZER__" , sanitizer .upper ())
147
+ def update_wrapper_source (sanitizer , sanitizer_n , src , tar_source , options ):
148
+ src = src .replace ("__SANITIZER__" , sanitizer .upper ())
147
149
if sanitizer == "valgrind" :
148
150
sanitizer_args = []
149
151
elif sanitizer == "memory" :
@@ -153,11 +155,9 @@ def update_wrapper_source(sanitizer, sanitizer_n, wrapper_source, tar_source, op
153
155
154
156
# if sanitizer != "memory" and not (sanitizer_n == 2 and sanitizer == "valgrind"):
155
157
if sanitizer != "memory" and not (sanitizer_n == 2 and sanitizer == "valgrind" ):
156
- # FIXME if we enable '-fsanitize=undefined', '-fno-sanitize-recover=undefined,integer' for memory
158
+ # FIXME if we enable '-fsanitize=undefined', '-fno-sanitize-recover=undefined,integer' for memory
157
159
# which would be preferable here we get uninitialized variable error message for undefined errors
158
- wrapper_source = wrapper_source .replace (
159
- "__UNDEFINED_BEHAVIOUR_SANITIZER_IN_USE__" , "1"
160
- )
160
+ src = src .replace ("__UNDEFINED_BEHAVIOUR_SANITIZER_IN_USE__" , "1" )
161
161
sanitizer_args += ["-fsanitize=undefined" ]
162
162
163
163
# These options stop error explanations if __ubsan_on_report can not be intercepted (on Ubuntu)
@@ -172,59 +172,64 @@ def update_wrapper_source(sanitizer, sanitizer_n, wrapper_source, tar_source, op
172
172
if os .path .exists (lib_dir ):
173
173
sanitizer_args += ["-shared-libasan" , "-Wl,-rpath," + lib_dir ]
174
174
175
- wrapper_source = wrapper_source .replace (
176
- "__LEAK_CHECK_YES_NO__" , "yes" if options .leak_check else "no"
177
- )
175
+ src = src .replace ("__LEAK_CHECK_YES_NO__" , "yes" if options .leak_check else "no" )
178
176
leak_check = options .leak_check
179
177
if leak_check and options .sanitizers [1 :] == ["valgrind" ]:
180
178
# do leak checking in valgrind (only) for (currently) better messages
181
179
leak_check = False
182
- wrapper_source = wrapper_source .replace (
183
- "__LEAK_CHECK_1_0__" , "1" if leak_check else "0"
184
- )
185
- wrapper_source = wrapper_source .replace (
186
- "__USE_FUNOPEN__" , "1" if options .use_funopen else "0"
187
- )
180
+ src = src .replace ("__LEAK_CHECK_1_0__" , "1" if leak_check else "0" )
181
+ src = src .replace ("__USE_FUNOPEN__" , "1" if options .use_funopen else "0" )
188
182
189
- wrapper_source = wrapper_source .replace (
190
- "__I_AM_SANITIZER1__" , "1" if sanitizer_n == 1 else "0"
191
- )
192
- wrapper_source = wrapper_source .replace (
193
- "__I_AM_SANITIZER2__" , "1" if sanitizer_n == 2 else "0"
194
- )
195
- wrapper_source = wrapper_source .replace (
183
+ src = src .replace ("__I_AM_SANITIZER1__" , "1" if sanitizer_n == 1 else "0" )
184
+ src = src .replace ("__I_AM_SANITIZER2__" , "1" if sanitizer_n == 2 else "0" )
185
+ src = src .replace (
196
186
"__WHICH_SANITIZER__" , "sanitizer2" if sanitizer_n == 2 else "sanitizer1"
197
187
)
198
188
199
- wrapper_source = tar_source + wrapper_source
200
- return wrapper_source , sanitizer_args
189
+ src = tar_source + src
190
+ return src , sanitizer_args
201
191
202
192
203
193
def execute_compiler (
204
194
compiler ,
205
195
dcc_supplied_arguments ,
206
196
options ,
207
- wrapper_source = "" ,
208
- debug_wrapper_file = "tmp_dcc_sanitizer1.c" ,
197
+ wrapper_C_source = "" ,
198
+ debug_C_wrapper_file = "tmp_dcc_sanitizer1.c" ,
209
199
rename_functions = True ,
210
200
print_stdout = True ,
211
201
checking_only = False ,
202
+ wrapper_cpp_source = "" ,
203
+ debug_cpp_wrapper_file = "tmp_dcc_sanitizer1.cpp" ,
212
204
):
213
- extra_arguments , extra_arguments_debug = compile_wrapper_source (
214
- wrapper_source , options , rename_functions , debug_wrapper_file
205
+ extra_c_arguments , extra_c_arguments_debug = compile_wrapper_source (
206
+ wrapper_C_source ,
207
+ options ,
208
+ debug_C_wrapper_file ,
209
+ cpp = False ,
210
+ rename_functions = rename_functions ,
211
+ )
212
+ extra_cpp_arguments , extra_cpp_arguments_debug = compile_wrapper_source (
213
+ wrapper_cpp_source ,
214
+ options ,
215
+ debug_cpp_wrapper_file ,
216
+ cpp = True ,
217
+ rename_functions = rename_functions ,
215
218
)
216
219
217
220
command = (
218
221
[compiler ]
219
222
+ dcc_supplied_arguments
220
- + extra_arguments
223
+ + extra_c_arguments
224
+ + extra_cpp_arguments
221
225
+ options .user_supplied_compiler_args
222
226
)
223
227
if options .debug > 1 :
224
228
debug_command = (
225
229
[compiler ]
226
230
+ dcc_supplied_arguments
227
- + extra_arguments_debug
231
+ + extra_c_arguments_debug
232
+ + extra_cpp_arguments_debug
228
233
+ options .user_supplied_compiler_args
229
234
)
230
235
append_debug_compile (debug_command )
@@ -282,9 +287,11 @@ def execute_compiler(
282
287
dcc_supplied_arguments ,
283
288
options ,
284
289
rename_functions = False ,
285
- wrapper_source = wrapper_source ,
290
+ wrapper_C_source = wrapper_C_source ,
286
291
print_stdout = print_stdout ,
287
- debug_wrapper_file = debug_wrapper_file ,
292
+ debug_C_wrapper_file = debug_C_wrapper_file ,
293
+ wrapper_cpp_source = wrapper_cpp_source ,
294
+ debug_cpp_wrapper_file = debug_cpp_wrapper_file ,
288
295
)
289
296
290
297
if stdout and print_stdout :
@@ -300,15 +307,20 @@ def execute_compiler(
300
307
301
308
302
309
def compile_wrapper_source (
303
- source , options , rename_functions = True , debug_wrapper_file = "tmp_dcc_sanitizer1.c"
310
+ source , options , debug_wrapper_file , cpp = False , rename_functions = True
304
311
):
305
312
if not source :
306
313
return [], []
307
314
rename_arguments , source = get_rename_arguments (source , options , rename_functions )
308
- relocatable_filename = os .path .join (
309
- options .temporary_directory , "dcc_wrapper_source.o"
315
+ relocatable_basename = (
316
+ "dcc_cpp_wrapper_source.o" if cpp else "dcc_c_wrapper_source.o"
317
+ )
318
+ relocatable_pathname = os .path .join (
319
+ options .temporary_directory , relocatable_basename
310
320
)
311
- compiler = options .c_compiler .replace ("clang++" , "clang" ).replace ("++" , "cc" )
321
+ compiler = options .c_compiler
322
+ if not cpp :
323
+ compiler = options .c_compiler .replace ("clang++" , "clang" ).replace ("++" , "cc" )
312
324
if options .debug > 1 :
313
325
try :
314
326
options .debug_print ("Leaving dcc code in" , debug_wrapper_file )
@@ -321,23 +333,23 @@ def compile_wrapper_source(
321
333
"-c" ,
322
334
debug_wrapper_file ,
323
335
"-o" ,
324
- "dcc_wrapper_source.o" ,
336
+ relocatable_basename ,
325
337
] + WRAPPER_SOURCE_COMPILER_ARGS
326
338
append_debug_compile (debug_command )
327
339
command = [
328
340
compiler ,
329
341
"-c" ,
330
342
"-x" ,
331
- "c" ,
343
+ "c++" if cpp else "c " ,
332
344
"-" ,
333
345
"-o" ,
334
- relocatable_filename ,
346
+ relocatable_pathname ,
335
347
] + WRAPPER_SOURCE_COMPILER_ARGS
336
348
process = run (command , options , input = source )
337
349
if process .stdout or process .returncode != 0 :
338
350
options .die ("Internal error\n " + process .stdout )
339
- return rename_arguments + [relocatable_filename ], rename_arguments + [
340
- "dcc_wrapper_source.o" ,
351
+ return rename_arguments + [relocatable_pathname ], rename_arguments + [
352
+ relocatable_basename
341
353
]
342
354
343
355
@@ -401,7 +413,17 @@ def append_debug_compile(command):
401
413
print (e , file = sys .stderr )
402
414
403
415
404
- def get_wrapper_tar_source (options ):
416
+ def get_wrapper_cpp_code (options ):
417
+ wrapper_source = "" .join (
418
+ pkgutil .get_data ("embedded_src" , f ).decode ("utf8" )
419
+ for f in [
420
+ "dcc_io.c" ,
421
+ ]
422
+ )
423
+ return add_constants_to_source_code (wrapper_source , options )
424
+
425
+
426
+ def get_wrapper_code (options ):
405
427
wrapper_source = "" .join (
406
428
pkgutil .get_data ("embedded_src" , f ).decode ("utf8" )
407
429
for f in [
@@ -411,41 +433,45 @@ def get_wrapper_tar_source(options):
411
433
"dcc_check_output.c" ,
412
434
]
413
435
)
414
-
415
- wrapper_source = wrapper_source .replace ("__PATH__" , options .dcc_path )
416
- wrapper_source = wrapper_source .replace ("__DCC_VERSION__" , '"' + VERSION + '"' )
417
- wrapper_source = wrapper_source .replace ("__HOSTNAME__" , '"' + platform .node () + '"' )
418
- wrapper_source = wrapper_source .replace (
419
- "__CLANG_VERSION__" , f'"{ options .clang_version } "'
420
- )
421
- wrapper_source = wrapper_source .replace (
422
- "__SUPRESSIONS_FILE__" , options .suppressions_file
436
+ wrapper_source = add_constants_to_source_code (wrapper_source , options )
437
+ wrapper_source , tar_source = add_embedded_tarfile_handling_to_source_code (
438
+ wrapper_source , options
423
439
)
424
- wrapper_source = wrapper_source .replace (
440
+ wrapper_cpp_source = ""
441
+ if options .cpp_mode :
442
+ wrapper_cpp_source = "" .join (
443
+ pkgutil .get_data ("embedded_src" , f ).decode ("utf8" )
444
+ for f in [
445
+ "dcc_io.cpp" ,
446
+ ]
447
+ )
448
+ return wrapper_source , tar_source , wrapper_cpp_source
449
+
450
+
451
+ def add_constants_to_source_code (src , options ):
452
+ src = src .replace ("__PATH__" , options .dcc_path )
453
+ src = src .replace ("__DCC_VERSION__" , '"' + VERSION + '"' )
454
+ src = src .replace ("__HOSTNAME__" , '"' + platform .node () + '"' )
455
+ src = src .replace ("__CLANG_VERSION__" , f'"{ options .clang_version } "' )
456
+ src = src .replace ("__SUPRESSIONS_FILE__" , options .suppressions_file )
457
+ src = src .replace (
425
458
"__STACK_USE_AFTER_RETURN__" , "1" if options .stack_use_after_return else "0"
426
459
)
427
- wrapper_source = wrapper_source .replace (
428
- "__CHECK_OUTPUT__" , "1" if options .check_output else "0"
429
- )
430
- wrapper_source = wrapper_source .replace (
460
+ src = src .replace ("__CHECK_OUTPUT__" , "1" if options .check_output else "0" )
461
+ src = src .replace ("__CPP_MODE__" , "1" if options .cpp_mode else "0" )
462
+ src = src .replace (
431
463
"__WRAP_POSIX_SPAWN__" , "1" if options .valgrind_fix_posix_spawn else "0"
432
464
)
433
- wrapper_source = wrapper_source .replace (
434
- "__CLANG_VERSION_MAJOR__" , str (options .clang_version_major )
435
- )
436
- wrapper_source = wrapper_source .replace (
437
- "__CLANG_VERSION_MINOR__" , str (options .clang_version_minor )
438
- )
439
- wrapper_source = wrapper_source .replace (
440
- "__N_SANITIZERS__" , str (len (options .sanitizers ))
441
- )
442
- wrapper_source = wrapper_source .replace ("__DEBUG__" , "1" if options .debug else "0" )
443
-
465
+ src = src .replace ("__CLANG_VERSION_MAJOR__" , str (options .clang_version_major ))
466
+ src = src .replace ("__CLANG_VERSION_MINOR__" , str (options .clang_version_minor ))
467
+ src = src .replace ("__N_SANITIZERS__" , str (len (options .sanitizers )))
468
+ src = src .replace ("__DEBUG__" , "1" if options .debug else "0" )
444
469
if len (options .sanitizers ) > 1 :
445
- wrapper_source = wrapper_source .replace (
446
- "__SANITIZER_2__" , options . sanitizers [ 1 ]. upper ()
447
- )
470
+ src = src .replace ("__SANITIZER_2__" , options . sanitizers [ 1 ]. upper ())
471
+ return src
472
+
448
473
474
+ def add_embedded_tarfile_handling_to_source_code (src , options ):
449
475
tar_n_bytes , tar_source = source_for_embedded_tarfile (options )
450
476
watcher = rf"python3 -E -c \"import io,os,sys,tarfile,tempfile\n\
451
477
with tempfile.TemporaryDirectory() as temp_dir:\n\
@@ -455,10 +481,8 @@ def get_wrapper_tar_source(options):
455
481
os.chdir(temp_dir)\n\
456
482
exec(open('watch_valgrind.py').read())\n\
457
483
\""
458
-
459
- wrapper_source = wrapper_source .replace ("__MONITOR_VALGRIND__" , watcher )
460
-
461
- return wrapper_source , tar_source
484
+ src = src .replace ("__MONITOR_VALGRIND__" , watcher )
485
+ return src , tar_source
462
486
463
487
464
488
def run (
0 commit comments