citrun

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

commit 79240861a80ea5a0d3a7eb14ee66a66955718210
parent 1cbcadace764312fcc0fc9c1e028e3b8843b7f83
Author: Kyle Milz <kyle@0x30.net>
Date:   Mon, 29 Aug 2016 20:32:28 -0600

t: convert exec totals to perl

Diffstat:
Dt/rt_exectotals.sh | 37-------------------------------------
At/rt_exectotals.t | 33+++++++++++++++++++++++++++++++++
Atest/shm.pm | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 120 insertions(+), 37 deletions(-)

diff --git a/t/rt_exectotals.sh b/t/rt_exectotals.sh @@ -1,37 +0,0 @@ -# -# Test that we can count an executing program as its running. -# -. test/utils.sh -plan 4 - -cat <<EOF > check_totals.cc -#include "src/process_dir.h" -#include "test/basic.h" - -#include <iostream> - -int -main(void) -{ - ProcessDir pdir; - pdir.scan(); - - ProcessFile f = pdir.m_procfiles[0]; - - for (int i = 0; i < 60; i++) - std::cout << f.total_execs() << std::endl; -} -EOF - -ok "tap program compile" clang++ -std=c++11 -c check_totals.cc \ - -I$CITRUN_TOOLS/.. -ok "tap program link" clang++ -o tap_program check_totals.o \ - $CITRUN_TOOLS/utils.a $CITRUN_TOOLS/../test/tap.a - -program 45 & -pid=$! - -ok "tap program run" tap_program - -kill $pid -wait diff --git a/t/rt_exectotals.t b/t/rt_exectotals.t @@ -0,0 +1,33 @@ +# +# Test that we can count an executing program as its running. +# +use strict; +use warnings; +use POSIX; +use Test::More tests => 100; +use Time::HiRes qw( usleep ); +use test::shm; + +my $child_pid = fork(); +if ($child_pid == 0) { + # Child. + exec ("test/program", "45"); +} + +sleep 1; +my $shm = test::shm->new(); + +my $last_total = 0; +for (0..99) { + usleep 10 * 1000; + my $total = 0; + + for (0..2) { + my $execs = $shm->execs_for($_); + $total += $_ for (@$execs); + } + cmp_ok $total, '>', $last_total, "new total > old total"; +} + +kill 'TERM', $child_pid; +wait; diff --git a/test/shm.pm b/test/shm.pm @@ -0,0 +1,87 @@ +package test::shm; +use strict; +use warnings; +use Cwd; +use POSIX; + +$ENV{CITRUN_TOOLS} = cwd . '/src'; + +sub new { + my ($class) = @_; + + my $self = {}; + bless($self, $class); + + open(my $fh, "<:mmap", "procfile.shm") or die $!; + $self->{fh} = $fh; + $self->{size} = (stat "procfile.shm")[7]; + + ($self->{major}, $self->{minor}) = unpack("C2", xread($fh, 2)); + @{ $self->{pids} } = unpack("L3", xread($fh, 12)); + + ($self->{prg_sz}) = unpack("S", xread($fh, 2)); + ($self->{progname}) = xread($fh, $self->{prg_sz}); + ($self->{cwd_sz}) = unpack("S", xread($fh, 2)); + ($self->{cwd}) = xread($fh, $self->{cwd_sz}); + $self->next_page(); + + my @translation_units; + while (tell $fh < $self->{size}) { + my %tu; + ($tu{size}) = unpack("L", xread($fh, 4)); + + ($tu{cmp_sz}) = unpack("S", xread($fh, 2)); + $tu{comp_file_name} = xread($fh, $tu{cmp_sz}); + ($tu{abs_sz}) = unpack("S", xread($fh, 2)); + $tu{abs_file_path} = xread($fh, $tu{abs_sz}); + + $tu{exec_buf_pos} = tell $fh; + xread($fh, $tu{size} * 8); + $self->next_page(); + + push @translation_units, (\%tu); + } + $self->{translation_units} = \@translation_units; + + return $self; +} + +sub next_page { + my ($self) = @_; + + my $pagesize = POSIX::sysconf(POSIX::_SC_PAGESIZE); + my $cur_pos = tell $self->{fh}; + xread($self->{fh}, $pagesize - ($cur_pos % $pagesize)); +} + +sub execs_for { + my ($self, $tu_num) = @_; + + my $tu = $self->{translation_units}->[$tu_num]; + seek $self->{fh}, $tu->{exec_buf_pos}, 0; + my @execs = unpack("Q$tu->{size}", xread($self->{fh}, $tu->{size} * 8)); + return \@execs; +} + +# +# Read an exact amount of bytes. +# +sub xread { + my ($fh, $bytes_total) = @_; + + my $data; + my $bytes_read = 0; + while ($bytes_total > 0) { + my $read = read($fh, $data, $bytes_total, $bytes_read); + + die "error: read failed: $!" if (!defined $read); + die "disconnected!\n" if ($read == 0); + + $bytes_total -= $read; + $bytes_read += $read; + } + + return $data; +} + +1;