0

I have a following code:

bool ok;

bson_t * query = bson_new();
BSON_APPEND_BINARY(query, "_id", BSON_SUBTYPE_BINARY, client_id, CLIENT_ID_SIZE);

bson_t * update = bson_new();
bson_t update_ch1;

BSON_APPEND_DOCUMENT_BEGIN(update, "$set", &update_ch1);
    BSON_APPEND_UTF8(&update_ch1, "est", "something");
bson_append_document_end(update, &update_ch1);

bson_t * fields = bson_new();

bson_t reply;
bson_error_t error;

ok = mongoc_collection_find_and_modify(
    client_collection,
    query,
    NULL,
    update,
    fields,
    false, // remove
    false, // upsert
    false, // new
    &reply,
    &error
);

if (!ok)
{
    fprintf(stderr, "Failed to update client collection in database: %s\n", error.message);
}

bson_destroy(fields);
bson_destroy(update);
bson_destroy(query);
bson_destroy(&reply); <---- Core dump here

The problem is that it occasionally crashes. By analysing a core dump, it has been traced down to a database connectivity issue. In that case, ok is set to false and error.message says "No suitable servers found (serverselectiontryonce set) ...".
Unfortunately, the code crashed at bson_destroy(&reply); - obviously reply bson is not allocated b/c of the error in connection to database. It means that mongoc_collection_find_and_modify() fails to initialise that field in such a situation.
The question is how to reliably detect such a situation and skip bson_destroy() call.

E.g. (pseudocode):

 if (initilized(&reply)) bson_destroy(&reply);
Ales Teska
  • 1,198
  • 1
  • 17
  • 38
  • Use BSON_INITIALIZER maybe? – Ales Teska Jun 30 '17 at 12:55
  • Looks like a C Driver bug to me. "reply" should be initialized no matter what. If you're not using the latest C Driver (1.6.3), please upgrade. If you are using the latest, could you please open a ticket at jira.mongodb.org in the CDRIVER project? – A. Jesse Jiryu Davis Jul 04 '17 at 12:12
  • However, looking at your code again I believe the line `BSON_APPEND_BINARY(query, "_id", BSON_SUBTYPE_BINARY, client_id, "key");` is incorrect. It may cause memory corruption that leads to a crash. Could you please update your question to show what "client_id" is and how it's initialized? – A. Jesse Jiryu Davis Jul 04 '17 at 12:25
  • There was definitively older version of C Driver used. We replaced that with a new updated version and introduced BSON_INITIALIZER macro for any static bson_t variable. The issue disappeared. – Ales Teska Jul 04 '17 at 13:27
  • @A.JesseJiryuDavis - there was a mistake in the BSON_APPEND_BINARY line ... the last argument is of course a length. – Ales Teska Jul 04 '17 at 13:31
  • Great. What if you did NOT use BSON_INITIALIZER? You should not have to if mongoc_collection_find_and_modify is working correctly; that function should always initialize "reply". – A. Jesse Jiryu Davis Jul 04 '17 at 15:41
  • My guess is that it was not initialized if connection to database failed prior executing the query. Based on the core dump, the content of the reply was a random mess. When bson_destroy() was called, it obviously failed miserably (SEGFAULT). – Ales Teska Jul 04 '17 at 17:09
  • You should not have to if mongoc_collection_find_and_modify is working correctly. That function should always initialize "reply", no matter what. What if you did NOT use BSON_INITIALIZER with the C Driver version 1.6.3? Does it still crash? I'm asking so I can determine whether there is a bug in the C Driver. – A. Jesse Jiryu Davis Jul 04 '17 at 17:25
  • I see. It is a bit hard for me to trace that down. It was a production system where issue appeared and we were not able to reproduce it on dev. env. due to a rather complicated setup. – Ales Teska Jul 04 '17 at 18:48

0 Answers0