The following commit has been merged in the master branch:
commit da31a7e1fb60507e1b7473fd64cb05721e3359c1
Author: Marek Lindner <lindner_marek(a)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 );
}
--
batman; test conversation