commit e345b2c0c83f618033c4821fc853f8269505b056
parent bd4f2ed2015c10f06eac77434383d22273da7b06
Author: kyle <kyle@getaddrinfo.net>
Date: Wed, 9 Mar 2016 19:38:45 -0700
start using newly minted tu chaining instrumentation
- now we instrument every primary source file with a node for itself that is
linked to the next primary source file
- sometimes another primary source file comes along and replaces the previous
definition of its own node with the real deal
- if no next source file is processed then the application happily links because
theres no unresolved dependencies
Diffstat:
7 files changed, 113 insertions(+), 50 deletions(-)
diff --git a/SCV/Project.pm b/SCV/Project.pm
@@ -12,25 +12,33 @@ sub new {
# Make new temporary directory, clean it up at exit
$self->{tmp_dir} = tempdir( CLEANUP => 1 );
+ $self->{src_files} = [];
return $self;
}
sub add_src {
my ($self, $source) = @_;
+ my $num_src_files = scalar(@{ $self->{src_files} });
+
+ # Create temporary file name
+ my $src_name = "source_$num_src_files.c";
# Write source code to temp directory
- open( my $src_fh, ">", "$self->{tmp_dir}/source.c" );
+ open( my $src_fh, ">", "$self->{tmp_dir}/$src_name" );
syswrite( $src_fh, $source );
close( $src_fh );
+
+ push @{ $self->{src_files} }, $src_name;
}
sub compile {
my ($self) = @_;
my $tmp_dir = $self->{tmp_dir};
+ my $src_files = join(" ", @{ $self->{src_files} });
my $makefile = <<EOF;
BIN = program
-SRCS = source.c
+SRCS = $src_files
OBJS = \$(SRCS:c=o)
\$(BIN): \$(OBJS)
@@ -46,9 +54,9 @@ EOF
$ENV{PATH} = "$ENV{SCV_PATH}:$ENV{PATH}";
# Link in the runtime
- $ENV{CFLAGS} = "-pthread";
- # $ENV{LDLIBS} = "-Lruntime -lruntime -pthread";
- # $ENV{LD_LIBRARY_PATH} = "runtime";
+ $ENV{CFLAGS} = "-pthread -I/home/kyle/src/scv/include";
+ $ENV{LDLIBS} = "-L/home/kyle/src/scv/runtime -lruntime -pthread";
+ $ENV{LD_LIBRARY_PATH} = "runtime";
my $ret = system( "make -C $tmp_dir" );
die "make failed: $ret\n" if ($ret);
@@ -57,7 +65,7 @@ EOF
sub instrumented_src {
my ($self) = @_;
- open( my $inst_fh, "<", "$self->{tmp_dir}/inst/source.c" );
+ open( my $inst_fh, "<", "$self->{tmp_dir}/inst/source_0.c" );
my $inst_src;
while (my $line = <$inst_fh>) {
$inst_src .= $line;
diff --git a/include/scv_global.h b/include/scv_global.h
@@ -0,0 +1,7 @@
+struct scv_node {
+ unsigned int *lines_ptr;
+ unsigned int size;
+ const char *file_name;
+ struct scv_node *next;
+ /* unsigned int not_end; */
+};
diff --git a/instrument/instrumenter.cpp b/instrument/instrumenter.cpp
@@ -134,16 +134,9 @@ get_src_number()
std::string src_number_filename(cwd);
src_number_filename.append("/SRC_NUMBER");
- std::cerr << "src num file is " << src_number_filename << std::endl;
-
std::fstream src_number_file;
-
if (access(src_number_filename.c_str(), F_OK) == -1) {
- // SRC_NUMBER does not exist
- std::cerr << "SRC_NUMBER does not exist" << std::endl;
- std::cerr << "creating with contents '0'" << std::endl;
-
- // Create SRC_NUMBER
+ // SRC_NUMBER does not exist, create it
src_number_file.open(src_number_filename, std::fstream::out);
src_number_file << 0;
src_number_file.close();
@@ -157,9 +150,7 @@ get_src_number()
unsigned int src_num = 0;
src_number_file >> src_num;
-
++src_num;
- std::cerr << "src num is " << src_num << std::endl;
// Write the new source number
src_number_file.seekg(0);
@@ -180,30 +171,26 @@ MyFrontendAction::EndSourceFileAction()
SourceLocation start = sm.getLocForStartOfFile(main_fid);
std::string file_name = getCurrentFile();
- unsigned int src_number = get_src_number();
+ unsigned int tu_number = get_src_number();
std::stringstream ss;
// Add declarations for coverage buffers
int file_bytes = sm.getFileIDSize(main_fid);
ss << "#include <scv_global.h>" << std::endl;
+ // Define storage for coverage data
ss << "static unsigned int lines[" << file_bytes << "];" << std::endl;
- if (src_number != 0) {
- unsigned int prev_src_number = src_number - 1;
- ss << "extern struct scv_node node" << prev_src_number << ";" << std::endl;
- }
+ // Always declare this. The next TU will overwrite this or there won't
+ // be a next TU.
+ ss << "struct scv_node node" << tu_number + 1 << ";" << std::endl;
- ss << "struct scv_node node" << src_number << " = {" << std::endl
+ // Define this translation units main book keeping data structure
+ ss << "struct scv_node node" << tu_number << " = {" << std::endl
<< " .lines_ptr = lines," << std::endl
<< " .size = " << file_bytes << "," << std::endl
<< " .file_name = \"" << file_name << "\"," << std::endl;
- if (src_number != 0) {
- unsigned int prev_src_number = src_number - 1;
- ss << " .next = &node" << prev_src_number << "," << std::endl;
- } else {
- ss << " .next = 0," << std::endl;
- }
+ ss << " .next = &node" << tu_number + 1 << "," << std::endl;
ss << "};" << std::endl;
TheRewriter.InsertTextAfter(start, ss.str());
diff --git a/runtime/Makefile b/runtime/Makefile
@@ -2,7 +2,7 @@
error_SCV_PATH
.endif
-CFLAGS += -fPIC -pthread
+CFLAGS += -fPIC -pthread -I../include
LIB = libruntime.so
SRCS = runtime.c
OBJS = $(SRCS:c=o)
diff --git a/runtime/libruntime.so b/runtime/libruntime.so
Binary files differ.
diff --git a/runtime/runtime.c b/runtime/runtime.c
@@ -5,19 +5,36 @@
#include <sys/socket.h> // AF_UNIX
#include <sys/un.h> // sockaddr_un
+#include <scv_global.h>
-/* guaranteed to exist at link time because of instrumentation */
-extern unsigned int lines[];
-extern int size;
-extern const char file_name[];
+/* Entry point into an instrumented application */
+extern struct scv_node node0;
+
+void *
+walk_nodes(void *arg)
+{
+ int i;
+
+ printf("%s: alive", __func__);
+
+ struct scv_node *temp = &node0;
+ while (temp) {
+ printf("filename = %s\n", temp->file_name);
+ printf("size = %u\n", temp->size);
+ for (i = 0; i < temp->size; i++) {
+ printf(" ln %i = %u\n", i, temp->lines_ptr[i]);
+ }
+ temp = temp->next;
+ }
+
+ printf("%s: done", __func__);
+}
void *
control_thread(void *arg)
{
int fd;
- int i, set;
-
- printf("%s: file '%s' (%i bytes)\n", __func__, file_name, size);
+ int i;
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
@@ -28,22 +45,12 @@ control_thread(void *arg)
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, "socket", sizeof(addr.sun_path) - 1);
- printf("%s: initialized\n", __func__);
+ return;
+ // fprintf(stderr, "%s: initialized\n", __func__);
while (1) {
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)))
- warn("connect");
-
- set = 0;
- for (i = 0; i < size; i++)
- if (lines[i] == 1) {
- set++;
- lines[i] = 0;
- }
-
- printf("%i lines set\n", set);
-
- sleep(1);
+ err(1, "connect");
}
}
@@ -51,6 +58,5 @@ __attribute__((constructor))
static void runtime_init()
{
pthread_t tid;
-
pthread_create(&tid, NULL, control_thread, NULL);
}
diff --git a/t/multiple_sources.t b/t/multiple_sources.t
@@ -0,0 +1,55 @@
+use strict;
+use SCV::Project;
+use Test::More tests => 2;
+use Test::Differences;
+
+my $project = SCV::Project->new();
+unified_diff;
+
+$project->add_src(<<EOF
+void second_func();
+
+int
+main(void)
+{
+ second_func();
+ return 0;
+}
+EOF
+);
+
+$project->add_src(<<EOF
+void third_func();
+
+void
+second_func(void)
+{
+ third_func();
+ return;
+}
+EOF
+);
+
+$project->add_src(<<EOF
+void
+third_func(void)
+{
+ return;
+}
+EOF
+);
+
+$project->compile();
+
+my $tmp_dir = $project->get_tmpdir();
+
+my $inst_src_good = <<EOF;
+EOF
+
+my $inst_src = $project->instrumented_src();
+ok( $inst_src );
+
+#eq_or_diff $inst_src, $inst_src_good, "instrumented source comparison";
+
+my ($ret, $err) = $project->run();
+is($ret, 0, "instrumented program check return code");