Newer Solaris has added /proc/self/cmdline and /proc/<pid>/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
This commit is contained in:
Ivo Raisr 2015-08-14 20:50:11 +00:00
parent 8c3ef7eb80
commit b66705c636
8 changed files with 91 additions and 11 deletions

View File

@ -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/<pid>/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)

View File

@ -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/<pid>/cmdline only on Linux. */
#if defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE)
/* Fake /proc/<pid>/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/<pid>/auxv on both Linux and Solaris. */
VG_(debugLog)(1, "main", "Create fake /proc/<pid>/auxv\n");

View File

@ -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/<pid>/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 =

View File

@ -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

View File

@ -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 \

View File

@ -0,0 +1,10 @@
/proc/self/cmdline:
./../procfs-cmdline-exe\0arg1\0arg 2\0arg3\0
/proc/<pid>/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

View File

@ -0,0 +1,10 @@
/proc/self/cmdline:
open(): No such file or directory
/proc/<pid>/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

View File

@ -0,0 +1,3 @@
prog: ../procfs-cmdline-exe
args: arg1 "arg 2" arg3
stderr_filter: filter_stderr