Dear Maintainer,
I guess I found the issue here.
It looks like centengine is crashing with an unmodified
default configuration after 60 minutes running.

By changing "retention_update_interval" from 60 to 1 this could
be lowered to 1 minute.

Further it looks like having null pointers in "custom_variables"
member is not unusual.

But because 'dump::customvariables' receives the 'obj' by reference,
the compiler removes in an optimized build the null check,
I guess because it assumes that a reference has to be valid by definition.

Attached patch changes the argument by reference to a pointer.
A package build with that patch checks like expected for null and
leaves the function.

Upstream seems to have changed obj.custom_variables to a container type,
which might therefore not suffer from this problem anymore.

Kind regards,
Bernhard


    (gdb) print obj.custom_variables 
    $3 = (customvariablesmember_struct *) 0x0

  
https://sources.debian.org/src/centreon-engine/18.10.0-4/src/retention/dump.cc/#L127
    (gdb) list 121,133
    121     std::ostream& dump::customvariables(
    122                     std::ostream& os,
    123                     customvariablesmember_struct const& obj) {
    124       for (customvariablesmember const* member(&obj);
    125            member;
    126            member = member->next)
    127         if (member->variable_name)
    128           os << "_" << member->variable_name << "="
    129              << member->has_been_modified << ","
    130              << (member->variable_value ? member->variable_value : "")
    131              << "\n";
    132       return (os);
    133     }

  
https://sources.debian.org/src/centreon-engine/18.10.0-4/src/retention/dump.cc/#L454
    (gdb) list 389,455
    389     std::ostream& dump::service(std::ostream& os, service_struct const& 
obj) {
    ...
    454       dump::customvariables(os, *obj.custom_variables);
    455       os << "}\n";


(gdb) bt
#0  com::centreon::engine::retention::dump::customvariables (os=..., obj=...) 
at ./src/retention/dump.cc:127
#1  0x0000559743899013 in com::centreon::engine::retention::dump::host (os=..., 
obj=...) at ./src/retention/dump.cc:264
#2  0x000055974389a62b in com::centreon::engine::retention::dump::hosts 
(os=...) at ./src/retention/dump.cc:278
#3  com::centreon::engine::retention::dump::save (path=...) at 
./src/retention/dump.cc:359
#4  0x000055974386126b in _exec_event_retention_save (event=<optimized out>) at 
./src/events/timed_event.cc:176
#5  0x0000559743860b5d in handle_timed_event (event=event@entry=0x559744b5ea90) 
at ./src/events/timed_event.cc:752
#6  0x000055974385becb in com::centreon::engine::events::loop::_dispatching 
(this=0x559744b396a0) at ./src/events/loop.cc:233
#7  0x000055974385c9e9 in com::centreon::engine::events::loop::run 
(this=0x559744b396a0) at ./src/events/loop.cc:90
#8  0x0000559743784774 in main (argc=<optimized out>, argv=<optimized out>) at 
./src/main.cc:410



Unmodified Debian:                                                 || With 
patch applied:
...7c0 <+0>:     push   %r14                                       || ...530 
<+0>:     push   %r14
...7c2 <+2>:     lea    0x290a5(%rip),%r14        # 0x5597438c086e ||
...7c9 <+9>:     push   %r13                                       || ...532 
<+2>:     push   %r13
...7cb <+11>:    push   %r12                                       || ...534 
<+4>:     push   %r12
...7cd <+13>:    push   %rbp                                       || ...536 
<+6>:     push   %rbp
...7ce <+14>:    mov    %rdi,%rbp                                  || ...537 
<+7>:     mov    %rdi,%rbp
...7d1 <+17>:    push   %rbx                                       || ...53a 
<+10>:    push   %rbx
                                                                   || ...53b 
<+11>:    test   %rsi,%rsi                                     <<< null check
                                                                   || ...53e 
