broken KProcess in HEAD

Oswald Buddenhagen ossi at kde.org
Sat Jul 19 15:20:26 BST 2003


On Fri, Jul 18, 2003 at 11:21:05AM +0100, Gav Wood wrote:
> KProcess appears to have been broken in HEAD fairly recently.
>
#define fairly recently
my last changes were several months ago ...

> when built under HEAD, the command often finishes without KProcess
> signalling processExited(...); a quick ps shows that the command is
> zombified.
>
hmm, strange.
please apply the attached patch and report the messages. you may want to
add more qDebug()s if the output is non-conclusive and you want to dive
deeper into it.

> it seems that the longer the process takes to execute the more chance
> of KProcess failing.
> 
even stranger ...

fwiw, we're talking about kopete/protocols/sms/services/smsclient.cpp,
right? a few notes then ...
- connecting to processExited for a blocking process is relatively
  pointless. you can call the relevant functions after start() returns.
  i plan to make kprocess not emit this signal for blocking processes 
  any more in kde 4. 
- the way you collect output is relatively broken. you fromLocal8Bit
  every chunk separately - this will break if the program emits lots of
  utf8. you have to accumulate first and then do the conversion and split
  the lines.
  another thing i dislike is the fact, that stdin and stdout are
  different handles but are collected into the same buffer. this can
  potentially lead to oddly multiplexed contents ... anyway, kprocio
  makes the same mistake - i think i'll have to take care of this.
- you are leaking the kprocess
- wth is QString("%1:%2").arg("SMSClient").arg("ProviderName") supposed
  to be good for? i can hardly think of a more complicated way to code
  it ... ;)

greetings

-- 
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!
--
Chaos, panic, and disorder - my work here is done.
-------------- next part --------------
Index: kprocess.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kprocess.cpp,v
retrieving revision 1.125
diff -u -r1.125 kprocess.cpp
--- kprocess.cpp	16 Jul 2003 20:58:22 -0000	1.125
+++ kprocess.cpp	19 Jul 2003 14:17:49 -0000
@@ -958,7 +958,9 @@
 {
   closeStdin();
 
+qDebug("commClose()");
   if (pid_) { // detached, failed, and killed processes have no output. basta. :)
+qDebug(" commClose(): need to drain handles");
     // If both channels are being read we need to make sure that one socket
     // buffer doesn't fill up whilst we are waiting for data on the other
     // (causing a deadlock). Hence we need to use select.
@@ -966,6 +968,7 @@
     int notfd = KProcessController::theKProcessController->notifierFd();
 
     while ((communication & (Stdout | Stderr)) || runs) {
+qDebug(" commClose(): draining loop iteration");
       fd_set rfds;
       FD_ZERO(&rfds);
       struct timeval timeout, *p_timeout;
@@ -997,18 +1000,25 @@
       int fds_ready = select(max_fd+1, &rfds, 0, 0, p_timeout);
       if (fds_ready < 0) {
         if (errno == EINTR)
+{ qDebug(" commClose(): draining loop interrupted");
           continue;
+}
         break;
       } else if (!fds_ready)
         break;
 
       if ((communication & Stdout) && FD_ISSET(out[0], &rfds))
+{ qDebug(" commClose(): stdout");
         slotChildOutput(out[0]);
+}
 
       if ((communication & Stderr) && FD_ISSET(err[0], &rfds))
+{ qDebug(" commClose(): stderr");
         slotChildError(err[0]);
+}
 
       if (runs && FD_ISSET(notfd, &rfds)) {
+ qDebug(" commClose(): some process exited, returning");
         runs = false; // hack: signal potential exit
         return; // don't close anything, we will be called again
       }
@@ -1019,6 +1029,7 @@
   closeStderr();
 
   closePty();
+qDebug("commClose(): normal exit");
 }
 
 
Index: kprocctrl.cpp
===================================================================
RCS file: /home/kde/kdelibs/kdecore/kprocctrl.cpp,v
retrieving revision 1.57
diff -u -r1.57 kprocctrl.cpp
--- kprocctrl.cpp	8 Feb 2003 19:27:12 -0000	1.57
+++ kprocctrl.cpp	19 Jul 2003 14:17:49 -0000
@@ -132,6 +132,7 @@
 {
   int saved_errno = errno;
 
+qDebug("kprocctrl: received SIGCHLD");
   char dummy = 0;
   ::write( theKProcessController->fd[1], &dummy, 1 );
 
@@ -151,7 +152,10 @@
 {
   char dummy[16]; // somewhat bigger - just in case several have queued up
   if( ::read( fd[0], dummy, sizeof(dummy) ) > 0 )
+{ qDebug("kprocctrl: unscheduled check");
     needcheck = true;
+} else
+ qDebug("kprocctrl: unscheduling check unnecessary");
 }
 
 void
@@ -162,13 +166,17 @@
     needcheck = false;
     char dummy = 0;
     ::write( fd[1], &dummy, 1 );
+ qDebug("kprocctrl: rescheduled check");
   }
+  else
+ qDebug("kprocctrl: rescheduling check unnecessary");
 }
 
 void KProcessController::slotDoHousekeeping()
 {
   char dummy[16]; // somewhat bigger - just in case several have queued up
   ::read( fd[0], dummy, sizeof(dummy) );
+ qDebug("kprocctrl: doing housekeeping");
 
   int status;
  again:


More information about the kde-core-devel mailing list