The following commit has been merged in the master branch: commit da31a7e1fb60507e1b7473fd64cb05721e3359c1 Author: Marek Lindner lindner_marek@yahoo.de Date: Tue Mar 13 13:06:30 2007 +0100
purge routes before closing sockets on SIGSEGV handle race condition on unix client exit
diff --git a/allocate.c b/allocate.c index a09fb88..a423258 100644 --- a/allocate.c +++ b/allocate.c @@ -108,8 +108,8 @@ void removeMemory( int32_t tag, int32_t freetag ) {
if ( walker->counter == 0 ) {
- fprintf( stderr, "Freeing more memory than was allocated: malloc tag = %d, free tag = %d\n", tag, freetag ); - exit(1); + debug_output( 0, "Freeing more memory than was allocated: malloc tag = %d, free tag = %d\n", tag, freetag ); + restore_and_exit();
}
@@ -122,8 +122,8 @@ void removeMemory( int32_t tag, int32_t freetag ) {
if ( walker == NULL ) {
- fprintf( stderr, "Freeing memory that was never allocated: malloc tag = %d, free tag = %d\n", tag, freetag ); - exit(1); + debug_output( 0, "Freeing memory that was never allocated: malloc tag = %d, free tag = %d\n", tag, freetag ); + restore_and_exit();
}
@@ -160,8 +160,8 @@ void checkIntegrity(void) { if (walker->magicNumber != MAGIC_NUMBER) { - fprintf(stderr, "checkIntegrity - invalid magic number in header: %08x, malloc tag = %d\n", walker->magicNumber, walker->tag); - exit(1); + debug_output( 0, "checkIntegrity - invalid magic number in header: %08x, malloc tag = %d\n", walker->magicNumber, walker->tag ); + restore_and_exit(); }
memory = (unsigned char *)walker; @@ -170,21 +170,18 @@ void checkIntegrity(void)
if (chunkTrailer->magicNumber != MAGIC_NUMBER) { - fprintf(stderr, "checkIntegrity - invalid magic number in trailer: %08x, malloc tag = %d\n", chunkTrailer->magicNumber, walker->tag); - exit(1); + debug_output( 0, "checkIntegrity - invalid magic number in trailer: %08x, malloc tag = %d\n", chunkTrailer->magicNumber, walker->tag ); + restore_and_exit(); } } }
void checkLeak(void) { - struct chunkHeader *walker;
for (walker = chunkList; walker != NULL; walker = walker->next) - fprintf(stderr, "Memory leak detected, malloc tag = %d\n", walker->tag); - - + debug_output( 0, "Memory leak detected, malloc tag = %d\n", walker->tag ); }
void *debugMalloc(uint32_t length, int32_t tag) @@ -200,8 +197,8 @@ void *debugMalloc(uint32_t length, int32_t tag)
if (memory == NULL) { - fprintf(stderr, "Cannot allocate %u bytes, malloc tag = %d\n", (unsigned int)(length + sizeof(struct chunkHeader) + sizeof(struct chunkTrailer)), tag); - exit(1); + debug_output( 0, "Cannot allocate %u bytes, malloc tag = %d\n", (unsigned int)(length + sizeof(struct chunkHeader) + sizeof(struct chunkTrailer)), tag ); + restore_and_exit(); }
chunkHeader = (struct chunkHeader *)memory; @@ -240,16 +237,16 @@ void *debugRealloc(void *memoryParameter, uint32_t length, int32_t tag)
if (chunkHeader->magicNumber != MAGIC_NUMBER) { - fprintf(stderr, "debugRealloc - invalid magic number in header: %08x, malloc tag = %d\n", chunkHeader->magicNumber, chunkHeader->tag); - exit(1); + debug_output( 0, "debugRealloc - invalid magic number in header: %08x, malloc tag = %d\n", chunkHeader->magicNumber, chunkHeader->tag ); + restore_and_exit(); }
chunkTrailer = (struct chunkTrailer *)(memory + chunkHeader->length);
if (chunkTrailer->magicNumber != MAGIC_NUMBER) { - fprintf(stderr, "debugRealloc - invalid magic number in trailer: %08x, malloc tag = %d\n", chunkTrailer->magicNumber, chunkHeader->tag); - exit(1); + debug_output( 0, "debugRealloc - invalid magic number in trailer: %08x, malloc tag = %d\n", chunkTrailer->magicNumber, chunkHeader->tag ); + restore_and_exit(); } }
@@ -282,8 +279,8 @@ void debugFree(void *memoryParameter, int tag)
if (chunkHeader->magicNumber != MAGIC_NUMBER) { - fprintf(stderr, "debugFree - invalid magic number in header: %08x, malloc tag = %d, free tag = %d\n", chunkHeader->magicNumber, chunkHeader->tag, tag); - exit(1); + debug_output( 0, "debugFree - invalid magic number in header: %08x, malloc tag = %d, free tag = %d\n", chunkHeader->magicNumber, chunkHeader->tag, tag ); + restore_and_exit(); }
previous = NULL; @@ -298,8 +295,8 @@ void debugFree(void *memoryParameter, int tag)
if (walker == NULL) { - fprintf(stderr, "Double free detected, malloc tag = %d, free tag = %d\n", chunkHeader->tag, tag); - exit(1); + debug_output( 0, "Double free detected, malloc tag = %d, free tag = %d\n", chunkHeader->tag, tag ); + restore_and_exit(); }
if (previous == NULL) @@ -312,8 +309,8 @@ void debugFree(void *memoryParameter, int tag)
if (chunkTrailer->magicNumber != MAGIC_NUMBER) { - fprintf(stderr, "debugFree - invalid magic number in trailer: %08x, malloc tag = %d, free tag = %d\n", chunkTrailer->magicNumber, chunkHeader->tag, tag); - exit(1); + debug_output( 0, "debugFree - invalid magic number in trailer: %08x, malloc tag = %d, free tag = %d\n", chunkTrailer->magicNumber, chunkHeader->tag, tag ); + restore_and_exit(); }
#if defined MEMORY_USAGE @@ -344,8 +341,8 @@ void *debugMalloc(uint32_t length, int32_t tag)
if (result == NULL) { - fprintf(stderr, "Cannot allocate %u bytes, malloc tag = %d\n", length, tag); - exit(1); + debug_output( 0, "Cannot allocate %u bytes, malloc tag = %d\n", length, tag ); + restore_and_exit(); }
return result; @@ -359,8 +356,8 @@ void *debugRealloc(void *memory, uint32_t length, int32_t tag)
if (result == NULL) { - fprintf(stderr, "Cannot re-allocate %u bytes, malloc tag = %d\n", length, tag); - exit(1); + debug_output( 0, "Cannot re-allocate %u bytes, malloc tag = %d\n", length, tag ); + restore_and_exit(); }
return result; diff --git a/batman.h b/batman.h index 8b49a0f..2d4b0ea 100644 --- a/batman.h +++ b/batman.h @@ -194,12 +194,12 @@ struct unix_client { struct list_head list; int32_t sock; uint8_t debug_level; - struct sockaddr_un addr; };
struct debug_clients { void *fd_list[4]; int16_t clients_num[4]; + pthread_mutex_t *mutex[4]; };
struct debug_level_info { diff --git a/os.h b/os.h index 2ef174a..ec02f30 100644 --- a/os.h +++ b/os.h @@ -35,6 +35,7 @@ void add_del_route( uint32_t dest, uint16_t netmask, uint32_t router, int8_t del int8_t is_aborted(); void handler( int32_t sig ); void segmentation_fault( int32_t sig ); +void restore_and_exit();
int8_t receive_packet( unsigned char *packet_buff, int32_t packet_buff_len, int16_t *hna_buff_len, uint32_t *neigh, uint32_t timeout, struct batman_if **if_incoming ); diff --git a/posix-specific.c b/posix-specific.c index 2a5fda3..a09c16e 100644 --- a/posix-specific.c +++ b/posix-specific.c @@ -41,7 +41,7 @@
#include "os.h" #include "orginator.h" -#include "batman-specific.h" +#include "batman.h"
@@ -102,29 +102,40 @@ void debug_output( int8_t debug_prio, char *format, ... ) {
if ( debug_clients.clients_num[debug_prio_intern] > 0 ) {
- va_start( args, format ); + if ( pthread_mutex_trylock( (pthread_mutex_t *)debug_clients.mutex[debug_prio_intern] ) == 0 ) {
- list_for_each( debug_pos, (struct list_head *)debug_clients.fd_list[debug_prio_intern] ) { + va_start( args, format );
- debug_level_info = list_entry(debug_pos, struct debug_level_info, list); + list_for_each( debug_pos, (struct list_head *)debug_clients.fd_list[debug_prio_intern] ) {
- if ( debug_prio_intern == 3 ) - dprintf( debug_level_info->fd, "[%10u] ", get_time() ); + debug_level_info = list_entry(debug_pos, struct debug_level_info, list);
- if ( ( ( debug_level == 1 ) || ( debug_level == 2 ) ) && ( debug_level_info->fd == 1 ) && ( strncmp( format, "BOD\n", 3 ) == 0 ) ) { + if ( debug_prio_intern == 3 ) + dprintf( debug_level_info->fd, "[%10u] ", get_time() );
- system( "clear" ); + if ( ( ( debug_level == 1 ) || ( debug_level == 2 ) ) && ( debug_level_info->fd == 1 ) && ( strncmp( format, "BOD\n", 3 ) == 0 ) ) {
- } else { + system( "clear" ); + + } else {
- if ( ( ( debug_level != 1 ) && ( debug_level != 2 ) ) || ( debug_level_info->fd != 1 ) || ( strncmp( format, "EOD\n", 3 ) == 0 ) ) - vdprintf( debug_level_info->fd, format, args ); + if ( ( ( debug_level != 1 ) && ( debug_level != 2 ) ) || ( debug_level_info->fd != 1 ) || ( strncmp( format, "EOD\n", 3 ) == 0 ) ) + vdprintf( debug_level_info->fd, format, args ); + + }
}
- } + va_end( args );
- va_end( args ); + if ( pthread_mutex_unlock( (pthread_mutex_t *)debug_clients.mutex[debug_prio_intern] ) < 0 ) + debug_output( 0, "Error - could not unlock mutex (debug_output): %s \n", strerror( errno ) ); + + } else { + + debug_output( 0, "Error - could not trylock mutex (debug_output): %s \n", strerror( errno ) ); + + }
}
@@ -138,6 +149,7 @@ void *unix_listen( void *arg ) { struct debug_level_info *debug_level_info; struct list_head *unix_pos, *unix_pos_tmp, *debug_pos, *debug_pos_tmp; struct timeval tv; + struct sockaddr_un sun_addr; int32_t status, max_sock; int8_t res; unsigned char buff[10]; @@ -156,7 +168,7 @@ void *unix_listen( void *arg ) {
tv.tv_sec = 1; tv.tv_usec = 0; - tmp_wait_sockets = wait_sockets; + memcpy( &tmp_wait_sockets, &wait_sockets, sizeof(fd_set) );
res = select( max_sock + 1, &tmp_wait_sockets, NULL, NULL, &tv );
@@ -168,18 +180,18 @@ void *unix_listen( void *arg ) { unix_client = debugMalloc( sizeof(struct unix_client), 201 ); memset( unix_client, 0, sizeof(struct unix_client) );
- if ( ( unix_client->sock = accept( unix_if.unix_sock, (struct sockaddr *)&unix_client->addr, &sun_size) ) == -1 ) { + if ( ( unix_client->sock = accept( unix_if.unix_sock, (struct sockaddr *)&sun_addr, &sun_size) ) == -1 ) { debug_output( 0, "Error - can't accept unix client: %s\n", strerror(errno) ); continue; }
- INIT_LIST_HEAD(&unix_client->list); + INIT_LIST_HEAD( &unix_client->list );
- FD_SET(unix_client->sock, &wait_sockets); + FD_SET( unix_client->sock, &wait_sockets ); if ( unix_client->sock > max_sock ) max_sock = unix_client->sock;
- list_add_tail(&unix_client->list, &unix_if.client_list); + list_add_tail( &unix_client->list, &unix_if.client_list );
debug_output( 3, "Unix socket: got connection\n" );
@@ -207,6 +219,9 @@ void *unix_listen( void *arg ) {
if ( unix_client->debug_level != 0 ) {
+ if ( pthread_mutex_lock( (pthread_mutex_t *)debug_clients.mutex[(int)unix_client->debug_level - '1'] ) != 0 ) + debug_output( 0, "Error - could not lock mutex (unix_listen => 1): %s \n", strerror( errno ) ); + list_for_each_safe( debug_pos, debug_pos_tmp, (struct list_head *)debug_clients.fd_list[(int)unix_client->debug_level - '1'] ) {
debug_level_info = list_entry(debug_pos, struct debug_level_info, list); @@ -224,10 +239,16 @@ void *unix_listen( void *arg ) {
}
+ if ( pthread_mutex_unlock( (pthread_mutex_t *)debug_clients.mutex[(int)unix_client->debug_level - '1'] ) != 0 ) + debug_output( 0, "Error - could not unlock mutex (unix_listen => 1): %s \n", strerror( errno ) ); + }
if ( unix_client->debug_level != buff[2] ) {
+ if ( pthread_mutex_lock( (pthread_mutex_t *)debug_clients.mutex[(int)buff[2] - '1'] ) != 0 ) + debug_output( 0, "Error - could not lock mutex (unix_listen => 2): %s \n", strerror( errno ) ); + debug_level_info = debugMalloc( sizeof(struct debug_level_info), 202 ); INIT_LIST_HEAD( &debug_level_info->list ); debug_level_info->fd = unix_client->sock; @@ -236,12 +257,17 @@ void *unix_listen( void *arg ) {
unix_client->debug_level = (int)buff[2];
+ if ( pthread_mutex_unlock( (pthread_mutex_t *)debug_clients.mutex[(int)buff[2] - '1'] ) != 0 ) + debug_output( 0, "Error - could not unlock mutex (unix_listen => 2): %s \n", strerror( errno ) ); + } else {
unix_client->debug_level = 0;
}
+ + }
} else { @@ -254,6 +280,9 @@ void *unix_listen( void *arg ) {
if ( unix_client->debug_level != 0 ) {
+ if ( pthread_mutex_lock( (pthread_mutex_t *)debug_clients.mutex[(int)unix_client->debug_level - '1'] ) != 0 ) + debug_output( 0, "Error - could not lock mutex (unix_listen => 3): %s \n", strerror( errno ) ); + list_for_each_safe( debug_pos, debug_pos_tmp, (struct list_head *)debug_clients.fd_list[(int)unix_client->debug_level - '1'] ) {
debug_level_info = list_entry(debug_pos, struct debug_level_info, list); @@ -271,6 +300,9 @@ void *unix_listen( void *arg ) {
}
+ if ( pthread_mutex_unlock( (pthread_mutex_t *)debug_clients.mutex[(int)unix_client->debug_level - '1'] ) != 0 ) + debug_output( 0, "Error - could not unlock mutex (unix_listen => 3): %s \n", strerror( errno ) ); + }
debug_output( 3, "Unix client closed connection ...\n" ); @@ -585,6 +617,8 @@ void apply_init_args( int argc, char *argv[] ) {
debug_clients.fd_list[res] = debugMalloc( sizeof(struct list_head), 204 ); INIT_LIST_HEAD( (struct list_head *)debug_clients.fd_list[res] ); + debug_clients.mutex[res] = debugMalloc( sizeof(pthread_mutex_t), 209 ); + pthread_mutex_init( (pthread_mutex_t *)debug_clients.mutex[res], NULL );
}
@@ -770,7 +804,7 @@ void apply_init_args( int argc, char *argv[] ) {
} else if ( strncmp( buff_ptr, "BOD", 3 ) == 0 ) {
- if ( ! batch_mode ) + if ( !batch_mode ) system( "clear" );
} else { @@ -1585,20 +1619,28 @@ void *gw_listen( void *arg ) {
-void segmentation_fault( int32_t sig ) { +void restore_and_exit() {
- debug_output( 0, "Error - SIGSEGV received !\n" ); + purge_orig( get_time() + ( 5 * TIMEOUT ) + orginator_interval );
restore_defaults();
- purge_orig( get_time() + ( 5 * TIMEOUT ) + orginator_interval ); - exit(EXIT_FAILURE);
}
+void segmentation_fault( int32_t sig ) { + + debug_output( 0, "Error - SIGSEGV received !\n" ); + + restore_and_exit(); + +} + + + void cleanup() {
int8_t i; @@ -1622,6 +1664,7 @@ void cleanup() { }
debugFree( debug_clients.fd_list[i], 1218 ); + debugFree( debug_clients.mutex[i], 1219 );
}