181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# This file is part of ltrace.
281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# Copyright (C) 2014 Petr Machata, Red Hat Inc.
381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# Copyright (C) 2006 Yao Qi <qiyao@cn.ibm.com>, IBM Corporation
481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata#
581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# This program is free software; you can redistribute it and/or
681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# modify it under the terms of the GNU General Public License as
781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# published by the Free Software Foundation; either version 2 of the
881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# License, or (at your option) any later version.
981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata#
1081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# This program is distributed in the hope that it will be useful, but
1181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# WITHOUT ANY WARRANTY; without even the implied warranty of
1281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# General Public License for more details.
1481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata#
1581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# You should have received a copy of the GNU General Public License
1681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# along with this program; if not, write to the Free Software
1781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
1881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# 02110-1301 USA
1998d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam
2081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# Objectives: Verify that Ltrace can trace all the system calls in
2181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# execution.  Note that this test is necessarily noisy.  Dynamic
2281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata# linker adds a bunch of system calls of its own.
2398d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam
2481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machataset empty [ltraceCompile {} [ltraceSource c {
2581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    int main (void) { return 0; }
2681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata}]]
2798d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam
2881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machataset bin [ltraceCompile {} [ltraceSource c {
2981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    #include <stdio.h>
3081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    #include <unistd.h>
3181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    #include <sys/syscall.h>
3281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    #include <sys/stat.h>
3381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    #include <errno.h>
3481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    #include <stdlib.h>
3581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata
3681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    int
3781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    main ()
3881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    {
3981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      FILE* fp;
4081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      char s[]="system_calls";
4181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      char buffer[1024];
4281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      struct stat state;
4381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata
4481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      fp = fopen ("system_calls.tmp", "w");
4581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      if (fp == NULL)
4681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	{
4781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	  printf("Can not create system_calls.tmp\n");
4881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	  exit (0);
4981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	}
5081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      fwrite(s, sizeof(s), 1, fp);
5181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      fseek (fp, 0, SEEK_CUR);
5281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      fread(buffer, sizeof(s), 1, fp);
5381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      fclose(fp);
5481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata
5581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      getcwd (buffer, sizeof buffer);
5681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      chdir (".");
5781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      symlink ("system_calls.tmp", "system_calls.link");
5881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      remove("system_calls.link");
5981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      rename ("system_calls.tmp", "system_calls.tmp1");
6081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      stat ("system_calls.tmp", &state);
6181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      access ("system_calls.tmp", R_OK);
6281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      remove("system_calls.tmp1");
6381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata
6481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      mkdir ("system_call_mkdir", 0777);
6581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      rmdir ("system_call_mkdir");
6681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata
6781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata      return 0;
6881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    }
6981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata}]]
7081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata
7181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machataproc Calls {logfile} {
7281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    set fp [open $logfile]
7381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    set ret {}
7481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata
7581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    while {[gets $fp line] >= 0} {
7681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	if [regexp -- {^[a-zA-Z0-9]*@SYS} $line] {
7781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	    set call [lindex [split $line @] 0]
7881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	    dict incr ret $call
7981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	}
8081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    }
8181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata
8281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    close $fp
8381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    return $ret
8481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata}
8581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata
8681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machataproc GetDefault {d key def} {
8781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    if {[dict exists $d $key]} {
8881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	return [dict get $d $key]
8981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    } else {
9081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	return $def
9181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    }
9298d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam}
9398d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam
9481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machataproc Diff {d1 d2} {
9581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    set keys [lsort -unique [concat [dict keys $d1] [dict keys $d2]]]
9681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    set ret {}
9781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    foreach key $keys {
9881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	set n1 [GetDefault $d1 $key 0]
9981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	set n2 [GetDefault $d2 $key 0]
10081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	set sum [expr $n1 - $n2]
10181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	if {[expr $sum != 0]} {
10281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata		dict set ret $key $sum
10381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	}
10481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    }
10581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    return $ret
10681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata}
10781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata
10881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machataproc Match {d patterns} {
10981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    foreach line $patterns {
11081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	set pattern [lindex $line 0]
11181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	set op [lindex $line 1]
11281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	set expect [lindex $line 2]
11398d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam
11481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	set count 0
11581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	foreach key [dict keys $d] {
11681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	    if [regexp -- $pattern $key] {
11781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata		incr count [dict get $d $key]
11881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	    }
11981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	}
12098d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam
12181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	set msgMain "$pattern was recorded $count times"
12298d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam
12381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	if {[eval expr $count $op $expect]} {
12481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	    pass $msgMain
12581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	} else {
12681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	    fail "$msgMain, expected $op $expect"
12781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	}
12881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    }
12998d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam}
13098d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam
13181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr MachataMatch [Diff [Calls [ltraceRun -L -S -- $bin]] \
13281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata	   [Calls [ltraceRun -L -S -- $empty]]] {
13381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^write$} == 1 }
13481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^unlink(at)?$} >= 2 }
13581efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^open(at)?$} == 1 }
13681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^(new|f)?stat(64)?$} == 1 }
13781efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^close$} == 1 }
13881efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^getcwd$} == 1 }
13981efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^chdir$} == 1 }
14081efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^symlink(at)?$} == 1 }
14181efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^f?access(at)?$} == 1 }
14281efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^rename(at)?$} == 1 }
14381efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata    { {^mkdir(at)?$} == 1 }
14481efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr Machata}
14598d884bfd78ea7a37f46515c6e9e3635a95d8cbcPaul Gilliam
14681efcb04cd4e84ffd2c6ab851a2a10360956bd15Petr MachataltraceDone
147