From 2e12986647a8c2dae05d7261988327e5f8324275 Mon Sep 17 00:00:00 2001 From: Taylor Richards Date: Wed, 15 Dec 2004 04:10:45 +0000 Subject: [PATCH] outwnd_unix.cpp from fs2_open for logging to file in debug mode fixes for default function values always use vm_* functions for sanity sake make cfilearchiver 64-bit compatible fix crash on exit from double free() fix crash on startup from extra long GL extension string in debug --- Makefile | 1 + include/pstypes.h | 27 +- include/unix.h | 6 - src/cfilearchiver/cfilearchiver.cpp | 14 +- src/graphics/gropengl.cpp | 35 ++- src/menuui/readyroom.cpp | 33 ++- src/osapi/os_unix.cpp | 12 + src/osapi/outwnd_unix.cpp | 443 ++++++++++++++++++++++++++++ src/platform/unix.cpp | 23 +- 9 files changed, 565 insertions(+), 29 deletions(-) create mode 100644 src/osapi/outwnd_unix.cpp diff --git a/Makefile b/Makefile index 5021f13..f33d437 100644 --- a/Makefile +++ b/Makefile @@ -158,6 +158,7 @@ CODE_SOURCES =./src/anim/animplay.cpp \ ./src/observer/observer.cpp \ ./src/osapi/os_unix.cpp \ ./src/osapi/osregistry-unix.cpp \ + ./src/osapi/outwnd_unix.cpp \ ./src/palman/palman.cpp \ ./src/parse/encrypt.cpp \ ./src/parse/parselo.cpp \ diff --git a/include/pstypes.h b/include/pstypes.h index 2277eed..7f05bc7 100644 --- a/include/pstypes.h +++ b/include/pstypes.h @@ -15,6 +15,14 @@ * Header file containg global typedefs, constants and macros * * $Log$ + * Revision 1.11 2004/12/15 04:10:45 taylor + * outwnd_unix.cpp from fs2_open for logging to file in debug mode + * fixes for default function values + * always use vm_* functions for sanity sake + * make cfilearchiver 64-bit compatible + * fix crash on exit from double free() + * fix crash on startup from extra long GL extension string in debug + * * Revision 1.10 2004/07/04 11:31:43 taylor * amd64 support, compiler warning fixes, don't use software rendering * @@ -253,6 +261,7 @@ #ifdef PLAT_UNIX #include "unix.h" #endif + // value to represent an uninitialized state in any int or uint #define UNINITIALIZED 0x7f8e6d9c @@ -407,9 +416,11 @@ extern void _cdecl Warning( char * filename, int line, char * format, ... ); #if defined(NDEBUG) #define Assert(x) do {} while (0) +#define STUB_FUNCTION #else void gr_activate(int); #define Assert(x) do { if (!(x)){ gr_activate(0); WinAssert(#x,__FILE__,__LINE__); gr_activate(1); } } while (0) +#define STUB_FUNCTION mprintf(("STUB: %s at %s, line %d, thread %d\n", __FUNCTION__, LOCATION, getpid())) #endif //#define Int3() _asm { int 3 } @@ -755,13 +766,13 @@ template void CAP( T& v, T mn, T mx ) int vm_init(int min_heap_size); // Allocates some RAM. -// void *vm_malloc( int size ); + void *vm_malloc( int size ); // -// char *vm_strdup( const char *ptr ); + char *vm_strdup( const char *ptr ); // Frees some RAM. -// void vm_free( void *ptr ); + void vm_free( void *ptr ); // Frees all RAM. void vm_free_all(); @@ -770,12 +781,10 @@ template void CAP( T& v, T mn, T mx ) #define VM_MALLOC(size) vm_malloc(size) #define VM_FREE(ptr) vm_free(ptr) -// #define malloc(size) vm_malloc(size) -// #define free(ptr) vm_free(ptr) -// #define strdup(ptr) vm_strdup(ptr) - #define vm_malloc(size) malloc(size) - #define vm_free(ptr) free(ptr) - #define vm_strdup(ptr) strdup(ptr) + #define malloc(size) vm_malloc(size) + #define free(ptr) vm_free(ptr) + #define strdup(ptr) vm_strdup(ptr) + #endif diff --git a/include/unix.h b/include/unix.h index c3e5cf4..0ed1678 100644 --- a/include/unix.h +++ b/include/unix.h @@ -88,12 +88,6 @@ typedef struct { #define CRITICAL_SECTION SDL_mutex* -#ifndef NDEBUG -#define STUB_FUNCTION fprintf(stderr,"STUB: %s at " __FILE__ ", line %d, thread %d\n",__FUNCTION__,__LINE__,getpid()) -#else -#define STUB_FUNCTION -#endif - #define closesocket(A) close(A) #define CopyMemory(A,B,C) memcpy(A,B,C) #define UINT unsigned int diff --git a/src/cfilearchiver/cfilearchiver.cpp b/src/cfilearchiver/cfilearchiver.cpp index 460faa4..4100322 100644 --- a/src/cfilearchiver/cfilearchiver.cpp +++ b/src/cfilearchiver/cfilearchiver.cpp @@ -15,6 +15,14 @@ * Program to create an archive file for use with cfile stuff * * $Log$ + * Revision 1.6 2004/12/15 04:10:45 taylor + * outwnd_unix.cpp from fs2_open for logging to file in debug mode + * fixes for default function values + * always use vm_* functions for sanity sake + * make cfilearchiver 64-bit compatible + * fix crash on exit from double free() + * fix crash on startup from extra long GL extension string in debug + * * Revision 1.5 2003/05/04 04:49:48 taylor * improve error handling, instructions * @@ -102,7 +110,7 @@ int write_index(char *hf, char *df) return 1; } -void pack_file( char *filespec, char *filename, int filesize, time_t time_write ) +void pack_file( char *filespec, char *filename, int filesize, fs_time_t time_write ) { char path[1024]; @@ -130,7 +138,7 @@ void pack_file( char *filespec, char *filename, int filesize, time_t time_write fwrite( &Total_size, 1, 4, fp_out_hdr ); fwrite( &filesize, 1, 4, fp_out_hdr ); fwrite( &path, 1, 32, fp_out_hdr ); - fwrite( &time_write, 1, sizeof(time_t), fp_out_hdr); + fwrite( &time_write, 1, sizeof(fs_time_t), fp_out_hdr); Total_size += filesize; Num_files++; @@ -250,7 +258,7 @@ void pack_directory( char * filespec) pack_directory(tmp); } } else { - pack_file( filespec, find.name, find.size, find.time_write ); + pack_file( filespec, find.name, find.size, (fs_time_t)find.time_write ); } while( !_findnext( find_handle, &find ) ) { diff --git a/src/graphics/gropengl.cpp b/src/graphics/gropengl.cpp index d3c9f89..48170fb 100644 --- a/src/graphics/gropengl.cpp +++ b/src/graphics/gropengl.cpp @@ -15,6 +15,14 @@ * Code that uses the OpenGL graphics library * * $Log$ + * Revision 1.71 2004/12/15 04:10:45 taylor + * outwnd_unix.cpp from fs2_open for logging to file in debug mode + * fixes for default function values + * always use vm_* functions for sanity sake + * make cfilearchiver 64-bit compatible + * fix crash on exit from double free() + * fix crash on startup from extra long GL extension string in debug + * * Revision 1.70 2004/09/20 01:31:44 theoddone33 * GCC 3.4 fixes. * @@ -666,7 +674,7 @@ void gr_opengl_reset_clip() // glScissor(0, 0, gr_screen.max_w, gr_screen.max_h); } -void gr_opengl_set_bitmap( int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha, int sx, int sy ) +void gr_opengl_set_bitmap( int bitmap_num, int alphablend_mode = GR_ALPHABLEND_NONE, int bitblt_mode = GR_BITBLT_MODE_NORMAL, float alpha = 1.0f, int sx = -1, int sy = -1 ) { gr_screen.current_alpha = alpha; gr_screen.current_alphablend_mode = alphablend_mode; @@ -2855,8 +2863,31 @@ void gr_opengl_init() mprintf(( "Vendor : %s\n", glGetString(GL_VENDOR) )); mprintf(( "Renderer : %s\n", glGetString(GL_RENDERER) )); mprintf(( "Version : %s\n", glGetString(GL_VERSION) )); - mprintf(( "Extensions : %s\n", glGetString(GL_EXTENSIONS) )); + +#ifndef NDEBUG + // print out extensions - taken from FS2_Open (credits: phreak, taylor) + mprintf(( "Extensions : \n")); + + static const char *OGL_extensions = (const char*)glGetString(GL_EXTENSIONS); + + char *extlist = (char*)malloc(strlen(OGL_extensions)); + + if (extlist != NULL) { + memcpy(extlist, OGL_extensions, strlen(OGL_extensions)); + + char *curext = strtok(extlist, " "); + + while (curext) { + mprintf(( " %s\n", curext )); + curext = strtok(NULL, " "); + } + + free(extlist); + extlist = NULL; + } + mprintf(( "\n" )); +#endif int value; int rgb_size[3]; diff --git a/src/menuui/readyroom.cpp b/src/menuui/readyroom.cpp index 20032b0..44847d4 100644 --- a/src/menuui/readyroom.cpp +++ b/src/menuui/readyroom.cpp @@ -15,6 +15,14 @@ * Ready Room code, which is the UI screen for selecting Campaign/mission to play next mainly. * * $Log$ + * Revision 1.7 2004/12/15 04:10:45 taylor + * outwnd_unix.cpp from fs2_open for logging to file in debug mode + * fixes for default function values + * always use vm_* functions for sanity sake + * make cfilearchiver 64-bit compatible + * fix crash on exit from double free() + * fix crash on startup from extra long GL extension string in debug + * * Revision 1.6 2004/09/20 01:31:44 theoddone33 * GCC 3.4 fixes. * @@ -1885,20 +1893,31 @@ void campaign_room_close() { int i; - for (i=0; i= 0) bm_unload(Background_bitmap); - if (Campaign_names_inited) - for (i=0; i +#include +#include + +#include "pstypes.h" +#include "outwnd.h" +#include "osapi.h" +#include "osregistry.h" +#include "cfile.h" +#include "cfilesystem.h" + +extern cf_pathtype Pathtypes[CF_MAX_PATH_TYPES]; + + +void outwnd_print(char *id, char *tmp); + +#define MAX_FILTERS 48 +#define MAX_LINE_WIDTH 128 + +bool outwnd_inited = false; +bool outwnd_disabled = true; +bool OutputActive = false; +int Outwnd_no_filter_file = 0; // 0 = .cfg file found, 1 = not found and warning not printed yet, 2 = not found and warning printed + +struct outwnd_filter_struct { + char name[FILTER_NAME_LENGTH]; + int state; +} *outwnd_filter[MAX_FILTERS], real_outwnd_filter[MAX_FILTERS]; + + +int outwnd_filter_count = 0; +int outwnd_filter_loaded = 0; + +// used for file logging +#ifndef NDEBUG + int Log_debug_output_to_file = 1; + FILE *Log_fp; + char *Freespace_logfilename = "fs_debug.log"; +#endif + +void load_filter_info(void) +{ + FILE *fp; + char pathname[MAX_PATH_LEN]; + char inbuf[FILTER_NAME_LENGTH+4]; + int z; + + outwnd_filter_loaded = 1; + outwnd_filter_count = 0; + + snprintf(pathname, MAX_PATH_LEN, "%s/%s/%s/", detect_home(), Osreg_user_dir, Pathtypes[CF_TYPE_DATA].path); + strcat(pathname, "debug_filter.cfg" ); + + fp = fopen(pathname, "rt"); + if (!fp) { + Outwnd_no_filter_file = 1; + + outwnd_filter[outwnd_filter_count] = &real_outwnd_filter[outwnd_filter_count]; + strcpy( outwnd_filter[outwnd_filter_count]->name, "error" ); + outwnd_filter[outwnd_filter_count]->state = 1; + outwnd_filter_count++; + + outwnd_filter[outwnd_filter_count] = &real_outwnd_filter[outwnd_filter_count]; + strcpy( outwnd_filter[outwnd_filter_count]->name, "general" ); + outwnd_filter[outwnd_filter_count]->state = 1; + outwnd_filter_count++; + + outwnd_filter[outwnd_filter_count] = &real_outwnd_filter[outwnd_filter_count]; + strcpy( outwnd_filter[outwnd_filter_count]->name, "warning" ); + outwnd_filter[outwnd_filter_count]->state = 1; + outwnd_filter_count++; + + return; + } + + Outwnd_no_filter_file = 0; + + while (fgets(inbuf, FILTER_NAME_LENGTH+3, fp)) + { + if (outwnd_filter_count == MAX_FILTERS) + break; + + outwnd_filter[outwnd_filter_count] = &real_outwnd_filter[outwnd_filter_count]; + if (*inbuf == '+') + outwnd_filter[outwnd_filter_count]->state = 1; + else if (*inbuf == '-') + outwnd_filter[outwnd_filter_count]->state = 0; + else continue; // skip everything else + + z = strlen(inbuf) - 1; + if (inbuf[z] == '\n') + inbuf[z] = 0; + + Assert(strlen(inbuf+1) < FILTER_NAME_LENGTH); + strcpy(outwnd_filter[outwnd_filter_count]->name, inbuf + 1); + + if ( !stricmp( outwnd_filter[outwnd_filter_count]->name, "error" ) ) { + outwnd_filter[outwnd_filter_count]->state = 1; + } else if ( !stricmp( outwnd_filter[outwnd_filter_count]->name, "general" ) ) { + outwnd_filter[outwnd_filter_count]->state = 1; + } else if ( !stricmp( outwnd_filter[outwnd_filter_count]->name, "warning" ) ) { + outwnd_filter[outwnd_filter_count]->state = 1; + } + + outwnd_filter_count++; + } + + if (ferror(fp) && !feof(fp)) + nprintf(("Error", "Error reading \"%s\"\n", pathname)); + + fclose(fp); +} + +void save_filter_info(void) +{ + FILE *fp; + int i; + char pathname[MAX_PATH_LEN]; + + if (!outwnd_filter_loaded) + return; + + if ( Outwnd_no_filter_file ) { + return; // No file, don't save + } + + snprintf(pathname, MAX_PATH_LEN, "%s/%s/%s/", detect_home(), Osreg_user_dir, Pathtypes[CF_TYPE_DATA].path); + strcat(pathname, "debug_filter.cfg" ); + + fp = fopen(pathname, "wt"); + if (fp) + { + for (i=0; istate ? '+' : '-', outwnd_filter[i]->name); + + fclose(fp); + } +} + +void outwnd_printf2(char *format, ...) +{ + char tmp[MAX_LINE_WIDTH*4]; + va_list args; + + va_start(args, format); + vsprintf(tmp, format, args); + va_end(args); + outwnd_print("General", tmp); +} + +void outwnd_printf(char *id, char *format, ...) +{ + char tmp[MAX_LINE_WIDTH*4]; + va_list args; + + va_start(args, format); + vsprintf(tmp, format, args); + va_end(args); + outwnd_print(id, tmp); +} + +void outwnd_print(char *id, char *tmp) +{ + int i; + outwnd_filter_struct *temp; + + if (!outwnd_inited) { + fputs("outwnd not initialized yet... ", stdout); + fputs(tmp, stdout); + fflush(stdout); + return; + } + + if ( Outwnd_no_filter_file == 1 ) { + Outwnd_no_filter_file = 2; + + outwnd_print( "general", "==========================================================================\n" ); + outwnd_print( "general", "DEBUG SPEW: No debug_filter.cfg found, so only general, error, and warning\n" ); + outwnd_print( "general", "categories can be shown and no debug_filter.cfg info will be saved.\n" ); + outwnd_print( "general", "==========================================================================\n" ); + } + + if (!id) + id = "General"; + + for (i=0; iname)) + break; + + + if (i == outwnd_filter_count) // new id found that's not yet in filter list + { + // Only create new filters if there was a filter file + if ( Outwnd_no_filter_file ) { + return; + } + + if (outwnd_filter_count >= MAX_FILTERS) { + Assert(outwnd_filter_count == MAX_FILTERS); // how did it get over the max? Very bad.. + outwnd_printf("General", "Outwnd filter limit reached. Recycling \"%s\" to add \"%s\"", + outwnd_filter[MAX_FILTERS - 1]->name, id); + + i--; // overwrite the last element (oldest used filter in the list) + } + + Assert(strlen(id) < FILTER_NAME_LENGTH); + outwnd_filter[i] = &real_outwnd_filter[i]; // note: this assumes the list doesn't have gaps (from deleting an element for example) + strcpy(outwnd_filter[i]->name, id); + outwnd_filter[i]->state = 1; + outwnd_filter_count = i + 1; + save_filter_info(); + } + + // sort the filters from most recently used to oldest, so oldest ones will get recycled first + temp = outwnd_filter[i]; + while (i--) + outwnd_filter[i + 1] = outwnd_filter[i]; + + i++; + outwnd_filter[i] = temp; + + if (!outwnd_filter[i]->state) + return; + +#ifndef NDEBUG + + if ( Log_debug_output_to_file ) { + if ( Log_fp != NULL ) { + fputs(tmp, Log_fp); + fflush(Log_fp); + } + } else { + fputs(tmp, stdout); + fflush(stdout); + } + +#else + + fputs(tmp, stdout); + fflush(stdout); + +#endif +} + + +void outwnd_init(int display_under_freespace_window) +{ + outwnd_inited = TRUE; + +#ifndef NDEBUG + char pathname[MAX_PATH_LEN]; + + snprintf(pathname, MAX_PATH_LEN, "%s/%s/%s/", detect_home(), Osreg_user_dir, Pathtypes[CF_TYPE_DATA].path); + strcat(pathname, Freespace_logfilename); + + if ( Log_fp == NULL ) { + Log_fp = fopen(pathname, "wb"); + if ( Log_fp == NULL ) { + outwnd_printf("Error", "Error opening %s\n", pathname); + } else { + outwnd_printf("General", "Opened %s OK\n", pathname); + printf("Future debug output directed to: %s\n", pathname); + } + } +#endif +} + +void outwnd_close() +{ +#ifndef NDEBUG + if ( Log_fp != NULL ) { + fclose(Log_fp); + Log_fp = NULL; + } +#endif + +} + +#endif // NDEBUG + +#endif // Goober5000 - #ifndef WIN32 diff --git a/src/platform/unix.cpp b/src/platform/unix.cpp index ffb49e7..611becd 100644 --- a/src/platform/unix.cpp +++ b/src/platform/unix.cpp @@ -8,7 +8,13 @@ #include #include -#include "unix.h" +#include "pstypes.h" + +// use system versions of this stuff in here rather than the vm_* versions +#undef malloc +#undef free +#undef strdup + #define MAX_LINE_WIDTH 128 @@ -112,7 +118,11 @@ typedef struct RAM { static RAM *RamTable; #endif +#ifndef NDEBUG void vm_free(void* ptr, char *file, int line) +#else +void vm_free(void* ptr) +#endif { #ifdef WANT_DEBUG fprintf(stderr, "FREE: %s:%d addr = %p\n", file, line, ptr); @@ -143,7 +153,11 @@ void vm_free(void* ptr, char *file, int line) #endif } +#ifndef NDEBUG void *vm_malloc(int size, char *file, int line) +#else +void *vm_malloc(int size) +#endif { #ifdef WANT_DEBUG fprintf(stderr, "MALLOC: %s:%d %d bytes\n", file, line, size); @@ -164,7 +178,11 @@ void *vm_malloc(int size, char *file, int line) #endif } +#ifndef NDEBUG char *vm_strdup(char const* str, char *file, int line) +#else +char *vm_strdup(char const* str) +#endif { #ifdef WANT_DEBUG fprintf(stderr, "STRDUP: %s:%d\n", file, line); @@ -210,6 +228,7 @@ void windebug_memwatch_init() } /* error message debugging junk */ +/* int Log_debug_output_to_file = 0; void load_filter_info(void) @@ -243,7 +262,7 @@ void outwnd_close() { // STUB_FUNCTION; } - +*/ void Warning( char * filename, int line, char * format, ... ) { char tmp[MAX_LINE_WIDTH*4]; -- 2.39.2