From: Ivo Raisr Date: Fri, 14 Aug 2015 20:50:11 +0000 (+0000) Subject: Newer Solaris has added /proc/self/cmdline and /proc//cmdline. X-Git-Tag: svn/VALGRIND_3_11_0~112 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b66705c63638c6e98c46edf538aa782b2edc24f1;p=thirdparty%2Fvalgrind.git Newer Solaris has added /proc/self/cmdline and /proc//cmdline. Add support for it in the syswrap machinery and test it more thoroughly. n-i-bz git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15545 --- diff --git a/configure.ac b/configure.ac index d5111f7535..7189fa8fb1 100644 --- a/configure.ac +++ b/configure.ac @@ -2676,6 +2676,23 @@ AM_CONDITIONAL(SOLARIS_XPG_SYMBOLS_PRESENT, test x$solaris_xpg_symbols_present = CFLAGS="$save_CFLAGS" +# Solaris-specific check determining if /proc/self/cmdline +# or /proc//cmdline is supported. +# +# C-level symbol: SOLARIS_PROC_CMDLINE +# Automake-level symbol: SOLARIS_PROC_CMDLINE +# +AC_CHECK_FILE([/proc/self/cmdline], +[ +solaris_proc_cmdline=yes +AC_DEFINE([SOLARIS_PROC_CMDLINE], 1, + [Define to 1 if you have /proc/self/cmdline.]) +], [ +solaris_proc_cmdline=no +]) +AM_CONDITIONAL(SOLARIS_PROC_CMDLINE, test x$solaris_proc_cmdline = xyes) + + # Solaris-specific check determining default platform for the Valgrind launcher. # Used in case the launcher cannot select platform by looking at the client # image (for example because the executable is a shell script). @@ -3346,6 +3363,7 @@ AM_CONDITIONAL(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR, test x$solaris_reserve_sysstat else AM_CONDITIONAL(SOLARIS_SUN_STUDIO_AS, false) AM_CONDITIONAL(SOLARIS_XPG_SYMBOLS_PRESENT, false) +AM_CONDITIONAL(SOLARIS_PROC_CMDLINE, false) AM_CONDITIONAL(SOLARIS_OLD_SYSCALLS, false) AM_CONDITIONAL(SOLARIS_LWP_SIGQUEUE_SYSCALL, false) AM_CONDITIONAL(SOLARIS_LWP_SIGQUEUE_SYSCALL_TAKES_PID, false) diff --git a/coregrind/m_main.c b/coregrind/m_main.c index 0ce771c5bc..f745600bc6 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -1983,8 +1983,8 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) HChar buf2[VG_(mkstemp_fullname_bufsz)(sizeof buf - 1)]; Int fd, r; -#if defined(VGO_linux) - /* Fake /proc//cmdline only on Linux. */ +#if defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE) + /* Fake /proc//cmdline only on Linux and Solaris if supported. */ HChar nul[1]; const HChar* exename; @@ -2007,8 +2007,8 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) } /* Don't bother to seek the file back to the start; instead do - it every time a copy of it is given out (by PRE(sys_open)). - That is probably more robust across fork() etc. */ + it every time a copy of it is given out (by PRE(sys_open) or + PRE(sys_openat)). That is probably more robust across fork() etc. */ /* Now delete it, but hang on to the fd. */ r = VG_(unlink)( buf2 ); @@ -2016,7 +2016,7 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) VG_(err_config_error)("Can't delete client cmdline file in %s\n", buf2); VG_(cl_cmdline_fd) = fd; -#endif // defined(VGO_linux) +#endif // defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE) /* Fake /proc//auxv on both Linux and Solaris. */ VG_(debugLog)(1, "main", "Create fake /proc//auxv\n"); diff --git a/coregrind/m_syswrap/syswrap-solaris.c b/coregrind/m_syswrap/syswrap-solaris.c index cd6370db06..d1f010c9e0 100644 --- a/coregrind/m_syswrap/syswrap-solaris.c +++ b/coregrind/m_syswrap/syswrap-solaris.c @@ -1590,7 +1590,7 @@ static Bool handle_psinfo_open(SyscallStatus *status, if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/psinfo")) return False; - /* use original arguments to open or openat */ + /* Use original arguments to open() or openat(). */ SysRes sres; #if defined(SOLARIS_OLD_SYSCALLS) if (use_openat) @@ -1650,6 +1650,35 @@ static Bool handle_psinfo_open(SyscallStatus *status, return True; } +#if defined(SOLARIS_PROC_CMDLINE) +/* Handles the case where the open is of /proc/self/cmdline or + /proc//cmdline. Just give it a copy of VG_(cl_cmdline_fd) for the + fake file we cooked up at startup (in m_main). Also, seek the + cloned fd back to the start. */ +static Bool handle_cmdline_open(SyscallStatus *status, const HChar *filename) +{ + if (!ML_(safe_to_deref)((const void *) filename, 1)) + return False; + + HChar name[VKI_PATH_MAX]; // large enough + VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)()); + + if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/cmdline")) + return False; + + SysRes sres = VG_(dup)(VG_(cl_cmdline_fd)); + SET_STATUS_from_SysRes(sres); + if (!sr_isError(sres)) { + OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET); + if (off < 0) + SET_STATUS_Failure(VKI_EMFILE); + } + + return True; +} +#endif /* SOLARIS_PROC_CMDLINE */ + + #if defined(SOLARIS_OLD_SYSCALLS) PRE(sys_open) { @@ -3820,13 +3849,18 @@ PRE(sys_openat) return; } - if (ML_(handle_auxv_open)(status, (const HChar*)ARG2, ARG3)) + if (ML_(handle_auxv_open)(status, (const HChar *) ARG2, ARG3)) return; - if (handle_psinfo_open(status, True /*use_openat*/, (const HChar*)ARG2, + if (handle_psinfo_open(status, True /*use_openat*/, (const HChar *) ARG2, fd, ARG3, ARG4)) return; +#if defined(SOLARIS_PROC_CMDLINE) + if (handle_cmdline_open(status, (const HChar *) ARG2)) + return; +#endif /* SOLARIS_PROC_CMDLINE */ + *flags |= SfMayBlock; } @@ -7820,7 +7854,7 @@ static void repository_door_pre_mem_door_call_hook(ThreadId tid, Int fd, "entity_name->rpr_answertype)", r->rpr_answertype); } break; - #if (SOLARIS_REPCACHE_PROTOCOL_VERSION >= 25) +#if (SOLARIS_REPCACHE_PROTOCOL_VERSION >= 25) case VKI_REP_PROTOCOL_ENTITY_GET_ROOT: { struct vki_rep_protocol_entity_root *r = @@ -7831,7 +7865,7 @@ static void repository_door_pre_mem_door_call_hook(ThreadId tid, Int fd, "entity_root->rpr_outid)", r->rpr_outid); } break; - #endif /* SOLARIS_REPCACHE_PROTOCOL_VERSION >= 25 */ +#endif /* SOLARIS_REPCACHE_PROTOCOL_VERSION >= 25 */ case VKI_REP_PROTOCOL_ENTITY_GET: { struct vki_rep_protocol_entity_get *r = diff --git a/none/tests/procfs-non-linux.vgtest b/none/tests/procfs-non-linux.vgtest index 61bf34934f..8250b271ab 100644 --- a/none/tests/procfs-non-linux.vgtest +++ b/none/tests/procfs-non-linux.vgtest @@ -1,3 +1,6 @@ -prereq: [ $(uname) != Linux ] +# For Linux, there is 'procfs-linux'. +# For Solaris, there is Solaris-specific 'solaris/proc-cmdline-exe'. +# +prereq: ! ../../tests/os_test linux && ! ../../tests/os_test solaris prog: procfs-cmdline-exe stderr_filter: filter_stderr diff --git a/none/tests/solaris/Makefile.am b/none/tests/solaris/Makefile.am index 4506b46007..1860bf89d5 100644 --- a/none/tests/solaris/Makefile.am +++ b/none/tests/solaris/Makefile.am @@ -18,6 +18,8 @@ EXTRA_DIST = \ proc_aout.stderr.exp proc_aout.stdout.exp proc_aout.vgtest \ proc_auxv.stderr.exp proc_auxv.stdout.exp proc_auxv.vgtest \ proc_auxv_multiple.stderr.exp proc_auxv_multiple.stdout.exp proc_auxv_multiple.vgtest \ + proc-cmdline-exe.stderr.exp-with-cmdline proc-cmdline-exe.stderr.exp-without-cmdline \ + proc-cmdline-exe.vgtest \ proc_psinfo.stderr.exp proc_psinfo.stdout.exp proc_psinfo.vgtest \ posix_spawn.stderr.exp posix_spawn.stdout.exp posix_spawn.vgtest \ pthread-stack.stderr.exp pthread-stack.vgtest \ diff --git a/none/tests/solaris/proc-cmdline-exe.stderr.exp-with-cmdline b/none/tests/solaris/proc-cmdline-exe.stderr.exp-with-cmdline new file mode 100644 index 0000000000..6fd6f1301c --- /dev/null +++ b/none/tests/solaris/proc-cmdline-exe.stderr.exp-with-cmdline @@ -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 +readlink: No such file or directory +readlink: No such file or directory +readlinkat: No such file or directory +readlinkat: No such file or directory + diff --git a/none/tests/solaris/proc-cmdline-exe.stderr.exp-without-cmdline b/none/tests/solaris/proc-cmdline-exe.stderr.exp-without-cmdline new file mode 100644 index 0000000000..9d656f733e --- /dev/null +++ b/none/tests/solaris/proc-cmdline-exe.stderr.exp-without-cmdline @@ -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: No such file or directory +readlinkat: No such file or directory + diff --git a/none/tests/solaris/proc-cmdline-exe.vgtest b/none/tests/solaris/proc-cmdline-exe.vgtest new file mode 100644 index 0000000000..117dd9fb34 --- /dev/null +++ b/none/tests/solaris/proc-cmdline-exe.vgtest @@ -0,0 +1,3 @@ +prog: ../procfs-cmdline-exe +args: arg1 "arg 2" arg3 +stderr_filter: filter_stderr