Details
Description
I'm experiencing a segfault, whenever I do a query which involves a $or or $and.
If I do a 'count()', then it's returning the correct number of records, but when I do a 'find', then I get a segfault when attempting to dispose the returned cursor. LastError returns NoError.
Sample logging;
-------------------------
nitialising Mongo
Mongo Version: 1.6.1
mongoc_cursor_destroy: 0
mongoc_collection_destroy: 0
mongoc_client_destroy: 0
Connect Query: { "$or" : [
,
{ "token" : "ALL" } ] }
Doing mongo.find()
Mongo Error: No Error
mongo.find() success: 20480 records
Finished Mongo Find
Disconnect Mongo Connection
mongoc_cursor_destroy: 1
2017-03-27 08:03:45 PM: SIGSEGV - Fatal !
[Dispatch Backtrace]: (1) ./dispatch_service(_Z14signal_handleri+0x85) [0x4068cb]
[Dispatch Backtrace]: (2) /lib64/libc.so.6(+0x35250) [0x7f1edb61a250]
[Dispatch Backtrace]: (2) /lib64/libc.so.6(+0x35250) [0x7f1edb61a250]
[Dispatch Backtrace]: (3) /lib64/libbson-1.0.so.0(bson_destroy+0x2c) [0x7f1edc1d5c3c]
[Dispatch Backtrace]: (4) /lib64/libmongoc-1.0.so.0(+0x1bb65) [0x7f1edc415b65]
[Dispatch Backtrace]: (5) ./dispatch_service(_ZN5Mongo10disconnectEv+0x88) [0x40b2ce]
[Dispatch Backtrace]: (6) ./dispatch_service(_Z17initialMongoQueryv+0x1c5) [0x406bd8]
[Dispatch Backtrace]: (7) ./dispatch_service(main+0xdb) [0x406d28]
[Dispatch Backtrace]: (8) /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f1edb606b35]
[Dispatch Backtrace]: (9) ./dispatch_service() [0x4056c9]
Below is the code aspect for form this query. If I do a simpler query: eg. { "sequence":
{ "$gt": 123456 }} then working as expected. It's only when I try something like: { "$or" : [ { or { "$and" : [ {
The query is valid as far as I can tell - returning a 'count' of records in mongoc and also in MongoHub (for OS X)
-------------------------------------------
|
|
Mongo mongo;
|
|
mongo.connect("notification", "notifyqueue");
|
|
// mongo.addQuery_Int32GT("sequence", 390000 ); //sequence );
|
// mongo.addQuery_Int32GTAndCharOrChar( "sequence", 300000, "token", "all", "token", "0bc1db8f5ce1873a528510c636d4ee6f" );
|
mongo.addQuery_CharOrChar( "token", "58af74c34d94887d0b8b4861", "token", "ALL" );
|
|
|
|
printf( "Connect Query: %s\n", mongo.returnQuery().c_str() );
|
|
// printf("mongo.find() success: %d records\n", (int)mongo.count() );
|
|
printf("Doing mongo.find()\n");
|
if( mongo.find() )
|
{
|
printf( "Mongo Error: %s\n", mongo.lastErrorMessage().c_str() );
|
|
|
printf("mongo.find() success: %d records\n", (int)mongo.count() );
|
while( mongo.nextRecord() )
|
// {
|
printf("Mongo Next Record");
|
// std::string out = mongo.recordAsString();
|
// printf("Record: %s\n--------\n", out.c_str() );
|
// }
|
printf("Finished Mongo Find\n");
|
|
|
} else {
|
printf( "Mongo Error: %s\n", mongo.lastErrorMessage().c_str() );
|
}
|
|
|
printf("Disconnect Mongo Connection\n");
|
mongo.disconnect();
|
|
Aspects of Mongo class that is called
-------------------------------------------------------
|
|
|
|
void Mongo::addQuery_CharOrChar( const char * fieldname1, const char * value1, const char * fieldname2, const char * value2 )
|
{
|
// eg. { $or:[ {fieldname: value}, {fieldname: value} ] }
|
if( !query ) query = BSON_CREATE();
|
|
bson_t child, child1, child2;
|
|
|
|
if( BSON_APPEND_ARRAY_BEGIN( query, "$or", &child ) )
|
{
|
if( BSON_APPEND_DOCUMENT_BEGIN( &child, "", &child1 ) )
|
{
|
BSON_APPEND_UTF8 ( &child1, fieldname1, value1);
|
bson_append_document_end( &child, &child1 );
|
}
|
|
|
if( BSON_APPEND_DOCUMENT_BEGIN( &child, "", &child2 ) )
|
{
|
BSON_APPEND_UTF8 ( &child2, fieldname2, value2);
|
bson_append_document_end( &child, &child2 );
|
}
|
|
|
bson_append_array_end( query, &child );
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void Mongo::disconnect( void )
|
{
|
try {
|
doc = NULL;
|
opts = BSON_DESTROY(opts);
|
query = BSON_DESTROY(query);
|
|
|
printf("mongoc_cursor_destroy: %d\n", (int)(cursor != NULL) );
|
if( cursor ) mongoc_cursor_destroy (cursor); cursor = NULL;
|
|
|
printf("mongoc_collection_destroy: %d\n", (int)(collection != NULL) );
|
if( collection ) mongoc_collection_destroy (collection); collection = NULL;
|
|
printf("mongoc_client_destroy: %d\n", (int)(client != NULL) );
|
if( client ) mongoc_client_destroy (client); client = NULL;
|
|
|
|
} catch (...) {
|
log_write("Mongo::disconnect try...catch error");
|
}
|
}
|
|
|
void Mongo::connect( const char * theDatabase, const char * theCollection )
|
{
|
try {
|
if( setup() )
|
{
|
// clean up if already connected to a different table / collection.
|
if( cursor ) mongoc_cursor_destroy (cursor); cursor = NULL;
|
if( collection ) mongoc_collection_destroy (collection); collection = NULL;
|
opts = BSON_DESTROY(opts);
|
query = BSON_DESTROY(query);
|
|
|
|
// Connect to the new table
|
collection = mongoc_client_get_collection (client, theDatabase, theCollection );
|
|
|
|
|
// Initialise default options and query parameters
|
// opts = BSON_CREATE();
|
// query = BSON_CREATE();
|
doc = NULL;
|
|
|
}
|
} catch (...) {
|
log_write("Mongo::connect try...catch error");
|
}
|
}
|
|
|
|
|
|
|
bool Mongo::find( void )
|
{
|
bool success = false;
|
|
try {
|
if( !setup() ) return false; // Not connected to Mongo Database
|
if( !collection ) return false; // Haven't connected to database / collection
|
|
|
|
if( cursor ) mongoc_cursor_destroy (cursor);
|
|
if( !opts ) bson_init (opts);
|
if( !query ) bson_init (query);
|
doc = NULL;
|
|
cursor = mongoc_collection_find_with_opts (collection, query, opts, read_prefs);
|
success = (cursor != NULL);
|
|
} catch (...) {
|
log_write("Error: Mongo::find try...catch");
|
}
|
|
return success;
|
}
|
|
|
uint64_t Mongo::count( void )
|
{
|
uint64_t count = -1;
|
if( collection )
|
{
|
try {
|
count = mongoc_collection_count (collection, MONGOC_QUERY_SLAVE_OK, query, 0, 0, read_prefs, &error);
|
} catch(...) {
|
log_write("Error: Mongo::recordCount try...catch");
|
}
|
}
|
|
return count;
|
}
|
Attachments
Issue Links
- duplicates
-
CDRIVER-2072 Using a filter or projection with empty field names causes a crash when destroying cursor
-
- Closed
-