Author: florian
Date: Wed Jul 30 14:24:10 2014
New Revision: 14210
Log:
Change VG_(readlink) and VG_(resolve_filename) to return pointer to
dynamically allocated string which will be overwritten with each
invocation. Fix call sites.
Modified:
branches/BUF_REMOVAL/coregrind/m_coredump/coredump-elf.c
branches/BUF_REMOVAL/coregrind/m_debuginfo/debuginfo.c
branches/BUF_REMOVAL/coregrind/m_libcfile.c
branches/BUF_REMOVAL/coregrind/m_syswrap/syswrap-generic.c
branches/BUF_REMOVAL/coregrind/pub_core_libcfile.h
branches/BUF_REMOVAL/include/pub_tool_libcfile.h
Modified: branches/BUF_REMOVAL/coregrind/m_coredump/coredump-elf.c
==============================================================================
--- branches/BUF_REMOVAL/coregrind/m_coredump/coredump-elf.c (original)
+++ branches/BUF_REMOVAL/coregrind/m_coredump/coredump-elf.c Wed Jul 30 14:24:10 2014
@@ -193,7 +193,7 @@
static void fill_prpsinfo(const ThreadState *tst,
struct vki_elf_prpsinfo *prpsinfo)
{
- static HChar name[VKI_PATH_MAX];
+ HChar *name;
VG_(memset)(prpsinfo, 0, sizeof(*prpsinfo));
@@ -220,7 +220,7 @@
prpsinfo->pr_uid = 0;
prpsinfo->pr_gid = 0;
- if (VG_(resolve_filename)(VG_(cl_exec_fd), name, VKI_PATH_MAX)) {
+ if (VG_(resolve_filename)(VG_(cl_exec_fd), &name)) {
HChar *n = name+VG_(strlen)(name)-1;
while (n > name && *n != '/')
Modified: branches/BUF_REMOVAL/coregrind/m_debuginfo/debuginfo.c
==============================================================================
--- branches/BUF_REMOVAL/coregrind/m_debuginfo/debuginfo.c (original)
+++ branches/BUF_REMOVAL/coregrind/m_debuginfo/debuginfo.c Wed Jul 30 14:24:10 2014
@@ -1090,7 +1090,6 @@
{
Int i, r, sz_exename;
ULong obj_mtime, pdb_mtime;
- HChar exename[VKI_PATH_MAX];
HChar* pdbname = NULL;
HChar* dot;
SysRes sres;
@@ -1111,21 +1110,23 @@
time into obj_mtime. */
r = VG_(fstat)(fd_obj, &stat_buf);
if (r == -1)
- goto out; /* stat failed ?! */
+ return; /* stat failed ?! */
vg_assert(r == 0);
obj_mtime = stat_buf.mtime;
- /* and get its name into exename[]. */
- vg_assert(VKI_PATH_MAX > 100); /* to ensure /proc/self/fd/%d is safe */
- VG_(memset)(exename, 0, sizeof(exename));
- VG_(sprintf)(exename, "/proc/self/fd/%d", fd_obj);
- /* convert exename from a symlink to real name .. overwrites the
- old contents of the buffer. Ick. */
- sz_exename = VG_(readlink)(exename, exename, sizeof(exename)-2 );
+ /* and get its name into exename. */
+ HChar tmp[64]; // large enough
+ VG_(sprintf)(tmp, "/proc/self/fd/%d", fd_obj);
+
+ /* convert tmp from a symlink to real name */
+ HChar *exe;
+ sz_exename = VG_(readlink)(tmp, &exe);
+
if (sz_exename == -1)
- goto out; /* readlink failed ?! */
- vg_assert(sz_exename >= 0 && sz_exename < sizeof(exename));
- vg_assert(exename[sizeof(exename)-1] == 0);
+ return; /* readlink failed ?! */
+
+ HChar exename[sz_exename + 1];
+ VG_(strcpy)(exename, exe); // make a copy on the stack
if (VG_(clo_verbosity) > 0) {
VG_(message)(Vg_UserMsg, "LOAD_PDB_DEBUGINFO: objname: %s\n", exename);
Modified: branches/BUF_REMOVAL/coregrind/m_libcfile.c
==============================================================================
--- branches/BUF_REMOVAL/coregrind/m_libcfile.c (original)
+++ branches/BUF_REMOVAL/coregrind/m_libcfile.c Wed Jul 30 14:24:10 2014
@@ -70,14 +70,18 @@
/* Given a file descriptor, attempt to deduce its filename. To do
this, we use /proc/self/fd/<FD>. If this doesn't point to a file,
- or if it doesn't exist, we return False. */
-Bool VG_(resolve_filename) ( Int fd, HChar* buf, Int n_buf )
+ or if it doesn't exist, we return False.
+ Upon successful completion *result contains the filename. The
+ filename will be overwritten with the next invocation so callers
+ need to copy the filename if needed. *result is NULL if the filename
+ cannot be deduced. */
+Bool VG_(resolve_filename) ( Int fd, HChar** result )
{
# if defined(VGO_linux)
- HChar tmp[64];
+ HChar tmp[64]; // large enough
VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
- VG_(memset)(buf, 0, n_buf);
- if (VG_(readlink)(tmp, buf, n_buf) > 0 && buf[0] == '/')
+
+ if (VG_(readlink)(tmp, result) > 0 && (*result)[0] == '/')
return True;
else
return False;
@@ -85,12 +89,16 @@
# elif defined(VGO_darwin)
HChar tmp[VKI_MAXPATHLEN+1];
if (0 == VG_(fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) {
- if (n_buf > 0) {
- VG_(strncpy)( buf, tmp, n_buf < sizeof(tmp) ? n_buf : sizeof(tmp) );
- buf[n_buf-1] = 0;
- }
- if (tmp[0] == '/') return True;
+ static HChar *buf = NULL;
+
+ if (buf == NULL)
+ buf = VG_(arena_malloc)(VG_AR_CORE, VKI_MAXPATHLEN+1);
+ VG_(strcpy)( buf, tmp );
+
+ *result = buf;
+ if (result[0] == '/') return True;
}
+ *result = NULL;
return False;
# else
@@ -507,17 +515,51 @@
}
-Int VG_(readlink) (const HChar* path, HChar* buf, UInt bufsiz)
+/* Perform the readlink operation on path. Upon successful completion
+ *result points to a dynamically allocated buffer that contains the
+ untruncated contents of the symbolic link. The string is properly
+ terminated with '\0'. The return value is the number of characters
+ written to that buffer not counting the terminating '\0' character.
+ This buffer will be overwritten in the next invocation so callers
+ need to copy the result if needed.
+ If the operation fails, the function returns -1 and *result is NULL. */
+Int VG_(readlink) (const HChar* path, HChar** result)
{
SysRes res;
- /* res = readlink( path, buf, bufsiz ); */
+ static HChar *buf = NULL;
+ static UInt bufsiz = 0;
+
+ if (buf == NULL) { // 1st time
+ bufsiz = VKI_PATH_MAX;
+ buf = VG_(arena_malloc)(VG_AR_CORE, "readlink", bufsiz);
+ }
+
+ while (42) {
# if defined(VGP_arm64_linux)
- res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
+ res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
(UWord)path, (UWord)buf, bufsiz);
# else
- res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
+ res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
# endif
- return sr_isError(res) ? -1 : sr_Res(res);
+ if (sr_isError(res)) {
+ *result = NULL;
+ return -1;
+ }
+ UInt num_char_written = sr_Res(res);
+
+ if (num_char_written == bufsiz) {
+ // Buffer was too small. Increase size and retry.
+ bufsiz += VKI_PATH_MAX;
+ buf = VG_(arena_realloc)(VG_AR_CORE, "readlink", buf, bufsiz);
+ continue;
+ }
+
+ vg_assert(num_char_written < bufsiz); // paranoia
+
+ buf[num_char_written] = '\0'; // properly terminate
+ *result = buf;
+ return num_char_written;
+ }
}
Int VG_(getdents) (Int fd, struct vki_dirent *dirp, UInt count)
Modified: branches/BUF_REMOVAL/coregrind/m_syswrap/syswrap-generic.c
==============================================================================
--- branches/BUF_REMOVAL/coregrind/m_syswrap/syswrap-generic.c (original)
+++ branches/BUF_REMOVAL/coregrind/m_syswrap/syswrap-generic.c Wed Jul 30 14:24:10 2014
@@ -591,9 +591,9 @@
// Record opening of an fd, and find its name.
void ML_(record_fd_open_named)(ThreadId tid, Int fd)
{
- static HChar buf[VKI_PATH_MAX];
+ HChar* buf;
HChar* name;
- if (VG_(resolve_filename)(fd, buf, VKI_PATH_MAX))
+ if (VG_(resolve_filename)(fd, &buf))
name = buf;
else
name = NULL;
Modified: branches/BUF_REMOVAL/coregrind/pub_core_libcfile.h
==============================================================================
--- branches/BUF_REMOVAL/coregrind/pub_core_libcfile.h (original)
+++ branches/BUF_REMOVAL/coregrind/pub_core_libcfile.h Wed Jul 30 14:24:10 2014
@@ -44,7 +44,7 @@
extern Int VG_(fcntl) ( Int fd, Int cmd, Addr arg );
/* Convert an fd into a filename */
-extern Bool VG_(resolve_filename) ( Int fd, HChar* buf, Int n_buf );
+extern Bool VG_(resolve_filename) ( Int fd, HChar** buf );
/* Return the size of a file, or -1 in case of error */
extern Long VG_(fsize) ( Int fd );
Modified: branches/BUF_REMOVAL/include/pub_tool_libcfile.h
==============================================================================
--- branches/BUF_REMOVAL/include/pub_tool_libcfile.h (original)
+++ branches/BUF_REMOVAL/include/pub_tool_libcfile.h Wed Jul 30 14:24:10 2014
@@ -91,7 +91,7 @@
extern SysRes VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout);
-extern Int VG_(readlink)( const HChar* path, HChar* buf, UInt bufsize );
+extern Int VG_(readlink)( const HChar* path, HChar** buf );
extern Int VG_(getdents)( Int fd, struct vki_dirent *dirp, UInt count );
extern const HChar* VG_(basename)( const HChar* path );
|