public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
* [SCM]  master: When /proc/PID/exe is invalid throw an exception.
@ 2008-06-12 20:32 cagney
  0 siblings, 0 replies; only message in thread
From: cagney @ 2008-06-12 20:32 UTC (permalink / raw)
  To: frysk-cvs

The branch, master has been updated
       via  e7fe8b0edbf5bc538a3e7fbcd37997bc800d27a5 (commit)
      from  531115f2541df6ed1e8a8f16e24c519fb858b209 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit e7fe8b0edbf5bc538a3e7fbcd37997bc800d27a5
Author: Andrew Cagney <cagney@toil.yyz.redhat.com>
Date:   Thu Jun 12 16:31:00 2008 -0400

    When /proc/PID/exe is invalid throw an exception.
    
    frysk-core/frysk/bindir/ChangeLog
    2008-06-12  Andrew Cagney  <cagney@redhat.com>
    
    	* TestFexe.java (testExeOfDeletedFile()): Enable.  Match expected
    	error.
    	* fexe.java: Use Exe.getName.
    
    frysk-core/frysk/proc/live/ChangeLog
    2008-06-12  Andrew Cagney  <cagney@redhat.com>
    
    	* LinuxPtraceProc.java (getExe()): Delete.
    
    frysk-sys/frysk/sys/ChangeLog
    2008-06-12  Andrew Cagney  <cagney@redhat.com>
    
    	* cni/Errno.cxx (throwUserException): New.
    	* cni/Errno.hxx (throwUserException): New.
    
    frysk-sys/frysk/sys/proc/ChangeLog
    2008-06-12  Andrew Cagney  <cagney@redhat.com>
    
    	* Exe.java (getName): Rename get.
    	(openReadOnly): New.
    	* jni/Exe.cxx (Exe::getName): Update.
    	* cni/Exe.cxx (Exe::getName): Update.
    
    frysk-sys/jnixx/ChangeLog
    2008-06-12  Andrew Cagney  <cagney@redhat.com>
    
    	* exceptions.cxx (userException): Implement.
    	* exceptions.hxx (userException): Declare.

-----------------------------------------------------------------------

Summary of changes:
 frysk-core/frysk/bindir/ChangeLog               |    4 ++
 frysk-core/frysk/bindir/TestFexe.java           |    4 +--
 frysk-core/frysk/bindir/fexe.java               |    4 +-
 frysk-core/frysk/proc/live/ChangeLog            |    4 ++
 frysk-core/frysk/proc/live/LinuxPtraceProc.java |   33 ++-----------------
 frysk-sys/frysk/sys/ChangeLog                   |    3 ++
 frysk-sys/frysk/sys/cni/Errno.cxx               |    8 +++++
 frysk-sys/frysk/sys/cni/Errno.hxx               |    4 ++
 frysk-sys/frysk/sys/proc/ChangeLog              |    7 ++++
 frysk-sys/frysk/sys/proc/Exe.java               |    9 ++---
 frysk-sys/frysk/sys/proc/cni/Exe.cxx            |   38 ++++++++++++++++++----
 frysk-sys/frysk/sys/proc/jni/Exe.cxx            |   29 +++++++++++++++--
 frysk-sys/jnixx/ChangeLog                       |    5 +++
 frysk-sys/jnixx/exceptions.cxx                  |   23 ++++++++++++++
 frysk-sys/jnixx/exceptions.hxx                  |    4 ++
 15 files changed, 129 insertions(+), 50 deletions(-)

First 500 lines of diff:
diff --git a/frysk-core/frysk/bindir/ChangeLog b/frysk-core/frysk/bindir/ChangeLog
index 5f57822..32b6db4 100644
--- a/frysk-core/frysk/bindir/ChangeLog
+++ b/frysk-core/frysk/bindir/ChangeLog
@@ -1,5 +1,9 @@
 2008-06-12  Andrew Cagney  <cagney@redhat.com>
 
+	* TestFexe.java (testExeOfDeletedFile()): Enable.  Match expected
+	error.
+	* fexe.java: Use Exe.getName.
+
 	* TestFexe.java (testExeOfDeletedFile()): New; mark as unresolved
 	6621.
 
