[Xymon] Possible defect in rrd handler causing divide-by-zero crashes

John Thurston john.thurston at alaska.gov
Tue Apr 21 23:04:42 CEST 2015


It has been a long road, but I may have uncovered a defect in the rrd 
handler. I'm currently running xymon 4.3.17 (somewhat patched) on 
Solaris 10 on SPARC.

:: Symptom ::
The xymond_rrd process crashes. It leaves footprints in the log like:
> 2015-04-20 19:09:18 Child process 23929 died: Signal 8
> 2015-04-20 19:09:18 Peer at 0.0.0.0:0 failed: Broken pipe
> 2015-04-20 19:09:18 Peer not up, flushing message queue
It also leaves a pid file behind.
It also leaves gaps in the rrd data.

:: Tracing ::
By collecting core dumps and using pstack, I was able to see:
> __divdi3+0x164(0, 0, 0, 0, 0, 0)
> do_la_rrd+0x2d4(1017c8, 1017e4, 10181d, 101829, 1, 55369956)
> update_rrd+0x76c(1017c8, 1017e4, 10182c, 55369956, 1017c0, 69000)
> main+0xa40(10182c, ffbfdc3c, 101829, 68800, 3, 49538)
> _start+0x5c(0, 0, 0, 0, 0, 0)

By enabling --debug on the "xymond_channel --channel=status" task (after 
applying jc's patch of March 13 so that the debug code didn't crash 
xymond - Thank you!), I was able to see that the last messages received 
prior to crashes was always a sequence of status messages containing 
"mem" followed by "cpu".

A "Signal 8" is commonly associated with a "divide by zero" event. Not 
being very C-aware, I had to consult google to learn that __divdi3 is a 
library used for unsigned long-int division. So if I'm reading the stack 
trace correctly, update_rrd called do_la_rrd which tied to do a division 
which failed.

:: Smoking gun? ::
One of the hosts (running a BBPE 4.3 client), whose status message 
triggered a crash, has the following in its last CPU message:
> Memory Statistics
> Total Physical memory:                    0 bytes (1.00MB)
> Available Physical memory:                0 bytes (1.00MB)
> Total PageFile size:            17397915648 bytes (16.20GB)
> Available PageFile size:        12473839616 bytes (11.62GB)
> Total Virtual memory size:      17397915648 bytes (16.20GB)
> Available Virtual memory size:  12487081984 bytes (11.63GB)

And has the following in its last MEM message:
> Physical Memory: 0.00MB/1.00MB (-1.#J%)
> Commit Charge: 4.59GB/16.20GB (28.30%)
>
> Memory Statistics (Used/Available/Total in bytes)
> Physical Memory:            0 (0.00MB) /            0 (1.00MB) /            0 (1.00MB)
> Commit Charge:     4924112896 (4.59GB) /  12473839616 (11.62GB) /  17397915648 (16.20GB)
> Virtual memory:    4910481408 (4.57GB) /  12487081984 (11.63GB) /  17397915648 (16.20GB)

It isn't reasonable for a system to actually have 0MB of memory, but 
that is what the client has reported.

:: Hypothesis ::

The message handling code is accepting messages from clients stating 0MB 
total physical memory, but such information is making its way into the 
RRD handler and causing a divide by zero.

Can anyone else test this hypothesis?

Can someone with more C-skills look at do_la_rrd and see if a zero 
really can find its way into its division statements?

-- 
    Do things because you should, not just because you can.

John Thurston    907-465-8591
John.Thurston at alaska.gov
Enterprise Technology Services
Department of Administration
State of Alaska



More information about the Xymon mailing list