citrun

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

commit 0c75b9d346acc34433ad8623688f83446986fda9
parent 9da0d37c3f96b504e39ece3e25a7c3ce3b3bd8f8
Author: Kyle Milz <kyle@getaddrinfo.net>
Date:   Sun, 20 Mar 2016 22:24:04 -0600

lib: send back pid, ppid, and pgrp

- the viewer will use these to group relevant processes together

Diffstat:
MSCV/Viewer.pm | 19++++++++++++++-----
Mlib/runtime.c | 16++++++++++++++--
Mt/runtime_counters_increase.t | 12++++++------
At/runtime_metadata.t | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Mt/runtime_sanity.t | 7++++---
5 files changed, 88 insertions(+), 16 deletions(-)

diff --git a/SCV/Viewer.pm b/SCV/Viewer.pm @@ -35,6 +35,16 @@ sub get_metadata { my $buf = read_all($client, 8); my $num_tus = unpack("Q", $buf); + # Next is the 3 4 byte pid_t's + $buf = read_all($client, 12); + my ($pid, $ppid, $pgrp) = unpack("L3", $buf); + + my $runtime_metadata = { + pid => $pid, + ppid => $ppid, + pgrp => $pgrp, + }; + my @tus; for (1..$num_tus) { my $buf = read_all($client, 8); @@ -47,18 +57,17 @@ sub get_metadata { push @tus, { filename => $file_name, lines => $num_lines }; } + $runtime_metadata->{tus} = \@tus; - $self->{tus} = \@tus; - return \@tus; + return $runtime_metadata; } sub get_execution_data { - my ($self) = @_; + my ($self, $tus) = @_; my $client = $self->{client_socket}; - my @tus = @{ $self->{tus} }; my @data; - for (@tus) { + for (@$tus) { my $num_lines = $_->{lines}; my $buf = read_all($client, 8 * $num_lines); diff --git a/lib/runtime.c b/lib/runtime.c @@ -1,3 +1,4 @@ +#include <assert.h> #include <err.h> #include <limits.h> // PATH_MAX #include <pthread.h> @@ -9,7 +10,7 @@ #include <sys/types.h> // read #include <sys/uio.h> // read #endif -#include <unistd.h> // read +#include <unistd.h> // read, getpid, getppid, getpgrp #include "scv_runtime.h" @@ -69,14 +70,25 @@ send_metadata(int fd) uint64_t num_tus = 0; struct scv_node walk = node0; + /* Send the total number of translation unit records we'll send later */ while (walk.size != 0) { ++num_tus; walk = *walk.next; } - xwrite(fd, &num_tus, sizeof(num_tus)); + /* Send process id, parent process id and group process id. */ + pid_t process_id = getpid(); + pid_t parent_process_id = getppid(); + pid_t process_group = getpgrp(); + + assert(sizeof(pid_t) == 4); + xwrite(fd, &process_id, sizeof(pid_t)); + xwrite(fd, &parent_process_id, sizeof(pid_t)); + xwrite(fd, &process_group, sizeof(pid_t)); + walk = node0; + /* Send translation unit records */ while (walk.size != 0) { /* Send file name size and then the file name itself. */ file_name_sz = strnlen(walk.file_name, PATH_MAX); diff --git a/t/runtime_counters_increase.t b/t/runtime_counters_increase.t @@ -1,7 +1,7 @@ use strict; use SCV::Project; use SCV::Viewer; -use Test::More tests => 15; +use Test::More tests => 14; use Test::Differences; my $project = SCV::Project->new(); @@ -46,17 +46,17 @@ $project->run(45); # Accept the runtime's connection $viewer->accept(); -my $metadata = $viewer->get_metadata(); -is( scalar(@{ $metadata }), 1, "runtime check for a single tu" ); +my $runtime_metadata = $viewer->get_metadata(); +my $tus = $runtime_metadata->{tus}; -my $source_0 = $metadata->[0]; +my $source_0 = $tus->[0]; like ($source_0->{filename}, qr/.*source_0\.c/, "runtime filename check"); is( $source_0->{lines}, 28, "runtime lines count" ); -my $data = $viewer->get_execution_data(); +my $data = $viewer->get_execution_data($tus); my @exec_lines1 = @{ $data->[0] }; -my $data = $viewer->get_execution_data(); +my $data = $viewer->get_execution_data($tus); my @exec_lines2 = @{ $data->[0] }; # Only lines 8 - 12 in the source code above are executing diff --git a/t/runtime_metadata.t b/t/runtime_metadata.t @@ -0,0 +1,50 @@ +use strict; +use SCV::Project; +use SCV::Viewer; +use Test::More tests => 11; + +my $viewer = SCV::Viewer->new(); +my $project = SCV::Project->new(); + +$project->add_src(<<EOF +int +main(void) +{ + /* Just do something so we can probe the runtime reliably */ + while (1); + return 0; +} +EOF +); + +$project->compile(); +$project->run(); + +$viewer->accept(); + +# Request and check metadata first +my $runtime_metadata = $viewer->get_metadata(); + +my $pid = $runtime_metadata->{pid}; +my $ppid = $runtime_metadata->{ppid}; +my $pgrp = $runtime_metadata->{pgrp}; + +cmp_ok( $pid, ">", 1, "pid is positive" ); +cmp_ok( $ppid, ">", 1, "ppid is positive" ); +cmp_ok( $pgrp, ">", 1, "pgrp is positive" ); + +cmp_ok( $pid, "<", 100 * 1000, "pid is a reasonable value" ); +cmp_ok( $ppid, "<", 100 * 1000, "ppid is a reasonable value" ); +cmp_ok( $pgrp, "<", 100 * 1000, "pgrp is a reasonable value" ); + +my $tus = $runtime_metadata->{tus}; +is ( scalar(@$tus), 1, "translation unit count" ); +my $tu = $tus->[0]; + +like( $tu->{filename}, qr/.*source_0.c/, "filename check" ); +is( $tu->{lines}, 8, "line count check" ); + +$project->kill(); +my ($ret, $err) = $project->wait(); +is( $ret, 0, "instrumented program check return code" ); +is( $err, undef, "instrumented program check stderr" ); diff --git a/t/runtime_sanity.t b/t/runtime_sanity.t @@ -64,9 +64,10 @@ $project->run(45); $viewer->accept(); # Request and check metadata first -my $metadata = $viewer->get_metadata(); +my $runtime_metadata = $viewer->get_metadata(); +my $tus = $runtime_metadata->{tus}; -my ($source_0, $source_1, $source_2) = @{ $metadata }; +my ($source_0, $source_1, $source_2) = @$tus; like ($source_0->{filename}, qr/.*source_0.c/, "runtime filename check 0") ; is ($source_0->{lines}, 20, "runtime line count check 0"); like ($source_1->{filename}, qr/.*source_1.c/, "runtime filename check 1") ; @@ -75,7 +76,7 @@ like ($source_2->{filename}, qr/.*source_2.c/, "runtime filename check 2") ; is ($source_2->{lines}, 9, "runtime line count check 2"); # Request and check execution data -my $data = $viewer->get_execution_data(); +my $data = $viewer->get_execution_data($tus); my @lines = @{ $data->[0] }; is ( $lines[$_], 0, "src 0 line $_ check" ) for (1..11);