<+14>:    je     0x560648b46630 <...customvariables...+256>    <<< jump
...7d2 <+18>:    mov    %rsi,%rbx                                  || ...544 
<+20>:    mov    %rsi,%rbx
...7d5 <+21>:    jmpq   0x559743897868 <...customvariables...+168> ||           
       ...
                 ...                                               ||           
       ...
...868 <+168>:   cmpq   $0x0,(%rbx)               <<< crash        ||           
       ...
                 ...                                               || ...630 
<+256>:   pop    %rbx
                                                                   || ...631 
<+257>:   mov    %rbp,%rax
                                                                   || ...634 
<+260>:   pop    %rbp
                                                                   || ...635 
<+261>:   pop    %r12
                                                                   || ...637 
<+263>:   pop    %r13
                                                                      ...639 
<+265>:   pop    %r14
                                                                      ...63b 
<+267>:   retq   

Description: Change argument by reference to pointer to avoid crash
 GCC seems to expect always valid references, therefore removes
 in optimized builds null checks of references.

Author: Bernhard Übelacker <bernha...@mailbox.org>
Bug-Debian: https://bugs.debian.org/948491
Bug: https://github.com/centreon/centreon-engine/issues/338
Forwarded: no
Last-Update: 2020-01-10

--- centreon-engine-18.10.0.orig/inc/com/centreon/engine/retention/dump.hh
+++ centreon-engine-18.10.0/inc/com/centreon/engine/retention/dump.hh
@@ -39,7 +39,7 @@ namespace         retention {
     std::ostream& comments(std::ostream& os);
     std::ostream& contact(std::ostream& os, contact_struct const& obj);
     std::ostream& contacts(std::ostream& os);
-    std::ostream& customvariables(std::ostream& os, customvariablesmember_struct const& obj);
+    std::ostream& customvariables(std::ostream& os, customvariablesmember_struct const* obj);
     std::ostream& downtime(std::ostream& os, scheduled_downtime_struct const& obj);
     std::ostream& downtimes(std::ostream& os);
     std::ostream& header(std::ostream& os);
--- centreon-engine-18.10.0.orig/src/retention/dump.cc
+++ centreon-engine-18.10.0/src/retention/dump.cc
@@ -92,7 +92,7 @@ std::ostream& dump::contact(std::ostream
     "modified_service_attributes=" << (obj.modified_service_attributes & ~config->retained_contact_service_attribute_mask()) << "\n"
     "service_notification_period=" << (obj.service_notification_period ? obj.service_notification_period : "") << "\n"
     "service_notifications_enabled=" << obj.service_notifications_enabled << "\n";
-  dump::customvariables(os, *obj.custom_variables);
+  dump::customvariables(os, obj.custom_variables);
   os << "}\n";
   return (os);
 }
@@ -120,8 +120,8 @@ std::ostream& dump::contacts(std::ostrea
  */
 std::ostream& dump::customvariables(
                 std::ostream& os,
-                customvariablesmember_struct const& obj) {
-  for (customvariablesmember const* member(&obj);
+                customvariablesmember_struct const* obj) {
+  for (customvariablesmember const* member = obj;
        member;
        member = member->next)
     if (member->variable_name)
@@ -261,7 +261,7 @@ std::ostream& dump::host(std::ostream& o
     os << (x > 0 ? "," : "") << obj.state_history[(x + obj.state_history_index) % MAX_STATE_HISTORY_ENTRIES];
   os << "\n";
 
-  dump::customvariables(os, *obj.custom_variables);
+  dump::customvariables(os, obj.custom_variables);
   os << "}\n";
   return (os);
 }
@@ -451,7 +451,7 @@ std::ostream& dump::service(std::ostream
     os << (x > 0 ? "," : "") << obj.state_history[(x + obj.state_history_index) % MAX_STATE_HISTORY_ENTRIES];
   os << "\n";
 
-  dump::customvariables(os, *obj.custom_variables);
+  dump::customvariables(os, obj.custom_variables);
   os << "}\n";
   return (os);
 }

Reply via email to