citrun

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

commit 005b0768c37e2ab7f456eb0423db8375953f33a9
parent 0ac243be7e8c6aa564736bc7935bd018076b6113
Author: Kyle Milz <kyle@0x30.net>
Date:   Wed, 15 Jun 2016 20:48:28 -0600

src: make instrumented application depend on runtime lib

Diffstat:
Mlib/Jamfile | 8+++-----
Mlib/runtime.c | 2++
Msrc/inst_action.cc | 2++
Msrc/inst_ast_visitor.cc | 10++++++++++
Msrc/inst_main.cc | 1+
Mt/fibonacci.t | 4++--
Mt/for.t | 2+-
Mt/hello_world.t | 2+-
Mt/if.t | 2+-
Mt/inst_preamble.t | 1+
Mt/return.t | 4++--
Mt/switch.t | 2+-
Mt/while.t | 2+-
13 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/lib/Jamfile b/lib/Jamfile @@ -1,8 +1,6 @@ SubDir TOP lib ; -SubDirCcFlags -pthread -fpic -DPIC ; +SubDirCcFlags -pthread ; -Main libcitrun.$(SHLIB_SUF) : runtime.c ; -InstallLib $(PREFIX)/lib : libcitrun.$(SHLIB_SUF) ; - -LINKFLAGS on libcitrun.$(SHLIB_SUF) += -shared -fpic -pthread ; +Library libcitrun : runtime.c ; +InstallLib $(PREFIX)/lib : libcitrun ; diff --git a/lib/runtime.c b/lib/runtime.c @@ -20,6 +20,8 @@ extern uint64_t citrun_nodes_total; void send_metadata(int); void send_execution_data(int); +/* Make sure instrumented programs rely on this library in some way. */ +int needs_to_link_against_libcitrun; int xread(int d, const void *buf, size_t bytes_total); int xwrite(int d, const void *buf, size_t bytes_total); diff --git a/src/inst_action.cc b/src/inst_action.cc @@ -88,6 +88,8 @@ InstrumentAction::EndSourceFileAction() // Embed the header directly in the primary source file. ss << runtime_h << std::endl; + ss << "extern int needs_to_link_against_libcitrun;" << std::endl; + // Define storage for coverage data ss << "static uint64_t _citrun_lines[" << num_lines << "];" << std::endl; diff --git a/src/inst_ast_visitor.cc b/src/inst_ast_visitor.cc @@ -66,6 +66,16 @@ RewriteASTVisitor::VisitFunctionDecl(clang::FunctionDecl *f) if (f->hasBody() == 0) return true; + // We need to depend directly on a symbol provided by libcitrun, + // otherwise the library will get discarded at link time. + std::stringstream ss; + ss << "needs_to_link_against_libcitrun = 0;"; + + clang::Stmt *FuncBody = f->getBody(); + clang::SourceLocation curly_brace(FuncBody->getLocStart().getLocWithOffset(1)); + + TheRewriter.InsertTextBefore(curly_brace, ss.str()); + return true; } diff --git a/src/inst_main.cc b/src/inst_main.cc @@ -202,6 +202,7 @@ patch_link_command(std::vector<char *> &args) // Add the runtime library and the symbol define hack // automatically to the command line + args.push_back("-pthread"); args.push_back(lib_str); } diff --git a/t/fibonacci.t b/t/fibonacci.t @@ -50,7 +50,7 @@ my $inst_src_good = <<EOF; long long fibonacci(long long n) -{ +{needs_to_link_against_libcitrun = 0; if ((++_citrun_lines[7], n == 0)) return (++_citrun_lines[8], 0); else if ((++_citrun_lines[9], n == 1)) @@ -61,7 +61,7 @@ fibonacci(long long n) int main(int argc, char *argv[]) -{ +{needs_to_link_against_libcitrun = 0; long long n; if ((++_citrun_lines[20], argc != 2)) { diff --git a/t/for.t b/t/for.t @@ -28,7 +28,7 @@ $project->compile(); my $inst_src_good = <<EOF; int main(void) -{ +{needs_to_link_against_libcitrun = 0; int i; for (i = 0; (++_citrun_lines[6], i < 19); i++) { diff --git a/t/hello_world.t b/t/hello_world.t @@ -27,7 +27,7 @@ my $inst_src_good = <<EOF; int main(void) -{ +{needs_to_link_against_libcitrun = 0; (++_citrun_lines[6], printf("hello, world!")); return (++_citrun_lines[7], 0); } diff --git a/t/if.t b/t/if.t @@ -38,7 +38,7 @@ my $inst_src_good = <<EOF; int main(int argc, char *argv[]) -{ +{needs_to_link_against_libcitrun = 0; if ((++_citrun_lines[6], argc == 1)) return (++_citrun_lines[7], 1); else diff --git a/t/inst_preamble.t b/t/inst_preamble.t @@ -34,6 +34,7 @@ struct citrun_node { const char *file_name; }; +extern int needs_to_link_against_libcitrun; static uint64_t _citrun_lines[6]; struct citrun_node citrun_node_source_0 = { .lines_ptr = _citrun_lines, diff --git a/t/return.t b/t/return.t @@ -27,11 +27,11 @@ EOF $project->compile(); my $inst_src_good = <<EOF; -int foo() { +int foo() {needs_to_link_against_libcitrun = 0; return (++_citrun_lines[2], 0); } -int main(void) { +int main(void) {needs_to_link_against_libcitrun = 0; return (++_citrun_lines[6], 10); return (++_citrun_lines[8], 10 + 10); diff --git a/t/switch.t b/t/switch.t @@ -32,7 +32,7 @@ $project->compile(); my $inst_src_good = <<EOF; int main(void) -{ +{needs_to_link_against_libcitrun = 0; int i; switch ((++_citrun_lines[6], i)) { diff --git a/t/while.t b/t/while.t @@ -30,7 +30,7 @@ $project->compile(); my $inst_src_good = <<EOF; int main(void) -{ +{needs_to_link_against_libcitrun = 0; int i; i = 0;