citrun

watch C/C++ source code execute
Log | Files | Refs | LICENSE

commit 1c81db9747fe691a9e7fdad60df03b13c7f2694b
parent b750b7e759d4aff23ce46a07c9b64ca469154f84
Author: Kyle Milz <kyle@0x30.net>
Date:   Wed, 27 Jul 2016 16:29:29 -0600

src: check instrumentation failure against native compilation

Diffstat:
Msrc/inst_main.cc | 67+++++++++++++++++++++++++++++++++++++++++++------------------------
Mt/inst_fail.t | 9++-------
2 files changed, 45 insertions(+), 31 deletions(-)

diff --git a/src/inst_main.cc b/src/inst_main.cc @@ -169,6 +169,33 @@ patch_link_command(std::vector<char *> &args) } int +fork_compiler(std::vector<char *> &args) +{ + // args must be NULL terminated for exec*() functions. + args.push_back(NULL); + + pid_t child_pid; + if ((child_pid = fork()) < 0) + err(1, "fork"); + + if (child_pid == 0) { + // In child + if (execvp(args[0], &args[0])) + err(1, "execvp"); + } + + int status; + if (waitpid(child_pid, &status, 0) < 0) + err(1, "waitpid"); + + // Return the exit code of the native compiler. + if (WIFEXITED(status)) + return WEXITSTATUS(status); + + return -1; +} + +int main(int argc, char *argv[]) { // We probably didn't call citrun-inst directly. @@ -217,10 +244,21 @@ main(int argc, char *argv[]) } if (instrument(argc, argv, source_files)) { + // Instrumentation failed. restore_original_src(temp_file_map); - warnx("Instrumentation failed!"); - errx(1, "If this code compiles natively, I want to know about it."); + // Try compile with native compiler. + int ret = fork_compiler(args); + + // This is bad. + if (ret == 0) { + warnx("citrun instrumentation failed, but the native" + "compile succeeded!"); + return 0; + } + + // Native compiler failed too. That's okay. + return ret; } bool linking = false; @@ -233,30 +271,11 @@ main(int argc, char *argv[]) // gcc -o main main.c fib.c linking = true; - if (linking) { + if (linking) patch_link_command(args); - } - - // Instrumentation succeeded. Fork the native compiler. - args.push_back(NULL); - - pid_t child_pid; - if ((child_pid = fork()) < 0) - err(1, "fork"); - - if (child_pid == 0) { - // In child - if (execvp(args[0], &args[0])) - err(1, "execvp"); - } - - int status; - if (waitpid(child_pid, &status, 0) < 0) - err(1, "waitpid"); + int ret = fork_compiler(args); restore_original_src(temp_file_map); - // Use the same return code as the native compiler. - if (WIFEXITED(status)) - exit(WEXITSTATUS(status)); + return ret; } diff --git a/t/inst_fail.t b/t/inst_fail.t @@ -10,13 +10,8 @@ echo "int main(void) { return 0; " > $tmpfile export PATH="`pwd`/src:${PATH}" gcc -c $tmpfile 2> $logfile -if [ $? -eq 1 ]; then - echo ok 1 -fi - -if grep -q "Instrumentation failed!" $logfile; then - echo ok 2 -fi +[ $? -eq 1 ] && echo ok 1 +grep -q "error: expected" $logfile && echo ok 2 rm $tmpfile rm $logfile