More crash-proof KCrash (was Re: Konq crash backtraces)

Oswald Buddenhagen ossi at kde.org
Tue Jan 17 20:03:59 GMT 2006


On Tue, Jan 17, 2006 at 01:36:30PM +0100, Lubos Lunak wrote:
> > It's called to free up the dcop name while the crash dialog is
> > showing. It also allows kicker to restart from the crash handler.
> 
> I guess it pre-dates the closing of all open filedescriptors done in
> the crashhandler. Kicker restarts here just fine and the dcop
> connection is broken by the close() too.
> 
fwiw, i have the attached patch on my disk for something like 1 - 1½
years. it's particularly remarkable that it closes only the dcop and x
connection in the parent, then forks off the process for drkonqi and
closes the file descriptors only in the child. the idea is to keep the
handles open, so a parent process that determines the child's state
based on some pipes would not bury the process until drkonqi diagnosed
death - in kdm's case that means resetting the x-server, so drkonqi
wouldn't have a particularly long appearance otherwise.

-- 
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!
--
Chaos, panic, and disorder - my work here is done.
-------------- next part --------------
--- kcrash.cpp.orig	2003-11-22 16:17:23.000000000 +0100
+++ kcrash.cpp	2003-11-22 15:55:48.000000000 +0100
@@ -125,13 +125,11 @@
     crashRecursionCounter++; //
   }
 
-        // Close dcop connections
+  // Close dcop connections
   DCOPClient::emergencyClose();
-  // Close all remaining file descriptors
-  struct rlimit rlp;
-  getrlimit(RLIMIT_NOFILE, &rlp);
-  for (int i = 0; i < (int)rlp.rlim_cur; i++)
-    close(i);
+  // Close X connection
+  if ( qt_xdisplay() )
+    close(ConnectionNumber(qt_xdisplay()));
 
   bool shuttingDown = false;
 
@@ -152,16 +150,15 @@
         pid_t pid = fork();
 
         if (pid <= 0) {
-          // this code is leaking, but this should not hurt cause we will do a
-          // exec() afterwards. exec() is supposed to clean up.
-          char * argv[24]; // don't forget to update this
+          QCString sigstr, pidstr, verstr, namestr, addrstr;
+          const char * argv[24]; // don't forget to update this
           int i = 0;
 
           // argument 0 has to be drkonqi
-          argv[i++] = qstrdup("drkonqi");
+          argv[i++] = "drkonqi";
 
           // start up on the correct display
-          argv[i++] = qstrdup("-display");
+          argv[i++] = "-display";
 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
           if ( qt_xdisplay() )
             argv[i++] = XDisplayString(qt_xdisplay());
@@ -172,70 +169,73 @@
 #endif
 
           // we have already tested this
-          argv[i++] = qstrdup("--appname");
-          argv[i++] = qstrdup(appName);
+          argv[i++] = "--appname";
+          argv[i++] = appName;
           if (KApplication::loadedByKdeinit)
-            argv[i++] = qstrdup("--kdeinit");
+            argv[i++] = "--kdeinit";
 
           // only add apppath if it's not NULL
           if (appPath) {
-            argv[i++] = qstrdup("--apppath");
-            argv[i++] = qstrdup(appPath);
+            argv[i++] = "--apppath";
+            argv[i++] = appPath;
           }
 
           // signal number -- will never be NULL
-          QCString tmp;
-          tmp.setNum(sig);
-          argv[i++] = qstrdup("--signal");
-          argv[i++] = qstrdup(tmp.data());
+          sigstr.setNum(sig);
+          argv[i++] = "--signal";
+          argv[i++] = sigstr.data();
 
           // pid number -- only include if this is the child
-          // the debug stuff will be disabled if we was not able to fork
+          // the debug stuff will be disabled if we were not able to fork
           if (pid == 0) {
-            tmp.setNum(getppid());
-            argv[i++] = qstrdup("--pid");
-            argv[i++] = qstrdup(tmp.data());
+            pidstr.setNum(getppid());
+            argv[i++] = "--pid";
+            argv[i++] = pidstr.data();
           }
 
           const KInstance *instance = KGlobal::_instance;
           const KAboutData *about = instance ? instance->aboutData() : 0;
           if (about) {
             if (!about->version().isNull()) {
-              argv[i++] = qstrdup("--appversion");
-              argv[i++] = qstrdup(about->version().utf8());
+              verstr = about->version().utf8();
+              argv[i++] = "--appversion";
+              argv[i++] = verstr.data();
             }
 
             if (!about->programName().isNull()) {
-              argv[i++] = qstrdup("--programname");
-              argv[i++] = qstrdup(about->programName().utf8());
+              namestr = about->programName().utf8();
+              argv[i++] = "--programname";
+              argv[i++] = namestr.data();
             }
 
             if (!about->bugAddress().isNull()) {
-              argv[i++] = qstrdup("--bugaddress");
-              argv[i++] = qstrdup(about->bugAddress().utf8());
+              addrstr = about->bugAddress().utf8();
+              argv[i++] = "--bugaddress";
+              argv[i++] = addrstr.data();
             }
           }
 
           if ( kapp && !kapp->startupId().isNull()) {
-            argv[i++] = qstrdup("--startupid");
-            argv[i++] = qstrdup(kapp->startupId());
+            argv[i++] = "--startupid";
+            argv[i++] = kapp->startupId().data();
           }
 
-          if ( safer )
-            argv[i++] = qstrdup("--safer");
+          if ( safer || geteuid() != getuid() || getegid() != getgid() )
+            argv[i++] = "--safer";
 
           // NULL terminated list
           argv[i++] = NULL;
 
-          setgid(getgid());
-          setuid(getuid());
+          // Close all remaining file descriptors
+          if (pid == 0) {
+            struct rlimit rlp;
+            getrlimit(RLIMIT_NOFILE, &rlp);
+            for (int i = 0; i < (int)rlp.rlim_cur; i++)
+              close(i);
+          }
 
-          execvp("drkonqi", argv);
+          execvp("drkonqi", (char**)argv);
 
-          // we could clean up here
-          // i = 0;
-          // while (argv[i])
-          //   free(argv[i++]);
         }
         else
         {


More information about the kde-core-devel mailing list