xserver: Branch 'server-1.11-branch' - 3 commits

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Wed Jan 18 10:33:29 PST 2012


 configure.ac   |    7 +++
 os/backtrace.c |    6 ++-
 os/client.c    |  110 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 112 insertions(+), 11 deletions(-)

New commits:
commit 4a339afc586d55a9a248b893f007219d79c72600
Author: Julien Cristau <jcristau at debian.org>
Date:   Fri Dec 30 20:41:25 2011 +0100

    os: don't ignore failure from dladdr
    
    If dladdr returns 0, don't go and use the returned Dl_info, it may
    contain garbage.
    
    X.Org bug#44315 <https://bugs.freedesktop.org/show_bug.cgi?id=44315>
    
    Reported-and-tested-by: Cyril Brulebois <kibi at debian.org>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
    Reviewed-by: Cyril Brulebois <kibi at debian.org>
    Signed-off-by: Julien Cristau <jcristau at debian.org>
    (cherry picked from commit 6269977c91071e0ea16ca5b4b8e15fd6db0b6fcf)

diff --git a/os/backtrace.c b/os/backtrace.c
index 7ca6dab..f3255c7 100644
--- a/os/backtrace.c
+++ b/os/backtrace.c
@@ -44,7 +44,11 @@ void xorg_backtrace(void)
     ErrorF("\nBacktrace:\n");
     size = backtrace(array, 64);
     for (i = 0; i < size; i++) {
-	dladdr(array[i], &info);
+	int rc = dladdr(array[i], &info);
+	if (rc == 0) {
+	    ErrorF("%d: ?? [%p]\n", i, array[i]);
+	    continue;
+	}
 	mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)";
 	if (info.dli_saddr)
 	    ErrorF("%d: %s (%s+0x%lx) [%p]\n", i, mod,
commit 9a4be7e99f0e832df87b8e7fb548793dd4b52717
Author: Matthieu Herrb <matthieu.herrb at laas.fr>
Date:   Mon Jan 2 13:23:59 2012 +0000

    Add OpenBSD support to DetermineClientCmd()
    
    Uses kvm_getargv() from libkvm.
    
    Signed-off-by: Matthieu Herrb <matthieu.herrb at laas.fr>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit 6d6d4cb6043905d850834946e9bfc526ed5a9ef7)

diff --git a/configure.ac b/configure.ac
index fdaa583..65fbc8c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -999,6 +999,13 @@ if test "x$RES" = xyes && test "x$CLIENTIDS" = xyes; then
 else
 	CLIENTIDS=no
 fi
+if test "x$CLIENTIDS" = xyes; then
+	case $host_os in
+	openbsd*)
+		SYS_LIBS="$SYS_LIBS -lkvm"
+	;;
+	esac
+fi
 AC_MSG_RESULT([$CLIENTIDS])
 AM_CONDITIONAL(CLIENTIDS, [test "x$CLIENTIDS" = xyes])
 
diff --git a/os/client.c b/os/client.c
index e297f8c..aa9be84 100644
--- a/os/client.c
+++ b/os/client.c
@@ -64,6 +64,15 @@
 #include <procfs.h>
 #endif
 
+#ifdef __OpenBSD__
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+#include <kvm.h>
+#include <limits.h>
+#endif
+
 /**
  * Try to determine a PID for a client from its connection
  * information. This should be called only once when new client has
@@ -172,7 +181,39 @@ void DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs)
         if (cmdargs && sp)
             *cmdargs = strdup(sp);
     }
-#else /* not Solaris */
+#elif defined(__OpenBSD__)
+    /* on OpenBSD use kvm_getargv() */
+    {
+	kvm_t *kd;
+	char errbuf[_POSIX2_LINE_MAX];
+	char **argv;
+	struct kinfo_proc *kp;
+	size_t len = 0;
+	int i, n;
+
+	kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
+	if (kd == NULL)
+		return;
+	kp = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &n);
+	if (n != 1)
+		return;
+	argv = kvm_getargv(kd, kp, 0);
+	*cmdname = strdup(argv[0]);
+	i = 1;
+	while (argv[i] != NULL) {
+		len += strlen(argv[i]) + 1;
+		i++;
+	}
+	*cmdargs = calloc(1, len);
+	i = 1;
+	while (argv[i] != NULL) {
+		strlcat(*cmdargs, argv[i], len);
+		strlcat(*cmdargs, " ", len);
+		i++;
+	}
+	kvm_close(kd);
+    }
+#else /* Linux using /proc/pid/cmdline */
 
     /* Check if /proc/pid/cmdline exists. It's not supported on all
      * operating systems. */
commit 8046717d720c1bbbf02ba986622bc96c6b52a36c
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Sat Dec 24 10:00:56 2011 -0800

    Add Solaris support to DetermineClientCmd
    
    Uses /proc/pid/psinfo to read command & partial arguments.
    
    Moves cmdsize & argsize variables into non-Solaris #else clause
    to avoid unused variable warnings.
    
    Fixes format mismatch errors when building with DEBUG defined on
    a 64-bit platform (where Mask is defined as CARD32).
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Rami Ylimäki <rami.ylimaki at vincit.fi>
    Signed-off-by: Keith Packard <keithp at keithp.com>
    (cherry picked from commit cfc4c3d7fa8bd4da4c08b2ab8e6f85435f75353a)

