From 908594dfe1364208bcb988d9463e668938d2fccc Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 26 Aug 2009 18:11:18 +0000 Subject: [PATCH] Added regression tests that verify the following behavior: - On Linux, whether Valgrind properly intercepts the system calls that access /proc/self/cmdline, /proc//cmdline, /proc/self/exe and /proc//exe. - On Darwin, whether Valgrind does not modify the behavior of the system calls that access the aforementioned files. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10871 --- configure.in | 1 + none/tests/Makefile.am | 3 + none/tests/procfs-cmdline-exe.c | 115 +++++++++++++++++++++++++ none/tests/procfs-linux.stderr.exp | 10 +++ none/tests/procfs-linux.vgtest | 4 + none/tests/procfs-non-linux.stderr.exp | 10 +++ none/tests/procfs-non-linux.vgtest | 3 + 7 files changed, 146 insertions(+) create mode 100644 none/tests/procfs-cmdline-exe.c create mode 100644 none/tests/procfs-linux.stderr.exp create mode 100644 none/tests/procfs-linux.vgtest create mode 100644 none/tests/procfs-non-linux.stderr.exp create mode 100644 none/tests/procfs-non-linux.vgtest diff --git a/configure.in b/configure.in index bd3df63e38..fd5a4b57fc 100644 --- a/configure.in +++ b/configure.in @@ -1526,6 +1526,7 @@ AC_CHECK_FUNCS([ \ pthread_rwlock_timedrdlock \ pthread_rwlock_timedwrlock \ pthread_spin_lock \ + readlinkat \ semtimedop \ signalfd \ sigwaitinfo \ diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am index 154d4e1cd6..4b8cd27080 100644 --- a/none/tests/Makefile.am +++ b/none/tests/Makefile.am @@ -88,6 +88,8 @@ EXTRA_DIST = \ munmap_exe.stderr.exp munmap_exe.vgtest \ nestedfns.stderr.exp nestedfns.stdout.exp nestedfns.vgtest \ pending.stdout.exp pending.stderr.exp pending.vgtest \ + procfs-linux.stderr.exp procfs-linux.vgtest \ + procfs-non-linux.stderr.exp procfs-non-linux.vgtest \ pth_atfork1.stderr.exp pth_atfork1.stdout.exp pth_atfork1.vgtest \ pth_blockedsig.stderr.exp \ pth_blockedsig.stdout.exp pth_blockedsig.vgtest \ @@ -155,6 +157,7 @@ check_PROGRAMS = \ munmap_exe map_unaligned map_unmap mq \ nestedfns \ pending \ + procfs-cmdline-exe \ pth_atfork1 pth_blockedsig pth_cancel1 pth_cancel2 pth_cvsimple \ pth_empty pth_exit pth_exit2 pth_mutexspeed pth_once pth_rwlock \ pth_stackalign \ diff --git a/none/tests/procfs-cmdline-exe.c b/none/tests/procfs-cmdline-exe.c new file mode 100644 index 0000000000..9f550e5b7d --- /dev/null +++ b/none/tests/procfs-cmdline-exe.c @@ -0,0 +1,115 @@ +/* + * Read /proc/self/cmdline and /proc/self/exe such that it can be tested + * whether Valgrind intercepts the system calls that access these pseudo-files + * properly on Linux and whether Valgrind does not modify the behavior of + * accessing these files on other operating systems. + */ + +#define _ATFILE_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../config.h" + +static void test_cmdline(const char* const cwd, const char* const label, + const char* const path) +{ + int fd, n; + char ch; + + fprintf(stderr, "%s:\n", label); + fd = open(path, 0); + if (fd >= 0) + { + while ((n = read(fd, &ch, 1)) > 0) + { + if (ch == '\\') + fprintf(stderr, "\\\\"); + else if (ch == 0) + fprintf(stderr, "\\0"); + else if (isprint((unsigned)ch)) + fprintf(stderr, "%c", ch); + else + fprintf(stderr, "\\0%o", ch); + } + fprintf(stderr, "\n"); + close(fd); + } + else + perror("open()"); +} + +static void test_readlink(const char* const cwd, const char* const label, + const char* const path) +{ + char buf[512]; + const char* p; + int n; + + if ((n = readlink(path, buf, sizeof(buf) - 1)) >= 0) + { + buf[n] = 0; + p = buf; + if (strncmp(buf, cwd, strlen(cwd)) == 0) + p += strlen(cwd); + fprintf(stderr, "Result of readlink(\"%s\"): %s\n", label, p); + } + else + perror("readlink"); +} + +static void test_readlinkat(const char* const cwd, const char* const label, + const char* const path) +{ +#if HAVE_READLINKAT + char buf[512]; + const char* p; + int n; + + if ((n = readlinkat(AT_FDCWD, path, buf, sizeof(buf) - 1)) >= 0) + { + buf[n] = 0; + p = buf; + if (strncmp(buf, cwd, strlen(cwd)) == 0) + p += strlen(cwd); + fprintf(stderr, "Result of readlinkat(\"%s\"): %s\n", label, p); + } + else + perror("readlinkat"); +#else + errno = ENOSYS; + perror("readlinkat"); +#endif +} + +int main(int argc, char** argv) +{ + char cwd[512]; + char path[512]; + + cwd[0] = 0; + if (! getcwd(cwd, sizeof(cwd))) + perror("getcwd"); + strcat(cwd, "/"); + + snprintf(path, sizeof(path), "/proc/%d/cmdline", getpid()); + + test_cmdline(cwd, "/proc/self/cmdline", "/proc/self/cmdline"); + test_cmdline(cwd, "/proc//cmdline", path); + + snprintf(path, sizeof(path), "/proc/%d/exe", getpid()); + + test_readlink(cwd, "/proc/self/exe", "/proc/self/exe"); + test_readlink(cwd, "/proc//exe", path); + + test_readlinkat(cwd, "/proc/self/exe", "/proc/self/exe"); + test_readlinkat(cwd, "/proc//exe", path); + + return 0; +} diff --git a/none/tests/procfs-linux.stderr.exp b/none/tests/procfs-linux.stderr.exp new file mode 100644 index 0000000000..6314262e62 --- /dev/null +++ b/none/tests/procfs-linux.stderr.exp @@ -0,0 +1,10 @@ + +/proc/self/cmdline: +./procfs-cmdline-exe\0arg1\0arg 2\0arg3\0 +/proc//cmdline: +./procfs-cmdline-exe\0arg1\0arg 2\0arg3\0 +Result of readlink("/proc/self/exe"): procfs-cmdline-exe +Result of readlink("/proc//exe"): procfs-cmdline-exe +Result of readlinkat("/proc/self/exe"): procfs-cmdline-exe +Result of readlinkat("/proc//exe"): procfs-cmdline-exe + diff --git a/none/tests/procfs-linux.vgtest b/none/tests/procfs-linux.vgtest new file mode 100644 index 0000000000..ea8a8e9518 --- /dev/null +++ b/none/tests/procfs-linux.vgtest @@ -0,0 +1,4 @@ +prereq: [ $(uname) = Linux ] +prog: procfs-cmdline-exe +args: arg1 "arg 2" arg3 +stderr_filter: filter_stderr diff --git a/none/tests/procfs-non-linux.stderr.exp b/none/tests/procfs-non-linux.stderr.exp new file mode 100644 index 0000000000..ec92dfaecb --- /dev/null +++ b/none/tests/procfs-non-linux.stderr.exp @@ -0,0 +1,10 @@ + +/proc/self/cmdline: +open(): No such file or directory +/proc//cmdline: +open(): No such file or directory +readlink: No such file or directory +readlink: No such file or directory +readlinkat: Function not implemented +readlinkat: Function not implemented + diff --git a/none/tests/procfs-non-linux.vgtest b/none/tests/procfs-non-linux.vgtest new file mode 100644 index 0000000000..61bf34934f --- /dev/null +++ b/none/tests/procfs-non-linux.vgtest @@ -0,0 +1,3 @@ +prereq: [ $(uname) != Linux ] +prog: procfs-cmdline-exe +stderr_filter: filter_stderr -- 2.47.2