Browse files

CDRIVER-148 Memory leak using write_concern

 fix 3 driver leaks plus double free
 leaks in  mongo_check_last_error and mongo_run_command were serious
fix 29 leaks in tests
recommend documentation with highlighting and emphasis of memory management
  • Loading branch information...
1 parent 245d1a1 commit 41f00af411b9f6b77daed03f9a6f54bef751474e @gjmurakami-10gen gjmurakami-10gen committed Jun 28, 2012
View
1 .gitignore
@@ -12,6 +12,7 @@
*.swp
.DS_Store
+.idea
test_*
benchmark
View
2 Makefile
@@ -187,7 +187,7 @@ deps:
32bit:
$(MAKE) CFLAGS="-m32" LDFLAGS="-pg"
-test_%: test/%_test.c $(MONGO_STLIBNAME)
+test_%: test/%_test.c test/test.h $(MONGO_STLIBNAME)
$(CC) -o $@ -L. -Isrc $(TEST_DEFINES) $(ALL_LDFLAGS) $< $(MONGO_STLIBNAME)
%.o: %.c
View
3 src/bson.c
@@ -276,10 +276,11 @@ MONGO_EXPORT void bson_print_raw( const char *data , int depth ) {
break;
case BSON_CODEWSCOPE:
bson_printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) );
- bson_init( &scope );
+ //bson_init( &scope ); // review - stepped on by bson_iterator_code_scope?
bson_iterator_code_scope( &i, &scope );
bson_printf( "\n\t SCOPE: " );
bson_print( &scope );
+ //bson_destroy( &scope ); // review - causes free error
break;
case BSON_INT:
bson_printf( "%d" , bson_iterator_int( &i ) );
View
28 src/mongo.c
@@ -758,7 +758,7 @@ static int mongo_cursor_bson_valid( mongo_cursor *cursor, const bson *bson ) {
static int mongo_check_last_error( mongo *conn, const char *ns,
mongo_write_concern *write_concern ) {
-
+ int ret = MONGO_OK;
bson response = {NULL, 0};
bson fields;
bson_iterator it;
@@ -769,18 +769,19 @@ static int mongo_check_last_error( mongo *conn, const char *ns,
bson_free( cmd_ns );
if( res != MONGO_OK )
- return MONGO_ERROR;
+ ret = MONGO_ERROR;
else {
if( ( bson_find( &it, &response, "$err" ) == BSON_STRING ) ||
( bson_find( &it, &response, "err" ) == BSON_STRING ) ) {
__mongo_set_error( conn, MONGO_WRITE_ERROR,
"See conn->lasterrstr for details.", 0 );
mongo_set_last_error( conn, &it, &response );
- return MONGO_ERROR;
- } else
- return MONGO_OK;
+ ret = MONGO_ERROR;
+ }
+ bson_destroy( &response );
}
+ return ret;
}
static int mongo_choose_write_concern( mongo *conn,
@@ -1464,7 +1465,7 @@ MONGO_EXPORT double mongo_count( mongo *conn, const char *db, const char *ns, co
MONGO_EXPORT int mongo_run_command( mongo *conn, const char *db, const bson *command,
bson *out ) {
-
+ int ret = MONGO_OK;
bson response = {NULL, 0};
bson fields;
int sl = strlen( db );
@@ -1478,21 +1479,24 @@ MONGO_EXPORT int mongo_run_command( mongo *conn, const char *db, const bson *com
bson_free( ns );
if( res != MONGO_OK )
- return MONGO_ERROR;
+ ret = MONGO_ERROR;
else {
bson_iterator it;
if( bson_find( &it, &response, "ok" ) )
success = bson_iterator_bool( &it );
if( !success ) {
conn->err = MONGO_COMMAND_FAILED;
- return MONGO_ERROR;
+ bson_destroy( &response );
+ ret = MONGO_ERROR;
} else {
if( out )
- *out = response;
- return MONGO_OK;
+ *out = response;
+ else
+ bson_destroy( &response );
}
}
+ return ret;
}
MONGO_EXPORT int mongo_simple_int_command( mongo *conn, const char *db,
@@ -1662,7 +1666,6 @@ MONGO_EXPORT int mongo_cmd_add_user( mongo *conn, const char *db, const char *us
MONGO_EXPORT bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass ) {
bson from_db;
bson cmd;
- bson out;
const char *nonce;
int result;
@@ -1696,9 +1699,8 @@ MONGO_EXPORT bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, co
bson_destroy( &from_db );
- result = mongo_run_command( conn, db, &cmd, &out );
+ result = mongo_run_command( conn, db, &cmd, NULL );
- bson_destroy( &from_db );
bson_destroy( &cmd );
return result;
View
1 test/bson_subobject_test.c
@@ -43,6 +43,7 @@ int main() {
ASSERT( 0 == copy->stackPos );
ASSERT( 0 == copy->err );
+ bson_destroy( copy );
bson_destroy( b );
return 0;
View
4 test/bson_test.c
@@ -74,6 +74,8 @@ int test_bson_generic() {
ASSERT( 1 == copy->finished );
ASSERT( 0 == copy->err );
+ bson_destroy( copy );
+
bson_print( b );
bson_iterator_init( &it, b );
@@ -260,6 +262,8 @@ int test_bson_size( void ) {
ASSERT( bson_size( bsmall ) == 12 );
+ bson_destroy( bsmall );
+
return 0;
}
View
3 test/commands_test.c
@@ -36,6 +36,9 @@ int main() {
ASSERT( bson_find( it, out, "capped" ) == BSON_INT );
ASSERT( bson_find( it, out, "max" ) == BSON_INT );
+ bson_destroy( cmd );
+ bson_destroy( out );
+
mongo_cmd_drop_collection( conn, "test", col, NULL );
mongo_cmd_drop_db( conn, db );
View
7 test/env_posix_test.c
@@ -41,6 +41,11 @@ int test_read_timeout( void ) {
ASSERT( conn->err == MONGO_IO_ERROR );
ASSERT( strcmp( "Resource temporarily unavailable", conn->errstr ) == 0 );
+ bson_destroy( &obj );
+ bson_destroy( &b );
+
+ mongo_destroy( conn );
+
return 0;
}
@@ -87,6 +92,8 @@ int test_error_messages( void ) {
ASSERT( conn->err == MONGO_IO_ERROR );
ASSERT( conn->errcode == ENOTSOCK );
+ bson_destroy( b );
+
mongo_init( conn );
ASSERT( mongo_count( conn, "test", "foo", NULL ) == MONGO_ERROR );
View
8 test/errors_test.c
@@ -122,6 +122,10 @@ int test_namespace_validation_on_insert( void ) {
ASSERT( conn->err == MONGO_NS_INVALID );
ASSERT( strncmp( conn->errstr, "Collection may not contain '$'", 29 ) == 0 );
+ bson_destroy( b );
+ bson_destroy( b2 );
+ mongo_destroy( conn );
+
return 0;
}
@@ -174,6 +178,10 @@ int test_insert_limits( void ) {
NULL, 0 ) == MONGO_ERROR );
ASSERT( conn->err == MONGO_BSON_TOO_LARGE );
+ bson_destroy( b );
+ bson_destroy( b2 );
+ mongo_destroy( conn );
+
return 0;
}
View
2 test/examples_test.c
@@ -67,5 +67,7 @@ int main() {
/* Now iterate that object */
bson_print( &sub );
+ bson_destroy( &b );
+
return 0;
}
View
4 test/gridfs_test.c
@@ -187,8 +187,9 @@ void test_streaming() {
gridfs_destroy( gfs );
mongo_destroy( conn );
- free( buf );
+ free( medium );
free( small );
+ free( buf );
}
void test_large() {
@@ -245,6 +246,7 @@ void test_large() {
gridfs_destroy( gfs );
mongo_disconnect( conn );
mongo_destroy( conn );
+ free( buffer );
}
int main( void ) {
View
7 test/helpers_test.c
@@ -19,6 +19,7 @@ void test_index_helper( mongo *conn ) {
mongo_create_index( conn, "test.bar", &b, MONGO_INDEX_SPARSE | MONGO_INDEX_UNIQUE, &out );
bson_destroy( &b );
+ bson_destroy( &out );
bson_init( &b );
bson_append_start_object( &b, "key" );
@@ -35,6 +36,9 @@ void test_index_helper( mongo *conn ) {
ASSERT( bson_find( &it, &out, "unique" ) );
ASSERT( bson_find( &it, &out, "sparse" ) );
+
+ bson_destroy( &b );
+ bson_destroy( &out );
}
int main() {
@@ -48,8 +52,9 @@ int main() {
exit( 1 );
}
-
test_index_helper( conn );
+ mongo_destroy( conn );
+
return 0;
}
View
116 test/test.h
@@ -1,56 +1,60 @@
-#include "mongo.h"
-#include <stdlib.h>
-
-#define ASSERT(x) \
- do{ \
- if(!(x)){ \
- printf("\nFailed ASSERT [%s] (%d):\n %s\n\n", __FILE__, __LINE__, #x); \
- exit(1); \
- }\
- }while(0)
-
-#define ASSERT_EQUAL_STRINGS(x, y) \
- do{ \
- if((strncmp( x, y, strlen( y ) ) != 0 )){ \
- printf("\nFailed ASSERT_EQUAL_STRINGS [%s] (%d):\n \"%s\" does not equal\n %s\n", __FILE__, __LINE__, x, #y); \
- exit(1); \
- }\
- }while(0)
-
-#ifdef _WIN32
-#define INIT_SOCKETS_FOR_WINDOWS mongo_init_sockets();
-#else
-#define INIT_SOCKETS_FOR_WINDOWS do {} while(0)
-#endif
-
-const char *TEST_DB = "test";
-const char *TEST_COL = "foo";
-const char *TEST_NS = "test.foo";
-
-MONGO_EXTERN_C_START
-
-int mongo_get_server_version( char *version ) {
- mongo conn[1];
- bson cmd[1], out[1];
- bson_iterator it[1];
- const char *result;
-
- mongo_connect( conn, TEST_SERVER, 27017 );
-
- bson_init( cmd );
- bson_append_int( cmd, "buildinfo", 1 );
- bson_finish( cmd );
-
- if( mongo_run_command( conn, "admin", cmd, out ) == MONGO_ERROR ) {
- return -1;
- }
-
- bson_iterator_init( it, out );
- result = bson_iterator_string( it );
-
- memcpy( version, result, strlen( result ) );
-
- return 0;
-}
-
-MONGO_EXTERN_C_END
+#include "mongo.h"
+#include <stdlib.h>
+
+#define ASSERT(x) \
+ do{ \
+ if(!(x)){ \
+ printf("\nFailed ASSERT [%s] (%d):\n %s\n\n", __FILE__, __LINE__, #x); \
+ exit(1); \
+ }\
+ }while(0)
+
+#define ASSERT_EQUAL_STRINGS(x, y) \
+ do{ \
+ if((strncmp( x, y, strlen( y ) ) != 0 )){ \
+ printf("\nFailed ASSERT_EQUAL_STRINGS [%s] (%d):\n \"%s\" does not equal\n %s\n", __FILE__, __LINE__, x, #y); \
+ exit(1); \
+ }\
+ }while(0)
+
+#ifdef _WIN32
+#define INIT_SOCKETS_FOR_WINDOWS mongo_init_sockets();
+#else
+#define INIT_SOCKETS_FOR_WINDOWS do {} while(0)
+#endif
+
+const char *TEST_DB = "test";
+const char *TEST_COL = "foo";
+const char *TEST_NS = "test.foo";
+
+MONGO_EXTERN_C_START
+
+int mongo_get_server_version( char *version ) {
+ int ret = 0;
+ mongo conn[1];
+ bson cmd[1], out[1];
+ bson_iterator it[1];
+ const char *result;
+
+ mongo_connect( conn, TEST_SERVER, 27017 );
+
+ bson_init( cmd );
+ bson_append_int( cmd, "buildinfo", 1 );
+ bson_finish( cmd );
+
+ if( mongo_run_command( conn, "admin", cmd, out ) == MONGO_ERROR ) {
+ ret = -1;
+ }
+ else {
+ bson_iterator_init( it, out );
+ result = bson_iterator_string( it );
+
+ memcpy( version, result, strlen( result ) );
+ bson_destroy( out );
+ }
+ bson_destroy( cmd );
+ mongo_destroy( conn );
+ return 0;
+}
+
+MONGO_EXTERN_C_END
View
5 test/validate_test.c
@@ -44,6 +44,7 @@ int main() {
bson_append_int( &b, "foo", 1 );
ASSERT( mongo_insert( conn, "test.foo", &b, NULL ) == MONGO_ERROR );
ASSERT( conn->err == MONGO_BSON_NOT_FINISHED );
+ bson_destroy( &b );
/* Test valid keys. */
bson_init( &b );
@@ -98,9 +99,10 @@ int main() {
ASSERT( cursor->conn->err & MONGO_BSON_NOT_FINISHED );
bson_destroy( &b );
+ mongo_cursor_destroy( cursor );
/* Test valid strings. */
- bson_init( & b );
+ bson_init( &b );
result = bson_append_string( &b , "foo" , "bar" );
ASSERT( result == BSON_OK );
ASSERT( b.err == 0 );
@@ -129,6 +131,7 @@ int main() {
for ( j=0; j < BATCH_SIZE; j++ )
bson_destroy( &bs[j] );
+ bson_destroy( &b );
mongo_cmd_drop_db( conn, "test" );
mongo_disconnect( conn );
View
2 test/write_concern_test.c
@@ -178,6 +178,7 @@ void test_write_concern_input( mongo *conn ) {
conn->write_concern = NULL;
mongo_write_concern_destroy( wc );
mongo_write_concern_destroy( wcbad );
+ bson_destroy( b );
}
void test_insert( mongo *conn ) {
@@ -258,6 +259,7 @@ void test_insert( mongo *conn ) {
bson_destroy( b );
bson_destroy( b2 );
bson_destroy( b3 );
+ bson_destroy( b4 );
mongo_write_concern_destroy( wc );
}

0 comments on commit 41f00af

Please sign in to comment.