public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
From: cagney@sourceware.org
To: frysk-cvs@sourceware.org
Subject: [SCM]  master: When /proc/PID/exe is invalid throw an exception.
Date: Thu, 12 Jun 2008 20:32:00 -0000	[thread overview]
Message-ID: <20080612203220.30387.qmail@sourceware.org> (raw)

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


                 reply	other threads:[~2008-06-12 20:32 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080612203220.30387.qmail@sourceware.org \
    --to=cagney@sourceware.org \
    --cc=frysk-cvs@sourceware.org \
    --cc=frysk@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).