diff --git a/frysk-core/frysk/bindir/TestFexe.java b/frysk-core/frysk/bindir/TestFexe.java
index d5aba64..5a37447 100644
--- a/frysk-core/frysk/bindir/TestFexe.java
+++ b/frysk-core/frysk/bindir/TestFexe.java
@@ -89,8 +89,6 @@ public class TestFexe extends TestLib {
     }
 
     public void testExeOfDeletedFile() {
-	if (unresolved(6621))
-	    return;
 	TearDownExpect e = new TearDownExpect();
 	TearDownFile exe = TearDownFile.create();
 	// Create a copy of sleep that is executable.
@@ -111,6 +109,6 @@ public class TestFexe extends TestLib {
 	assertFalse("file exists", exe.stillExists());
 	// Try fexe with the executable deleted
 	e.send(Prefix.binFile("fexe").getPath() + " $pid\r");
-	e.expect(exe.getName() + " \\(deleted\\)\r\n\\$ ");
+	e.expect("The link /proc/[0-9]+/exe points to the deleted file .*" + exe.getName() + "\\r\n\\$ ");
     }
 }
diff --git a/frysk-core/frysk/bindir/fexe.java b/frysk-core/frysk/bindir/fexe.java
index 2bcb374..e6a0600 100644
--- a/frysk-core/frysk/bindir/fexe.java
+++ b/frysk-core/frysk/bindir/fexe.java
@@ -84,11 +84,11 @@ public class fexe
 	    if (verbose) {
 		ProcessIdentifier pid
 		= ProcessIdentifierFactory.create(proc.getPid());
-		System.out.println(  proc.getPid()
+		System.out.println(proc.getPid()
 			           + " "
 			           + proc.getExeFile().getFile().getAbsolutePath()
 			           + " "
-			           + Exe.get(pid)
+			           + Exe.getName(pid)
 			           + " "
 			           + sysRootedPath);
 	    } else 
diff --git a/frysk-core/frysk/proc/live/ChangeLog b/frysk-core/frysk/proc/live/ChangeLog
index eee24c5..61ffa17 100644
--- a/frysk-core/frysk/proc/live/ChangeLog
+++ b/frysk-core/frysk/proc/live/ChangeLog
@@ -1,3 +1,7 @@
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* LinuxPtraceProc.java (getExe()): Delete.
+
 2008-06-06  Teresa Thomas  <tthomas@redhat.com>
 
 	* LinuxPtraceTaskState.java: Additional logging messages.
diff --git a/frysk-core/frysk/proc/live/LinuxPtraceProc.java b/frysk-core/frysk/proc/live/LinuxPtraceProc.java
index e854829..c7e1888 100644
--- a/frysk-core/frysk/proc/live/LinuxPtraceProc.java
+++ b/frysk-core/frysk/proc/live/LinuxPtraceProc.java
@@ -224,40 +224,15 @@ public class LinuxPtraceProc extends LiveProc {
      * and a second returning the exe as it should be (but possibly
      * isn't :-).  Better yet have utrace handle it :-)
      */
-    private String exe;
-    private String getExe() {
+    private SysRootFile exe;
+    public SysRootFile getExeFile() {
 	if (exe == null) {
-	    ProcessIdentifier pid
-		= ProcessIdentifierFactory.create(getPid());
-	    String exe = Exe.get(pid);
-	    // Linux's /proc/$$/exe can get screwed up in several
-	    // ways.  Detect each here and return null.
-	    if (exe.endsWith(" (deleted)"))
-		// Assume (possibly incorrectly) that a trailing
-		// "(deleted)" always indicates a deleted file.
-		return null;
-	    if (exe.indexOf((char)0) >= 0)
-		// Assume that an EXE that has somehow ended up with
-		// an embedded NUL character is invalid.  This happens
-		// when the kernel screws up "mv a-really-long-file
-		// $exe" leaving the updated EXE string with something
-		// like "$exe<NUL>ally-long-file (deleted)".
-		return null;
-	    if (!new File(exe).exists())
-		// Final sanity check; the above two should have covered
-		// all possible cases.  But one never knows.
-		return null;
-	    this.exe = exe;
+	    File exeFile = new File(Exe.getName(pid));
+	    return new SysRootFile(SysRootCache.getSysRoot(exeFile.getName()), exeFile);
 	}
 	return exe;
     }
 
-    public SysRootFile getExeFile() {
-	String exe = getExe();
-	File exeFile = new File(exe);
-	return new SysRootFile(SysRootCache.getSysRoot(exeFile.getName()), exeFile);
-    }
-
     /**
      * If it hasn't already been read, read the stat structure.
      */
diff --git a/frysk-sys/frysk/sys/ChangeLog b/frysk-sys/frysk/sys/ChangeLog
index c6c022a..aec7679 100644
--- a/frysk-sys/frysk/sys/ChangeLog
+++ b/frysk-sys/frysk/sys/ChangeLog
@@ -1,5 +1,8 @@
 2008-06-12  Andrew Cagney  <cagney@redhat.com>
 
+	* cni/Errno.cxx (throwUserException): New.
+	* cni/Errno.hxx (throwUserException): New.
+
 	* Errno.java-sh: Extend ExternalException.
 	* cni/Errno.cxx: Update.
 
diff --git a/frysk-sys/frysk/sys/cni/Errno.cxx b/frysk-sys/frysk/sys/cni/Errno.cxx
index 3af0e1b..4ccac23 100644
--- a/frysk-sys/frysk/sys/cni/Errno.cxx
+++ b/frysk-sys/frysk/sys/cni/Errno.cxx
@@ -163,6 +163,14 @@ throwErrno (int err, const char *prefix)
   throwErrno (err, ajprintf ("%s: %s", prefix, strerror (err)));
 }
 
+void throwUserException(const char *format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  jstring message = vajprintf(format, ap);
+  va_end(ap);
+  throw new frysk::UserException(message);
+}
+
 void
 throwRuntimeException (const char *message)
 {
diff --git a/frysk-sys/frysk/sys/cni/Errno.hxx b/frysk-sys/frysk/sys/cni/Errno.hxx
index 6bcde43..5838b0f 100644
--- a/frysk-sys/frysk/sys/cni/Errno.hxx
+++ b/frysk-sys/frysk/sys/cni/Errno.hxx
@@ -47,6 +47,10 @@ extern void throwErrno (int err, const char *prefix)
 extern void throwErrno (int err, const char *prefix, const char *suffix, ...)
   __attribute__ ((noreturn)) __attribute__((format (printf, 3, 4)));
 
+// <<prefix>>: <<strerror(err)>> (<<suffix>> ...)
+extern void throwUserException(const char *format, ...)
+  __attribute__ ((noreturn)) __attribute__((format (printf, 1, 2)));
+
 // <<message>>
 extern void throwRuntimeException (const char *message)
   __attribute__ ((noreturn));
diff --git a/frysk-sys/frysk/sys/proc/ChangeLog b/frysk-sys/frysk/sys/proc/ChangeLog
index 84cf92d..79c61d4 100644
--- a/frysk-sys/frysk/sys/proc/ChangeLog
+++ b/frysk-sys/frysk/sys/proc/ChangeLog
@@ -1,3 +1,10 @@
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* Exe.java (getName): Rename get.
+	(openReadOnly): New.
+	* jni/Exe.cxx (Exe::getName): Update.
+	* cni/Exe.cxx (Exe::getName): Update.
+
 2008-06-04  Andrew Cagney  <cagney@redhat.com>
 
 	* TestMaps.java (testNative()): New.
diff --git a/frysk-sys/frysk/sys/proc/Exe.java b/frysk-sys/frysk/sys/proc/Exe.java
index 07c9a05..23e33be 100644
--- a/frysk-sys/frysk/sys/proc/Exe.java
+++ b/frysk-sys/frysk/sys/proc/Exe.java
@@ -43,14 +43,11 @@ import frysk.sys.ProcessIdentifier;
 
 /**
  * The contents of <tt>/proc/PID/exe</tt>.
- *
- * XXX: Should this be more like a builder or like Stat where there's
- * a refresh method that detects that the contents actually changed?
  */
 
 public class Exe {
-    public static String get(ProcessIdentifier pid) {
-	return get(pid.intValue());
+    public static String getName(ProcessIdentifier pid) {
+	return getName(pid.intValue());
     }
-    private static native String get (int pid);
+    private static native String getName(int pid);
 }
diff --git a/frysk-sys/frysk/sys/proc/cni/Exe.cxx b/frysk-sys/frysk/sys/proc/cni/Exe.cxx
index 6f258c5..8b583fb 100644
--- a/frysk-sys/frysk/sys/proc/cni/Exe.cxx
+++ b/frysk-sys/frysk/sys/proc/cni/Exe.cxx
@@ -48,22 +48,46 @@
 #include "frysk/sys/proc/Exe.h"
 
 jstring
-frysk::sys::proc::Exe::get (jint pid)
-{
+frysk::sys::proc::Exe::getName(jint pid) {
   char file[FILENAME_MAX];
   if (::snprintf (file, sizeof file, "/proc/%d/exe", (int) pid)
       >= FILENAME_MAX)
-    throwRuntimeException ("snprintf: buffer overflow");
+    throwRuntimeException("snprintf: buffer overflow");
 
   // /proc/$$/exe contains a soft-link specifying the name of the
   // executable, possibly with "(deleted)" appended.  That link's
   // upper bound is determined by FILENAME_MAX since that is the
-  // longest possible allowable file name.
-  const int maxLen = FILENAME_MAX + sizeof (" (deleted)") + 1;
+  // longest possible allowable file name.  Note that readlink doesn't
+  // NUL terminate so need to leave space for that.
+  const char deleted[] = " (deleted)";
+  const int maxLen = FILENAME_MAX + sizeof(deleted) + 1;
   char link[maxLen];
-  int len = ::readlink (file, link, sizeof (link));
+  int len = ::readlink(file, link, sizeof(link) - 1);
   if (len < 0 || len >= maxLen)
-    throwErrno (errno, "readlink");
+    throwErrno(errno, "readlink");
+  link[len] = '\0';
+
+  // Linux's /proc/$$/exe can get screwed up in several ways.  Detect
+  // each here and return null.
+  if ((int) strlen(link) != len) {
+    // Assume that an EXE that has somehow ended up with an embedded
+    // NUL character is invalid.  This happens when the kernel screws
+    // up "mv a-really-long-file $exe" leaving the updated EXE string
+    // with something like "$exe<NUL>ally-long-file (deleted)".
+    throwUserException("The link %s is corrupt", file);
+  }
+
+  if (strstr(link, deleted) + strlen(deleted) - link == len) {
+    // Assume (possibly incorrectly) that a trailing "(deleted)"
+    // always indicates a deleted file.
+    link[len - strlen(deleted)] = '\0';
+    throwUserException("The link %s points to the deleted file %s",
+		       file, link);
+  }
+
+  if (access(link, F_OK) != 0) {
+    throwErrno(errno, "file %s", link);
+  }
 
   // Note that some kernels have a "feature" where the link can become
   // corrupted.  Just retun that, the caller needs to decide if the
diff --git a/frysk-sys/frysk/sys/proc/jni/Exe.cxx b/frysk-sys/frysk/sys/proc/jni/Exe.cxx
index 12745a8..112f363 100644
--- a/frysk-sys/frysk/sys/proc/jni/Exe.cxx
+++ b/frysk-sys/frysk/sys/proc/jni/Exe.cxx
@@ -49,7 +49,7 @@
 using namespace java::lang;
 
 String
-frysk::sys::proc::Exe::get(jnixx::env env, jint pid) {
+frysk::sys::proc::Exe::getName(jnixx::env env, jint pid) {
   // Get the name of the EXE in /proc.
   char file[FILENAME_MAX];
   if (::snprintf(file, sizeof file, "/proc/%d/exe", (int) pid)
@@ -60,13 +60,36 @@ frysk::sys::proc::Exe::get(jnixx::env env, jint pid) {
   // executable, possibly with "(deleted)" appended.  That link's
   // upper bound is determined by FILENAME_MAX since that is the
   // longest possible allowable file name.
-  const int maxLen = FILENAME_MAX + sizeof (" (deleted)") + 1;
+  const char deleted[] = " (deleted)";
+  const int maxLen = FILENAME_MAX + sizeof(deleted) + 1;
   char link[maxLen];
-  int len = ::readlink (file, link, sizeof (link) - 1);
+  int len = ::readlink (file, link, sizeof(link) - 1);
   if (len < 0 || len >= maxLen)
     errnoException(env, errno, "readlink");
   link[len] = '\0';
 
+  // Linux's /proc/$$/exe can get screwed up in several ways.  Detect
+  // each here and return null.
+  if ((int) strlen(link) != len) {
+    // Assume that an EXE that has somehow ended up with an embedded
+    // NUL character is invalid.  This happens when the kernel screws
+    // up "mv a-really-long-file $exe" leaving the updated EXE string
+    // with something like "$exe<NUL>ally-long-file (deleted)".
+    userException(env, "The link %s is corrupt", file);
+  }
+
+  if (strstr(link, deleted) + strlen(deleted) - link == len) {
+    // Assume (possibly incorrectly) that a trailing "(deleted)"
+    // always indicates a deleted file.
+    link[len - strlen(deleted)] = '\0';
+    userException(env, "The link %s points to the deleted file %s",
+		  file, link);
+  }
+
+  if (access(link, F_OK) != 0) {
+    errnoException(env, errno, "file %s", link);
+  }
+
   // Note that some kernels have a "feature" where the link can become
   // corrupted.  Just retun that, the caller needs to decide if the
   // extracted link is valid.
diff --git a/frysk-sys/jnixx/ChangeLog b/frysk-sys/jnixx/ChangeLog
index 7fdd6ba..8a2673e 100644
--- a/frysk-sys/jnixx/ChangeLog
+++ b/frysk-sys/jnixx/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-12  Andrew Cagney  <cagney@redhat.com>
+
+	* exceptions.cxx (userException): Implement.
+	* exceptions.hxx (userException): Declare.
+
 2008-06-04  Andrew Cagney  <cagney@redhat.com>
 
 	* elements.cxx (slurp): Don't count the terminating NUL in the
diff --git a/frysk-sys/jnixx/exceptions.cxx b/frysk-sys/jnixx/exceptions.cxx
index 2f5ce80..928e0fd 100644
--- a/frysk-sys/jnixx/exceptions.cxx
+++ b/frysk-sys/jnixx/exceptions.cxx
@@ -150,3 +150,26 @@ runtimeException(::jnixx::env& env, const char *fmt, ...) {
     throw e;
   }
 }
+
+
+void
+userException(::jnixx::env& env, const char *fmt, ...) {
+  va_list ap;
+  va_start(ap, fmt);
+  char *message = NULL;
+  if (::vasprintf(&message, fmt, ap) < 0) {
+    // If this fails things are pretty much stuffed.
+    int err = errno;
+    fprintf(stderr, "warning: vasprintf in runtimeException failed: %s",
+	    ::strerror(err));
+    RuntimeException::ThrowNew(env, "vasprintf in runtimeException failed");
+  }
+  va_end(ap);
+  try {
+    frysk::UserException::ThrowNew(env, message);
+  } catch (java::lang::Throwable e) {
+    // Always executed.
+    ::free(message);
+    throw e;
+  }
+}
diff --git a/frysk-sys/jnixx/exceptions.hxx b/frysk-sys/jnixx/exceptions.hxx
index 877356c..36fde6f 100644
--- a/frysk-sys/jnixx/exceptions.hxx
+++ b/frysk-sys/jnixx/exceptions.hxx
@@ -52,3 +52,7 @@ extern void errnoException(::jnixx::env& env, int error, const char *prefix,
 extern void runtimeException(::jnixx::env& env, const char *fmt, ...)
   __attribute__((noreturn))
   __attribute__((format (printf, 2, 3)));
+
+extern void userException(::jnixx::env& env, const char *fmt, ...)
+  __attribute__((noreturn))
+  __attribute__((format (printf, 2, 3)));


hooks/post-receive
--
frysk system monitor/debugger


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-06-12 20:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-12 20:32 [SCM] master: When /proc/PID/exe is invalid throw an exception cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).