Uploaded image for project: 'C Driver'
  1. C Driver
  2. CDRIVER-2681

bson_context_get_default optimized out when compiling with LTO

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 1.11.0
    • Affects Version/s: None
    • Component/s: None
    • Labels:

      Drew noticed when we compile the C driver with link time optimization our tests fail. Repro:

      cd mongo-c-driver
      mkdir cmake-build && cd cmake-build
      cmake -DCMAKE_C_FLAGS="-flto" ../
      make -j8 test-libmongoc
      cd ../
      ./cmake-build/src/libmongoc/test-libmongoc -d --no-fork -l /bson/bcon/test_oid

      fails with a segfault.

      It looks like some function definitions are getting optimized out when they shouldn't be. It's a little difficult to debug since -flto removes debug info, but after some printf debugging, it became clear that bson_context_get_default was not getting called. Using nm you can also see there's no symbol in the binary:

      nm ./cmake-build/src/libmongoc/test-libmongoc | grep 'bson_context_get_default'

      comes up with nothing.

      Here's the definition of

      BSON_EXPORT (bson_context_t *)
      bson_context_get_default (void) BSON_GNUC_CONST;

      BSON_GNUC_CONST is defined as _attribute_ ((const)) for gcc/clang. The gcc function attributes docs give this explanation for the const attribute:

      Many functions do not examine any values except their arguments, and have no effects except to return a value. Calls to such functions lend themselves to optimization such as common subexpression elimination. The const attribute imposes greater restrictions on a function’s definition than the similar pure attribute below because it prohibits the function from reading global variables. Consequently, the presence of the attribute on a function declaration allows GCC to emit more efficient code for some calls to the function. Decorating the same function with both the const and the pure attribute is diagnosed.

      But bson_context_get_default does read from global variables (PTHREAD_ONCE_INIT}} and gContextDefault. Since const functions shouldn't have side effects, the linker thinks it can optimize it out. Sure enough, removing the const attribute results in this test passing.

      There are other functions marked as const that probably shouldn't be, e.g. mongoc_ssl_opt_get_default, which returns a global.


            kevin.albertson@mongodb.com Kevin Albertson
            kevin.albertson@mongodb.com Kevin Albertson
            0 Vote for this issue
            4 Start watching this issue