[compiler-rt] r263157 - Retrieve command line arguments and environment correctly on FreeBSD

Dimitry Andric via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 10 12:22:02 PST 2016


Author: dim
Date: Thu Mar 10 14:22:02 2016
New Revision: 263157

URL: http://llvm.org/viewvc/llvm-project?rev=263157&view=rev
Log:
Retrieve command line arguments and environment correctly on FreeBSD

Summary:
Recently I saw the test `TestCases/Posix/print_cmdline.cc` failing on
FreeBSD, with "expected string not found in input".  This is because
asan could not retrieve the command line arguments properly.

In `lib/sanitizer_common/sanitizer_linux.cc`, this is taken care of by
the `GetArgsAndEnv()` function, but it uses `__libc_stack_end` to get at
the required data.  This variable does not exist on BSDs; the regular
way to retrieve the arguments and environment information is via the
`kern.ps_strings` sysctl.

I added this functionality in sanitizer_linux.cc, as a separate #ifdef
block in `GetArgsAndEnv()`.  Also, `ReadNullSepFileToArray()` becomes
unused due to this change.  (It won't work on FreeBSD anyway, since
`/proc` is not mounted by default.)

Reviewers: kcc, emaste, joerg, davide

Subscribers: llvm-commits, emaste

Differential Revision: http://reviews.llvm.org/D17832

Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=263157&r1=263156&r2=263157&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Thu Mar 10 14:22:02 2016
@@ -60,7 +60,10 @@
 #include <unistd.h>
 
 #if SANITIZER_FREEBSD
+#include <sys/exec.h>
 #include <sys/sysctl.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
 #include <machine/atomic.h>
 extern "C" {
 // <sys/umtx.h> must be included after <errno.h> and <sys/types.h> on
@@ -395,11 +398,13 @@ const char *GetEnv(const char *name) {
 #endif
 }
 
+#if !SANITIZER_FREEBSD
 extern "C" {
   SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
 }
+#endif
 
-#if !SANITIZER_GO
+#if !SANITIZER_GO && !SANITIZER_FREEBSD
 static void ReadNullSepFileToArray(const char *path, char ***arr,
                                    int arr_size) {
   char *buff;
@@ -425,6 +430,7 @@ static void ReadNullSepFileToArray(const
 #endif
 
 static void GetArgsAndEnv(char ***argv, char ***envp) {
+#if !SANITIZER_FREEBSD
 #if !SANITIZER_GO
   if (&__libc_stack_end) {
 #endif
@@ -439,6 +445,18 @@ static void GetArgsAndEnv(char ***argv,
     ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
   }
 #endif
+#else
+  // On FreeBSD, retrieving the argument and environment arrays is done via the
+  // kern.ps_strings sysctl, which returns a pointer to a structure containing
+  // this information.  If the sysctl is not available, a "hardcoded" address,
+  // PS_STRINGS, must be used instead.  See also <sys/exec.h>.
+  ps_strings *pss;
+  size_t sz = sizeof(pss);
+  if (sysctlbyname("kern.ps_strings", &pss, &sz, NULL, 0) == -1)
+    pss = (ps_strings*)PS_STRINGS;
+  *argv = pss->ps_argvstr;
+  *envp = pss->ps_envstr;
+#endif
 }
 
 char **GetArgv() {




More information about the llvm-commits mailing list