LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   segfault in malloc_consolidate ?? (https://www.linuxquestions.org/questions/programming-9/segfault-in-malloc_consolidate-363048/)

zaichik 09-13-2005 02:51 PM

segfault in malloc_consolidate ??
 
Ouch, I have no idea where to go from here.

The line that generates this error is trying to open a connection to mysql on the localhost. This connection has been successfully opened before; in fact, this is the second time through the loop, and the first execution of the loop executed flawlessly.

This exact error occurs every time there is a second iteration of the loop. I double-checked to make sure that the connection is closed before it is reopened. Here is output from gdb:
Code:

2018    if( !mysql_real_connect( &conn_temp, server, mysqlUser, mysqlPass, mysqlDB, 0, NULL, 0 )) {
(gdb)

Program received signal SIGSEGV, Segmentation fault.
0x00d21301 in malloc_consolidate () from /lib/tls/libc.so.6

(gdb) backtrace
#0  0x00d21301 in malloc_consolidate () from /lib/tls/libc.so.6
#1  0x00d20b29 in _int_malloc () from /lib/tls/libc.so.6
#2  0x00d1fecd in malloc () from /lib/tls/libc.so.6
#3  0x00eceb8a in my_malloc () from /usr/lib/libmysqlclient.so.12
#4  0x00ee0055 in my_net_init () from /usr/lib/libmysqlclient.so.12
#5  0x00ecb4db in mysql_real_connect () from /usr/lib/libmysqlclient.so.12
#6  0x0804e8e2 in scan (report=1) at ipman.c:2018
#7  0x08049cc9 in main (argc=2, argv=0xbfffc054) at ipman.c:292
(gdb)

I don't expect anyone to be able to solve this, but if you could throw any ideas at me as to what kind of problem to look for on my part, what kind of stupidity would cause malloc_consolidate() to segfault, that would be much appreciated.

TIA!

Dark_Helmet 09-13-2005 03:10 PM

Check your loop. If it works the first time, it's likely you forget to "undo" something you did the first time through the loop. I don't use mysql, but my first guess is to make sure that you close the existing mysql connection before you try to connect to it again (using the same data structures, etc.). Usually there are data structures the library needs to keep track of how things are working. The open/connect functions expect those data structures to be initialized to know values, and that's usually what the close/disconnect functions do: they free any used memory and re-initialize the data structure.

That kind of problem has caused me grief before. It may not be the answer to your problem, but it's worth investigating.

zaichik 09-13-2005 03:58 PM

Hello Dark_Helmet,

Thanks for the reply. You are right on target with your observation. A mysql session starts with mysql_init( &context ), where context is a MYSQL structure that holds all the info about the session. The connection is made to the server with mysql_real_connect( ) and passing such things as a reference to the MYSQL structure, user name, server, etc. The MYSQL structure is wiped and previous connections made with the structure are closed with mysql_close( &context ).

I believe that I have closed everything before trying to reopen it. If you would be willing to check the problem loop, I have posted it at http://zaichik.org/loop.txt (if it's not kosher to post it in links, let me know and I will post it here).

In my test case, all occurences of target_mac[ ] are empty strings, and ip_is_bound() will return 0.

If you have the time, I would really appreciate a second pair of eyes on this (or third, fourth, fifth)...

Thanks again!

zaichik 09-13-2005 04:00 PM

Actually, I decided to go ahead and post the code. For posterity. Pardon its length.
Code:

while( row = mysql_fetch_row( res )) {
        ipv4 = strtoul( row[ 0 ], NULL, 0 );
// get the mac from ips_and_macs
        mysql_init( &conn_temp );
        if( !mysql_real_connect( &conn_temp, server, mysqlUser, mysqlPass, mysqlDB, 0, NULL, 0 )) {
                printf( "%s\n", mysql_error( &conn_temp ));
                free( ip );
                free( mac );
                free( reportMsg );
                free( mysqlQuery );
                mysql_close( &conn_temp );
                mysql_close( &conn );
                return( -1 );
        }
        sprintf( mysqlQuery, "SELECT mac_addr FROM ips_and_macs WHERE ip_addr = %u", ipv4 );
        mysql_real_query( &conn_temp, mysqlQuery, strlen( mysqlQuery ));
       
        if( !( res_temp = mysql_store_result( &conn_temp ))) {
                printf( "%s\n", mysql_error( &conn_temp ));
                printf( "%s: Second pass aborted.\n", myName );
                free( mysqlQuery );
                free( ip );
                free( mac );
                free( reportMsg );
                free( mysqlQuery );
                mysql_close( &conn );
                mysql_close( &conn_temp );
                return( -1 );
        }
       
        row_temp = mysql_fetch_row( res_temp );
       
        sprintf( mac, "%s", row_temp[ 0 ] );
        mysql_free_result( res_temp );
        mysql_close( &conn_temp );

        ip = int_to_dotted( ipv4 );
        for( x = 0; x < 5; x++ )
                sprintf( target_mac[ x ], "%s", "" );
        get_mac( ip );
printf( "Responses for IP %s: %s\t%s\t%s\t%s\t%s\n", ip, target_mac[ 0 ], target_mac[ 1 ], target_mac[ 2 ], target_mac[ 3 ], target_mac[ 4 ] );
//first deal with non-responders, again
        if( strlen( target_mac[ 0 ] ) == 0 &&
            strlen( target_mac[ 1 ] ) == 0 &&
            strlen( target_mac[ 2 ] ) == 0 &&
            strlen( target_mac[ 3 ] ) == 0 &&
            strlen( target_mac[ 4 ] ) == 0 ) {
            if( !ip_is_bound( ip )) {
                    mysql_init( &conn_temp );
                if( mysql_errno( &conn_temp )) {
                        printf( mysql_error( &conn_temp ));
                }
                sprintf( mysqlQuery, "UPDATE no_response SET pass_num = %d, pass_time = NOW() WHERE ip_addr = %u", pass, ipv4 );

// the following line generates the segfault               
               
                if( !mysql_real_connect( &conn_temp, server, mysqlUser, mysqlPass, mysqlDB, 0, NULL, 0 )) {
                        printf( "%s\n", mysql_error( &conn_temp ));
                        printf( "%s: IP address %s did not respond, but there was an error updating the table no_response.\n", myName, row[ 0 ] );
                }
                else {
                       
                        mysql_real_query( &conn_temp, mysqlQuery, strlen( mysqlQuery ));
                        if( mysql_errno( &conn_temp))
                                printf( "%s\n", mysql_error( &conn_temp ));
                        }
                        mysql_close( &conn_temp );
                }
            } // if !ip_is_bound
// otherwise, compare the stuff in target_mac with ip...they should be the same.  Or, if the
// packet got dropped, the array member for that packet should be a zero-length string.
            else {
// DELETE FROM no_response
                    sprintf( mysqlQuery, "DELETE FROM no_response WHERE ip_addr = %u", ipv4 );
                mysql_init( &conn_temp );
                if( !mysql_real_connect( &conn_temp, server, mysqlUser, mysqlPass, mysqlDB, 0, NULL, 0 )) {
                        printf( "%s\n", mysql_error( &conn_temp ));
                        printf( "%s:  Please remove ip_addr %s manually from no_response.\n", myName, ip );
                }
                else {
                        mysql_real_query( &conn_temp, mysqlQuery, strlen( mysqlQuery ) );
                }
                mysql_close( &conn_temp );
                if(( strcmp( mac, target_mac[ 0 ] ) == 0 || strlen( target_mac[ 0 ] ) == 0 ) &&
                  ( strcmp( mac, target_mac[ 1 ] ) == 0 || strlen( target_mac[ 1 ] ) == 0 ) &&
                  ( strcmp( mac, target_mac[ 2 ] ) == 0 || strlen( target_mac[ 2 ] ) == 0 ) &&
                  ( strcmp( mac, target_mac[ 3 ] ) == 0 || strlen( target_mac[ 3 ] ) == 0 ) &&
                  ( strcmp( mac, target_mac[ 4 ] ) == 0 || strlen( target_mac[ 4 ] ) == 0 )) {
                    //Again, all is good and this can actually be omitted unless we leave non-responders in the table between runs

                    }
                else {
                            // A stolen IP address! Report it!
                        printf( "%s:  The IP address %s does not report its assigned MAC address of %s. This will be reported shortly.\n", myName, ip, mac );
                        mismatch = TRUE;
                        reportMsg = ( char * ) malloc( MAX_SIZE_MSG );
                        if( reportMsg == NULL ) {
                                printf( "%s: Out of memory in scan().  Scan aborted, contact adminstrator.\n", myName );
                                exit( -1 );
                        }
                        sprintf( reportMsg, "IP address %s should have MAC %s, but reported:\n%s\n%s\n%s\n%s\n%s\n.",
                                row[ 0 ], row[ 1 ], target_mac[ 0 ], target_mac[ 1 ], target_mac[ 2 ],
                                target_mac[ 3 ], target_mac[ 4 ] );
                        add_report( reportMsg );
                        free( reportMsg );
                       
                }
                //close our resources -- after 2070, } // while, looping through no_response
                mysql_free_result( res_temp );
                mysql_close( &conn_temp );
            }
} // while, looping through no_response



All times are GMT -5. The time now is 10:48 AM.