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);