Op maandag 12 oktober 2015 19:52:23 schreef Vadim Zhukov:
> 12 окт. 2015 г. 16:27 пользователь "Remco" <[email protected]> написал:

Hi Vadim,

> > After an upgrade to OpenBSD 5.8 the konsole application in KDE4 starts
> 
> taking
> 
> > 100% cpu when piping somethine through more/less, e.g.:
> > $ getent passwd |less
> > 
> > I got some very basic output by running konsole as follows (from another
> > konsole window):

Let's call this other window the parent.

> > $ konsole > /tmp/konsole.log 2>&1

Let's call the konsole that's submitted here the child.

> > 
> > The logged information looks like:
> 

...

> > konsole(21654) OpenBSDProcessInfo::readProcArgs: sysctl() call failed
> 
> with code 3
> 
> > konsole(21654) OpenBSDProcessInfo::readCurrentDir: sysctl() call failed
> 
> with code 3
> 

After looking at konsole-4.14.3/src/ProcessInfo.cpp a couple of times, I 
suspected a faulty 
(parent)Pid parameter causing the loop.

I think the loop occurs in "QString ProcessInfo::validCurrentDir() const".

    while (!ok && currentPid != 0) {
        ProcessInfo* current = ProcessInfo::newInstance(currentPid);
        current->update();
        currentPid = current->parentPid(&ok);
        dir = current->currentDir(&ok);
        delete current;
    }

I think the biggest problem is the current->update() call. AFAICS this function 
calls other 
functions that can fail and chooses to ignore those failures. My suspicion is 
that this can 
cause a continuously invalid currentPid and (ok == false) situation. Another 
part of the 
problem is that the ProcessInfo::validCurrentDir() function itself doesn't fail 
either so it 
chooses to loop until a valid set of parameters is found.

By returning from this function early when finding a valid currentDir, the loop 
is avoided. 
This seems to work for the child and gives a usable konsole session. When using 
a pipe in 
the child, the parent still appears to enter some kind of loop. (it still 
outputs the two errors 
repeatedly, however it appears to do so roughly once per second instead of 
continuously, 
which is some improvement) The parent appears to get out of the loop when the 
piped 
command finishes. (the repeated messages stop) Neither of these processes 
appear to 
take excessive cpu time any longer. (cpu% negligeable)

Assuming that indeed a faulty (parent)Pid is used, I'm not sure exactly where 
that comes 
from, so I guess the real problem is still there.

However, this patch should improve the situation:

Index: patches/patch-src_ProcessInfo_cpp
=======================================================
============
RCS file: /cvs/ports/x11/kde4/konsole/patches/patch-src_ProcessInfo_cpp,v
retrieving revision 1.4
diff -u -p -u -r1.4 patch-src_ProcessInfo_cpp
--- patches/patch-src_ProcessInfo_cpp   10 Jul 2014 15:12:59 -0000      1.4
+++ patches/patch-src_ProcessInfo_cpp   13 Oct 2015 12:44:12 -0000
@@ -1,7 +1,7 @@
 $OpenBSD: patch-src_ProcessInfo_cpp,v 1.4 2014/07/10 15:12:59 sthen Exp $
 Fix sysctl(3) error handling.
---- src/ProcessInfo.cpp.orig   Tue Jun  3 10:30:56 2014
-+++ src/ProcessInfo.cpp        Thu Jul 10 16:12:33 2014
+--- src/ProcessInfo.cpp.orig   Sat Nov  1 05:17:02 2014
++++ src/ProcessInfo.cpp        Tue Oct 13 14:44:03 2015
 @@ -27,6 +27,7 @@
  #include <sys/socket.h>
  #include <netinet/in.h>
@@ -10,7 +10,25 @@ Fix sysctl(3) error handling.
  #include <unistd.h>
  #include <pwd.h>
  #include <sys/param.h>
-@@ -738,38 +739,28 @@ class OpenBSDProcessInfo : public UnixProcessInfo (pub
+@@ -100,12 +101,15 @@ void ProcessInfo::update()
+ 
+ QString ProcessInfo::validCurrentDir() const
+ {
+-    bool ok = false;
++    bool ok = true;
+ 
+     // read current dir, if an error occurs try the parent as the next
+     // best option
+-    int currentPid = parentPid(&ok);
+     QString dir = currentDir(&ok);
++    if (ok)
++          return (dir);
++
++    int currentPid = parentPid(&ok);
+     while (!ok && currentPid != 0) {
+         ProcessInfo* current = ProcessInfo::newInstance(currentPid);
+         current->update();
+@@ -738,38 +742,28 @@ class OpenBSDProcessInfo : public UnixProcessInfo (pub
  
  private:
      virtual bool readProcInfo(int aPid) {
@@ -60,7 +78,7 @@ Fix sysctl(3) error handling.
          return true;
      }
  
-@@ -785,7 +776,7 @@ class OpenBSDProcessInfo : public UnixProcessInfo (pub
+@@ -785,7 +779,7 @@ class OpenBSDProcessInfo : public UnixProcessInfo (pub
          managementInfoBase[2] = aPid;
          managementInfoBase[3] = whatMib;
  
@@ -69,7 +87,7 @@ Fix sysctl(3) error handling.
              len *= 2;
              nbuf = realloc(buf, len);
              if (nbuf == NULL) {
-@@ -794,8 +785,13 @@ class OpenBSDProcessInfo : public UnixProcessInfo (pub
+@@ -794,8 +788,13 @@ class OpenBSDProcessInfo : public UnixProcessInfo (pub
  
              buf = nbuf;
              rc = ::sysctl(managementInfoBase, 4, buf, &len, NULL, 0);

Reply via email to