[vz-users] vzlogger crash

Thorben Thuermer r00t at constancy.org
Wed Dec 26 18:58:41 CET 2012


On Wed, 26 Dec 2012 18:05:56 +0100
Paul Muster <paul at muster.dyndns.info> wrote:
> On 26.12.2012 17:24, Thorben Thuermer wrote:
> > waehre trotzdem noch dankbar fuer den vollstaendigen backtrace,
> > wuesste gerne was da kaputt ist.
> 
> Und nun - nach vielen Versuchen mit checkinstall, wo immer die
> debug-symbols auf der Strecke blieben - das binary auf den Server kopiert.

sorry fuer die umstaende - wie gehabt, einfach das vzlogger-binary kopieren
wuerde reichen.
(ich kann den fehler jetzt aber auch bei mir reproduzieren, wo ich weiss
 woran's liegt.)
(in deinem fall hast du wohl vzlogger wohl ohne sml-support kompiliert,
 verwendest aber eine config die sml als protokoll angibt.)

> # gdb ./vzlogger
> (gdb) run -c /usr/local/etc/vzlogger.conf
> Program received signal SIGSEGV, Segmentation fault.
> 0xb7ece5ab in ?? () from /lib/i386-linux-gnu/i686/nosegneg/libc.so.6
> (gdb) bt full
> #0  0xb7ece5ab in ?? () from /lib/i386-linux-gnu/i686/nosegneg/libc.so.6
> No symbol table info available.
> #1  0x0804d0af in meter_lookup_protocol (name=0x806c7f8 "sml",
> protocol=protocol at entry=0x806bfc4) at meter.c:102
>         it = <optimized out>
> #2  0x0804d159 in meter_init (mtr=mtr at entry=0x806bfb8, options=...) at
> meter.c:60
>         instances = 1
>         protocol_str = 0x806c7f8 "sml"
>         details = 0x806c7f8
> #3  0x0804bc1f in config_parse_meter (jso=0x806c630) at config.c:168
[...]

ein sehr dummer bug mal wieder...
die funktion meter_lookup_protocol in kombination mit der liste der
protokolle ist buggy.
wenn das in der config angegebene protokoll nicht gefunden wird,
stuerzt vzlogger ab.

 34 static const meter_details_t protocols[] = {
 37 METER_DETAIL(file,  "Read from file or fifo",               32, TRUE),
...
 46 {} /* stop condition for iterator */
 47 };
100 int meter_lookup_protocol(const char* name, meter_protocol_t *protocol) {
101     for (const meter_details_t *it = meter_get_protocols(); it != NULL; it++) {

der ende-marker in der liste ist '{}' (leere struct wohl),
der code prueft aber auf NULL,

im debugger sieht das dann so aus:
102                     if (strcmp(it->name, name) == 0) {
(gdb) p *it
$6 = {id = 0, name = 0x0, desc = 0x0, max_readings = 0, periodic = 0, init_func = 0, free_func = 0, open_func = 0, 
  close_func = 0, read_func = 0}
(gdb) n
Program received signal SIGSEGV, Segmentation fault.

=> es wird null an strcmp uebergeben.

der einfache fix waehre, als ende-marker NULL einzutragen,
aber der compiler akzeptiert NULL nicht als konstante vom typ
"meter_details_t", dadurch entstand der bug wohl.

was dann hilft:
$ git diff src/meter.c 
-       for (const meter_details_t *it = meter_get_protocols(); it != NULL; it++) {
+       for (const meter_details_t *it = meter_get_protocols(); it->name != NULL; it++) {


$ src/vzlogger -c vzlogger.conf
[Dec 26 18:52:58][mtr0] Invalid protocol: sml
[Dec 26 18:52:58][mtr0] Failed to initialize meter. Arborting.


> HTH & viele Grüße
> Paul

- Thorben


More information about the volkszaehler-users mailing list