369000 AMD64 fma4 instructions unsupported.
361253 [s390x] ex_clone.c:42: undefined reference to `pthread_create'
369169 ppc64 fails jm_int_isa_2_07 test
+369209 valgrind loops and eats up all memory if cwd doesn't exist.
n-i-bz Fix incorrect (or infinite loop) unwind on RHEL7 x86 and amd64
n-i-bz massif --pages-as-heap=yes does not report peak caused by mmap+munmap
// Don't read ./.valgrindrc if "." is the same as "$HOME", else its
// contents will be applied twice. (bug #142488)
+ // Also don't try to read it if there is no cwd.
if (home) {
const HChar *cwd = VG_(get_startup_wd)();
- f2_clo = ( VG_STREQ(home, cwd)
+ f2_clo = ( (cwd == NULL || VG_STREQ(home, cwd))
? NULL : read_dot_valgrindrc(".") );
}
Hence VG_(record_startup_wd) notes it (in a platform dependent way)
and VG_(get_startup_wd) produces the noted value. */
static HChar *startup_wd;
-static Bool startup_wd_acquired = False;
/* Record the process' working directory at startup. Is intended to
be called exactly once, at startup, before the working directory
- changes. Return True for success, False for failure, so that the
- caller can bomb out suitably without creating module cycles if
- there is a problem. */
-Bool VG_(record_startup_wd) ( void )
+ changes. */
+void VG_(record_startup_wd) ( void )
{
- vg_assert(!startup_wd_acquired);
# if defined(VGO_linux) || defined(VGO_solaris)
/* Simple: just ask the kernel */
SysRes res;
startup_wd = VG_(realloc)("startup_wd", startup_wd, szB);
VG_(memset)(startup_wd, 0, szB);
res = VG_(do_syscall2)(__NR_getcwd, (UWord)startup_wd, szB-1);
- } while (sr_isError(res));
+ } while (sr_isError(res) && sr_Err(res) == VKI_ERANGE);
+
+ if (sr_isError(res)) {
+ VG_(free)(startup_wd);
+ startup_wd = NULL;
+ return;
+ }
vg_assert(startup_wd[szB-1] == 0);
- startup_wd_acquired = True;
- return True;
# elif defined(VGO_darwin)
/* We can't ask the kernel, so instead rely on launcher-*.c to
(Int)VG_(getppid)());
wd = VG_(getenv)( envvar );
if (wd == NULL)
- return False;
+ return;
SizeT need = VG_(strlen)(wd) + 1;
startup_wd = VG_(malloc)("startup_wd", need);
VG_(strcpy)(startup_wd, wd);
- startup_wd_acquired = True;
- return True;
}
# else
# error Unknown OS
# endif
}
-/* Return the previously acquired startup_wd. */
+/* Return the previously acquired startup_wd or NULL. */
const HChar *VG_(get_startup_wd) ( void )
{
- vg_assert(startup_wd_acquired);
-
return startup_wd;
}
// Record the working directory at startup
// p: none
VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
- { Bool ok = VG_(record_startup_wd)();
- if (!ok)
- VG_(err_config_error)( "Can't establish current working "
- "directory at startup\n");
- }
- VG_(debugLog)(1, "main", "... %s\n", VG_(get_startup_wd)() );
+ VG_(record_startup_wd)();
+ const HChar *wd = VG_(get_startup_wd)();
+ VG_(debugLog)(1, "main", "... %s\n", wd != NULL ? wd : "<NO CWD>" );
//============================================================
// Command line argument handling order:
// If 'out' is not an absolute path name, prefix it with the startup dir.
if (out[0] != '/') {
+ if (base_dir == NULL) {
+ message = "Current working dir doesn't exist, use absolute path\n";
+ goto bad;
+ }
len = VG_(strlen)(base_dir) + 1 + VG_(strlen)(out) + 1;
HChar *absout = VG_(malloc)("options.efn.4", len);
/* Record the process' working directory at startup. Is intended to
be called exactly once, at startup, before the working directory
- changes. Return True for success, False for failure, so that the
- caller can bomb out suitably without creating module cycles if
- there is a problem. The saved value can later be acquired by
- calling VG_(get_startup_wd) (in pub_tool_libcfile.h). */
-extern Bool VG_(record_startup_wd) ( void );
+ changes. The saved value can later be acquired by calling
+ VG_(get_startup_wd) (in pub_tool_libcfile.h). Note that might
+ return if the working directory couldn't be found. */
+extern void VG_(record_startup_wd) ( void );
#endif // __PUB_CORE_LIBCFILE_H
#include "pub_tool_basics.h"
#include "pub_tool_libcassert.h" /* tl_assert() */
#include "pub_tool_libcbase.h" /* strlen() */
-#include "pub_tool_libcfile.h" /* VG_(get_startup_wd)() */
#include "pub_tool_libcprint.h" /* VG_(printf)() */
#include "pub_tool_machine.h"
#include "pub_tool_mallocfree.h" /* VG_(malloc), VG_(free) */
extern const HChar* VG_(tmpdir)(void);
/* Return the working directory at startup. The returned string is
- persistent. */
+ persistent. Might be NULL if the current working directory doesn't
+ exist. */
extern const HChar *VG_(get_startup_wd) ( void );
#endif // __PUB_TOOL_LIBCFILE_H
mq.stderr.exp mq.vgtest \
munmap_exe.stderr.exp munmap_exe.vgtest \
nestedfns.stderr.exp nestedfns.stdout.exp nestedfns.vgtest \
+ nocwd.stdout.exp nocwd.stderr.exp nocwd.vgtest \
nodir.stderr.exp nodir.vgtest \
pending.stdout.exp pending.stderr.exp pending.vgtest \
ppoll_alarm.stdout.exp ppoll_alarm.stderr.exp ppoll_alarm.vgtest \
manythreads \
mmap_fcntl_bug \
munmap_exe map_unaligned map_unmap mq \
+ nocwd \
pending \
procfs-cmdline-exe \
pselect_alarm \
--- /dev/null
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+int
+main (int argc, char **argv)
+{
+ char template[] = "/tmp/wd_test_XXXXXX";
+ char *tmpdir = mkdtemp(template);
+ if (tmpdir == NULL)
+ {
+ perror ("Couldn't mkdtemp");
+ exit (-1);
+ }
+
+ if (chdir (tmpdir) != 0)
+ {
+ perror ("Couldn't chdir into tmpdir");
+ exit (-1);
+ }
+
+ /* Go deep. */
+ int dirslen = PATH_MAX;
+ while (dirslen > 0)
+ {
+ /* We don't do any error checking in case some OS fails. */
+ mkdir ("subdir", S_IRWXU);
+ chdir ("subdir");
+ dirslen -= strlen ("subdir");
+ }
+
+ /* Make one component inaccessible. */
+ chmod(tmpdir, 0);
+
+ /* Remove the current dir (don't check error, might fail). */
+ rmdir ("../subdir");
+
+ execlp ("echo", "echo", "Hello", "World", (char *) NULL);
+ perror ("Couldn't execlp");
+ return -1;
+}
--- /dev/null
+Hello World
--- /dev/null
+prog: nocwd
+vgopts: -q --trace-children=yes