[systemd-devel] Disabled event sources / errors on sd-bus break the event loop (Looping too fast)

Krzysztof Kotlenga k.kotlenga at sims.pl
Wed Sep 23 09:46:13 PDT 2015


Krzysztof Kotlenga wrote:

> I recommend the following gdb script, because it provides some
> possibly interesting output:

Slightly fixed version:
https://gist.github.com/pocek/709d8c098d632ed1f21e

The first one was incorrectly printing pending_iteration instead of
prepare_iteration field. Nothing major.

> What's going on with order in that "prepare" Prioq?

I've debugged this a bit more. Two things:

1. I think prepare_prioq_compare function is wrong: "enabled" field
should be the first one to compare.

2. Maybe I don't get something right - please enlighten me if that's the
case - but prioq_put or rather shuffle_up function is buggy. 

Let's start with prepare Prioq like this:
bus-input e=1 pri=0 pi=8 fd=12
bus-input e=1 pri=0 pi=9 fd=18 <- netcat

Now we enter some garbage in netcat:
bus-input e=1 pri=0 pi=9 fd=12
bus-input e=0 pri=0 pi=9 fd=18 <- netcat

BTW, some loop iterations later it is still OK if we have fixed the
order in prepare_prioq_compare (see 1):

bus-input e=1 pri=0 pi=10 fd=12
bus-input e=0 pri=0 pi=9 fd=18 <- netcat

Good! Now let's make another connection. We have a breakpoint in
prepare_prioq_compare.

bus-input e=1 pri=0 pi=11 fd=12
bus-input e=0 pri=0 pi=9 fd=18
(null) e=1 pri=0 pi=0 fd=19 <- new connection, it doesn't have a
                               description set yet.

Backtrace for some context (shortened):
#0  prepare_prioq_compare (a=0x81466e18, b=0x81477490) 
#1  shuffle_up (q=0x81466ee8, idx=2)
#2  prioq_put (q=0x81466ee8, data=0x81477490, idx=0x814774b8)
#3  sd_event_source_set_prepare (s=0x81477490, callback=0x80181f81 <prepare_callback>)
#4  attach_io_events (bus=0x81476d20)
#5  sd_bus_attach_event (bus=0x81476d20, event=0x8140e6e0, priority=0)
#6  bus_on_connection (s=0x81471680, fd=14, revents=1, userdata=0x8140e318)
#7  source_dispatch (s=0x81471680)
#8  sd_event_dispatch (e=0x8140e6e0)
#9  sd_event_run (e=0x8140e6e0, timeout=18446744073709551615)
#10 manager_loop (m=0x8140e318)
#11 main (argc=4, argv=0xbfb1b254)

OK, let's see what we have got here:
(gdb) p x->prepare_index
$2 = 0
(gdb) p y->prepare_index
$3 = 2

So we are comparing the new sd_event_source with the first one in the
queue. This is bad. Let's move to shuffle_up first.

(gdb) frame 1
(gdb) p k
$4 = 0

Right. So shuffle_up doesn't iterate more than once here. It has only
swapped item 0 and 2. The prepare queue looks like this now:

(null) e=1 pri=0 pi=0 fd=19
bus-input e=0 pri=0 pi=9 fd=18
bus-input e=1 pri=0 pi=11 fd=12

It doesn't look like a correct order judging by how prepare_event
(sd-event.c) works. The last bus-input above is pretty much broken
because s->prepare callback won't be called anymore.

Am I wrong to believe that it should have swapped 2 and 1, not 2 and 0?

Lennart, can you fix Prioq or correct me if I'm wrong, please?

> This has been debugged on v225, but AFAICS master has the same issues.

I'm debugging this now on v226 now.

-- 
kjk


More information about the systemd-devel mailing list