Bug 68945 - dbus-daemon enters infinite loop (100% CPU usage)
Summary: dbus-daemon enters infinite loop (100% CPU usage)
Status: RESOLVED FIXED
Alias: None
Product: dbus
Classification: Unclassified
Component: core (show other bugs)
Version: unspecified
Hardware: All All
: medium major
Assignee: Simon McVittie
QA Contact:
URL:
Whiteboard: review?
Keywords: patch
Depends on:
Blocks:
 
Reported: 2013-09-04 16:28 UTC by Tomasz Łukaszewski
Modified: 2013-09-13 07:16 UTC (History)
5 users (show)

See Also:
i915 platform:
i915 features:


Attachments
_dbus_babysitter_unref: avoid infinite loop if waitpid() returns EINTR (1.59 KB, patch)
2013-09-05 10:31 UTC, Simon McVittie
Details | Splinter Review

Description Tomasz Łukaszewski 2013-09-04 16:28:57 UTC
There is an infinite loop in dbus/dbus-spawn.c between lines 311-317 (in both stable 1.6 line and in master):


          /* If we couldn't reap the child then kill it, and
           * try again
           */
          if (ret == 0)
            kill (sitter->sitter_pid, SIGKILL);

        again:
          if (ret == 0)
            ret = waitpid (sitter->sitter_pid, &status, 0);

          if (ret < 0)
            {
              if (errno == EINTR)
                goto again;
              else if (errno == ECHILD)


Once waitpid() returns -1 with errno set to EINTR, dbus-deamon enters an infinite loop.
Comment 1 Simon McVittie 2013-09-04 16:43:18 UTC
(In reply to comment #0)
> Once waitpid() returns -1 with errno set to EINTR, dbus-deamon enters an
> infinite loop.

Which platforms does this happen on, in practice?

I think the solution is to set "ret = 0" before "goto again", or add a sensible EINTR wrapper.
Comment 2 Tomasz Łukaszewski 2013-09-04 16:58:36 UTC
It happened few times on my openSUSE 12.3 x86_64 (actually, it is using 100% of one of my two cores right now.) I also found the same bug filed against earlier openSUSE version, so it happens to other people as well: https://bugzilla.novell.com/show_bug.cgi?id=782909
Comment 3 Simon McVittie 2013-09-05 10:30:42 UTC
Does the patch I'm about to attach solve this for you?
Comment 4 Simon McVittie 2013-09-05 10:31:17 UTC
Created attachment 85236 [details] [review]
_dbus_babysitter_unref: avoid infinite loop if waitpid()  returns EINTR

If waitpid() failed with EINTR, we'd go back for another go, but
because ret is nonzero, we'd skip the waitpid() and just keep looping.

Also avoid an unnecessary "goto" in favour of a proper loop, to make it
more clearly correct.
Comment 5 Tomasz Łukaszewski 2013-09-05 12:36:56 UTC
(In reply to comment #3)
> Does the patch I'm about to attach solve this for you?

I've applied a fix yesterday and new instance of dbus-daemon is running without problems right now, but it doesn't mean anything: this issue happens once in a few weeks, so it is almost impossible to tell that the problem was fixed.

Anyway, we know there is a bug there and it has to be fixed.
Comment 6 Colin Walters 2013-09-05 12:38:54 UTC
(In reply to comment #4)
> Created attachment 85236 [details] [review] [review]
> _dbus_babysitter_unref: avoid infinite loop if waitpid()  returns EINTR
> 
> If waitpid() failed with EINTR, we'd go back for another go, but
> because ret is nonzero, we'd skip the waitpid() and just keep looping.
> 
> Also avoid an unnecessary "goto" in favour of a proper loop, to make it
> more clearly correct.

Ouch, can't believe we've had that bug for so long (since 2003 looks like).

Reviewed-by: Colin Walters <walters@verbum.org>
Comment 7 Simon McVittie 2013-09-05 15:16:14 UTC
(In reply to comment #6)
> Ouch, can't believe we've had that bug for so long (since 2003 looks like).
> 
> Reviewed-by: Colin Walters <walters@verbum.org>

Fixed in git for 1.6.14 (which I'll release).
Comment 8 Jean Delvare 2013-09-05 15:18:48 UTC
Thanks for the patch. As soon as I am done with more urgent matters, I'll build an openSUSE package with it so it gets more testing.
Comment 9 Jean Delvare 2013-09-13 07:16:12 UTC
Fix was integrated into openSUSE Factory.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.