diff --git a/os/client.c b/os/client.c
index b534977..e297f8c 100644
--- a/os/client.c
+++ b/os/client.c
@@ -59,6 +59,11 @@
 #include "os.h"
 #include "dixstruct.h"
 
+#ifdef __sun
+#include <errno.h>
+#include <procfs.h>
+#endif
+
 /**
  * Try to determine a PID for a client from its connection
  * information. This should be called only once when new client has
@@ -117,8 +122,6 @@ void DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs)
 {
     char path[PATH_MAX + 1];
     int totsize = 0;
-    int cmdsize = 0;
-    int argsize = 0;
     int fd = 0;
 
     if (cmdname)
@@ -129,6 +132,48 @@ void DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs)
     if (pid == -1)
         return;
 
+#ifdef __sun /* Solaris */
+    /* Solaris does not support /proc/pid/cmdline, but makes information
+     * similar to what ps shows available in a binary structure in the
+     * /proc/pid/psinfo file. */
+    if (snprintf(path, sizeof(path), "/proc/%d/psinfo", pid) < 0)
+        return;
+    fd = open(path, O_RDONLY);
+    if (fd < 0)
+    {
+        ErrorF ("Failed to open %s: %s\n", path, strerror(errno));
+        return;
+    }
+    else
+    {
+        psinfo_t psinfo = { 0 };
+        char *sp;
+
+        totsize = read(fd, &psinfo, sizeof(psinfo_t));
+        close(fd);
+        if (totsize <= 0)
+            return;
+
+        /* pr_psargs is the first PRARGSZ (80) characters of the command
+         * line string - assume up to the first space is the command name,
+         * since it's not delimited.   While there is also pr_fname, that's
+         * more limited, giving only the first 16 chars of the basename of
+         * the file that was exec'ed, thus cutting off many long gnome
+         * command names, or returning "isapython2.6" for all python scripts.
+         */
+        psinfo.pr_psargs[PRARGSZ-1] = '\0';
+        sp = strchr(psinfo.pr_psargs, ' ');
+        if (sp)
+            *sp++ = '\0';
+
+        if (cmdname)
+            *cmdname = strdup(psinfo.pr_psargs);
+
+        if (cmdargs && sp)
+            *cmdargs = strdup(sp);
+    }
+#else /* not Solaris */
+
     /* Check if /proc/pid/cmdline exists. It's not supported on all
      * operating systems. */
     if (snprintf(path, sizeof(path), "/proc/%d/cmdline", pid) < 0)
@@ -146,7 +191,6 @@ void DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs)
     path[totsize - 1] = '\0';
 
     /* Contruct the process name without arguments. */
-    cmdsize = strlen(path) + 1;
     if (cmdname)
     {
         char *name = malloc(cmdsize);
@@ -159,10 +203,14 @@ void DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs)
     }
 
     /* Construct the arguments for client process. */
-    argsize = totsize - cmdsize;
-    if (cmdargs && (argsize > 0))
+    if (cmdargs)
     {
-        char *args = malloc(argsize);
+        int cmdsize = strlen(path) + 1;
+        int argsize = totsize - cmdsize;
+        char *args = NULL;
+
+        if (argsize > 0)
+            args = malloc(argsize);
         if (args)
         {
             int i = 0;
@@ -175,6 +223,7 @@ void DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs)
             *cmdargs = args;
         }
     }
+#endif
 }
 
 /**
@@ -198,9 +247,9 @@ void ReserveClientIds(struct _Client *client)
         DetermineClientCmd(client->clientIds->pid, &client->clientIds->cmdname, &client->clientIds->cmdargs);
 
     DebugF("client(%lx): Reserved pid(%d).\n",
-           client->clientAsMask, client->clientIds->pid);
+           (unsigned long) client->clientAsMask, client->clientIds->pid);
     DebugF("client(%lx): Reserved cmdname(%s) and cmdargs(%s).\n",
-           client->clientAsMask,
+           (unsigned long) client->clientAsMask,
            client->clientIds->cmdname ? client->clientIds->cmdname : "NULL",
            client->clientIds->cmdargs ? client->clientIds->cmdargs : "NULL");
 #endif /* CLIENTIDS */
@@ -222,9 +271,9 @@ void ReleaseClientIds(struct _Client *client)
         return;
 
     DebugF("client(%lx): Released pid(%d).\n",
-           client->clientAsMask, client->clientIds->pid);
+           (unsigned long) client->clientAsMask, client->clientIds->pid);
     DebugF("client(%lx): Released cmdline(%s) and cmdargs(%s).\n",
-           client->clientAsMask,
+           (unsigned long) client->clientAsMask,
            client->clientIds->cmdname ? client->clientIds->cmdname : "NULL",
            client->clientIds->cmdargs ? client->clientIds->cmdargs : "NULL");
 


More information about the xorg-commit mailing list