extern void WPSourceClose( wp_srcfile * wpsrc_file ) /**************************************************/ { if( wpsrc_file != NULL ) { FDoneSource( wpsrc_file->src_file ); if( wpsrc_file->src_buff != NULL ) { ProfFree( wpsrc_file->src_buff ); } ProfFree( wpsrc_file ); } }
char *AddPath( char *old_list, const char *path_list ) /***************************************************/ { size_t len; size_t old_len; char *new_list; char *p; new_list = old_list; if( path_list != NULL && *path_list != NULLCHAR ) { len = strlen( path_list ); if( old_list == NULL ) { p = new_list = ProfAlloc( len + 1 ); } else { old_len = strlen( old_list ); new_list = ProfAlloc( old_len + 1 + len + 1 ); memcpy( new_list, old_list, old_len ); ProfFree( old_list ); p = new_list + old_len; } while( *path_list != NULLCHAR ) { if( p != new_list ) *p++ = PATH_LIST_SEP; path_list = GetPathElement( path_list, NULL, &p ); } *p = NULLCHAR; } return( new_list ); }
void WPAsmClose( wp_asmfile * wpasm_file ) /****************************************/ { wp_asmline * asm_line; int row; int asm_group; int asm_row; if( wpasm_file != NULL ) { if( wpasm_file->asm_data != NULL ) { row = 0; while( row < wpasm_file->asm_rows ) { asm_line = WPGetAsmLoc( wpasm_file, row, &asm_group, &asm_row ); if( asm_line->source_line ) { FDoneSource( asm_line->u.src.src_file ); } row++; } row = wpasm_file->asm_rows; asm_group = 0; for( ;; ) { ProfFree( wpasm_file->asm_data[asm_group++].asm_lines ); row -= MAX_ASM_LINE_INDEX; if( row < 0 ) break; } ProfFree( wpasm_file->asm_data ); } if( wpasm_file->asm_buff != NULL ) { ProfFree( wpasm_file->asm_buff ); } if( wpasm_file->fh != 0 ) { ExeClose( wpasm_file->fh ); } ProfFree( wpasm_file ); } }
void DlgAbout( void ) /*******************/ { char *about_data; char *about_rover; size_t about_len; int index; about_len = 0; for( index = 0; index < AboutSize; ++index ) { about_len += strlen( AboutMessage[index] ) + 1; } about_data = ProfAlloc( about_len+1 ); about_rover = about_data; for( index = 0; index < AboutSize; ++index ) { about_len = strlen( AboutMessage[index] ); memcpy( about_rover, AboutMessage[index], about_len ); about_rover += about_len; *about_rover++ = '\r'; } *about_rover = NULLCHAR; WndDisplayMessage( about_data, LIT( About_WPROF ), GUI_INFORMATION ); ProfFree( about_data ); }
STATIC bint procCmd( char * cmd ) /*******************************/ { char *rover; int name_len; int old_len; int cmd_type; int index; bint do_report; bint do_option; do_report = P_FALSE; for( ;; ) { cmd = eatBlanks( cmd ); if( *cmd == NULLCHAR ) break; #ifdef __UNIX__ if( *cmd == '-' ) { #else if( *cmd == '-' || *cmd == '/' ) { #endif do_option = P_TRUE; ++cmd; cmd_type = minLook( &cmd ); } else if( *cmd == '?' ) { do_option = P_TRUE; cmd_type = HELP_OPT; } else { do_option = P_FALSE; rover = cmd; cmd = eatAllChars( cmd ); name_len = cmd - rover; if( name_len > _MAX_PATH ) { name_len = _MAX_PATH; } memcpy( SamplePath, rover, name_len ); SamplePath[name_len] = NULLCHAR; } if( do_option ) { switch( cmd_type ) { case FAIL_OPT: ErrorMsg( LIT( Cmd_Option_Not_Valid ), cmd-1 ); #if defined( __WINDOWS__ ) || defined( __NT__ ) || defined( __OS2_PM__ ) fatal( LIT( Usage ) ); #else /* fall through */ #endif case HELP_OPT: index = 0; while( cmdUsage[index] ) { ErrorMsg( cmdUsage[index++] ); } exit( 0 ); case DIP_OPT: cmd = eatBlanks( cmd ); if( *cmd == '=' ) { cmd = eatBlanks( cmd+1 ); } rover = cmd; cmd = eatAlphaNum( cmd ); if( *cmd == NULLCHAR || cmd-rover == 0 ) { if( WProfDips != NULL ) { ProfFree( WProfDips ); WProfDips = NULL; WProfDipSize = 0; } } else { name_len = cmd - rover; old_len = WProfDipSize; WProfDipSize = old_len + name_len + 1; if( old_len == 0 ) { WProfDipSize++; } else { old_len--; } WProfDips = ProfRealloc( WProfDips, WProfDipSize ); memcpy( WProfDips+old_len, rover, name_len ); old_len += name_len; WProfDips[old_len++] = NULLCHAR; WProfDips[old_len] = NULLCHAR; } break; #if defined( __DOS__ ) case NOGRAPHICSMOUSE_OPT: case NOCHARREMAP_OPT: WndStyle &= ~(GUI_CHARMAP_DLG|GUI_CHARMAP_MOUSE); break; #endif #ifndef NDEBUG case R_OPT: do_report = P_TRUE; break; #endif } } } return( do_report ); } STATIC char * eatBlanks( char * cmd ) { /*************************************/ while( isspace( *cmd ) && *cmd != NULLCHAR ) { ++cmd; } return( cmd ); } STATIC char * eatAlphaNum( char * cmd ) { /***************************************/ while( isalnum( *cmd ) && *cmd != NULLCHAR ) { ++cmd; } return( cmd ); } STATIC char * eatAllChars( char * cmd ) { /***************************************/ while( !isspace( *cmd ) && *cmd != NULLCHAR ) { ++cmd; } return( cmd ); } STATIC int minLook( char * * value ) { /************************************/ int index; int curr_len; char * * strtab; byte * lentab; char * strlook; char * strchck; char * base_val; char check_char; base_val = *value; lentab = cmdLen; strtab = cmdNames; index = 0; for(;;) { strlook = *strtab++; if( strlook == NULL ) { return( FAIL_OPT ); } strchck = base_val; curr_len = 0; for(;;) { check_char = tolower( *strchck ); if( check_char == NULLCHAR || !(isalpha( check_char ) || check_char == '?') ) { if( curr_len >= *lentab ) { *value += curr_len; return( cmdType[index] ); } break; } if( *strlook != check_char ) break; strlook++; strchck++; curr_len++; } lentab++; index++; } }
STATIC void calcAggregates( void ) /********************************/ { unsigned index; unsigned index2; int cmp_result; unsigned *sorted_idx; address ***sorted_vect; massgd_sample_addr **massgd_data; // unsigned mbuckets; unsigned curr_mbucket; unsigned curr_midx; thread_data *thd; unsigned buckets; unsigned base; unsigned best; unsigned end; massgd_sample_addr *curr; ClearMassaged( CurrSIOData ); buckets = 0; for( thd = CurrSIOData->samples; thd != NULL; thd = thd->next ) { buckets += RAW_BUCKET_IDX( thd->end_time - thd->start_time ) + 1; } sorted_idx = ProfCAlloc( buckets * sizeof( *sorted_idx ) ); sorted_vect = ProfAlloc( buckets * sizeof(*thd->raw_bucket) ); base = 0; for( thd = CurrSIOData->samples; thd != NULL; thd = thd->next ) { end = RAW_BUCKET_IDX( thd->end_time - thd->start_time ) + 1; for( index = 0; index < end; ++index, ++base ) { sorted_vect[base] = ProfAlloc( MAX_RAW_BUCKET_INDEX * sizeof( **sorted_vect ) ); for( index2 = 0; index2 < MAX_RAW_BUCKET_INDEX; ++index2 ) { sorted_vect[base][index2] = &thd->raw_bucket[index][index2]; } qsort( sorted_vect[base], MAX_RAW_BUCKET_INDEX, sizeof(**sorted_vect), rawSampCmp ); } } /* skip over all the 0:0 samples */ for( index = 0; index < buckets; ++index ) { index2 = 0; for( ;; ) { if( index2 >= MAX_RAW_BUCKET_INDEX ) break; if( !(sorted_vect[index][index2]->mach.segment == 0 && sorted_vect[index][index2]->mach.offset == 0) ) break; ++index2; } sorted_idx[index] = index2; } curr = NULL; curr_mbucket = 0; curr_midx = -1; // mbuckets = 1; massgd_data = ProfAlloc( sizeof( *massgd_data ) ); massgd_data[0] = ProfCAlloc( MAX_MASSGD_BUCKET_SIZE ); for( ;; ) { best = -1U; for( index = 0; index < buckets; ++index ) { index2 = sorted_idx[index]; if( index2 >= MAX_RAW_BUCKET_INDEX ) continue; if( best == -1U ) best = index; cmp_result = AddrCmp( sorted_vect[index][index2], sorted_vect[best][sorted_idx[best]] ); if( cmp_result < 0 ) best = index; } if( best == -1U ) break; if( curr == NULL || AddrCmp( sorted_vect[best][sorted_idx[best]], curr->raw ) != 0 ) { if( ++curr_midx >= MAX_MASSGD_BUCKET_INDEX ) { ++curr_mbucket; massgd_data = ProfRealloc( massgd_data, (curr_mbucket+1) * sizeof(*massgd_data) ); massgd_data[curr_mbucket] = ProfCAlloc( MAX_MASSGD_BUCKET_SIZE ); curr_midx = 0; } curr = &massgd_data[curr_mbucket][curr_midx]; curr->raw = sorted_vect[best][sorted_idx[best]]; } curr->hits++; sorted_idx[best]++; } CurrSIOData->massaged_sample = massgd_data; CurrSIOData->number_massaged = 1 + curr_midx + (curr_mbucket * (unsigned long)MAX_MASSGD_BUCKET_INDEX); CurrSIOData->massaged_mapped = true; for( index = 0; index < buckets; ++index ) { ProfFree( sorted_vect[index] ); } ProfFree( sorted_vect ); ProfFree( sorted_idx ); }
STATIC void loadImageInfo( image_info * curr_image ) /**************************************************/ { int name_len; int object_file; int sym_file; struct stat file_status; sym_file = -1; object_file = -1; curr_image->dip_handle = NO_MOD; if( curr_image->sym_deleted ) { } else if( curr_image->sym_name != NULL ) { sym_file = open( curr_image->sym_name, O_RDONLY|O_BINARY ); if( sym_file != -1 ) { curr_image->dip_handle = WPDipLoadInfo( sym_file, curr_image->sym_name, curr_image, sizeof(image_info), DIP_PRIOR_MIN, DIP_PRIOR_MAX ); } } else { name_len = strlen( curr_image->name ) + 1; memcpy( FNameBuff, curr_image->name, name_len ); ReplaceExt( FNameBuff, ".sym" ); name_len = strlen( FNameBuff ) + 1; curr_image->sym_name = ProfAlloc( name_len ); memcpy( curr_image->sym_name, FNameBuff, name_len ); sym_file = open( curr_image->sym_name, O_RDONLY|O_BINARY ); if( sym_file != -1 ) { curr_image->dip_handle = WPDipLoadInfo( sym_file, curr_image->sym_name, curr_image, sizeof(image_info), DIP_PRIOR_MIN, DIP_PRIOR_MAX ); } if( curr_image->dip_handle == NO_MOD ) { ProfFree( curr_image->sym_name ); curr_image->sym_name = NULL; } } object_file = open( curr_image->name, O_RDONLY|O_BINARY ); if( object_file == -1 ) { curr_image->exe_not_found = true; if( curr_image->main_load ) { ErrorMsg( LIT( Exe_Not_Found ), curr_image->name ); } } else if( curr_image->time_stamp == 0 ) { /* If sample timestamp is 0, the sampler couldn't figure out the right value. Assume it's OK. */ } else if( fstat( object_file, &file_status ) == 0 ) { /* QNX creation dates and time stamps tend to be 1 */ /* unit different, so do not test for equality */ if( file_status.st_mtime - curr_image->time_stamp > 1 ) { curr_image->exe_changed = true; if( curr_image->main_load ) { ErrorMsg( LIT( Exe_Has_Changed ), curr_image->name ); } } } if( curr_image->dip_handle == NO_MOD && !curr_image->sym_deleted && object_file != -1 ) { curr_image->dip_handle = WPDipLoadInfo( object_file, curr_image->name, curr_image, sizeof(image_info), DIP_PRIOR_MIN, DIP_PRIOR_MAX ); } if( curr_image->dip_handle == NO_MOD ) { if( sym_file != -1 ) { close( sym_file ); } if( object_file != -1 ) { close( object_file ); } } initModuleInfo( curr_image ); if( curr_image->dip_handle != NO_MOD ) { WalkModList( curr_image->dip_handle, &loadModuleInfo, curr_image ); } }
STATIC bool readSampleFile( void ) /********************************/ { file_handle fh; uint_16 size; void *buff; int buff_len; off_t start_position; bool main_exe; samp_block_prefix prefix; samp_block_prefix *next_prefix; /* we can add error checking for things like */ /**/ /* - number of samples match the info # of samples */ /* - main exe load if there is an overlay table */ /**/ fh = CurrSIOData->fh; start_position = lseek( fh, CurrSIOData->header.sample_start, SEEK_SET ); if( start_position == (off_t) -1 ) { ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name ); return( false ); } if( read( fh, &prefix, SIZE_PREFIX ) != SIZE_PREFIX ) { ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name ); return( false ); } buff = ProfAlloc( SIZE_DATA ); buff_len = SIZE_DATA; main_exe = false; while( prefix.kind != SAMP_LAST ) { size = prefix.length; if( buff_len < size ) { buff = ProfRealloc( buff, size ); buff_len = size; } /* reads data & next prefix */ if( BigRead( fh, buff, size ) != size ) { ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name ); ProfFree( buff ); return( false ); } next_prefix = (void *)( ((char *) buff) + ( size - SIZE_PREFIX )); /* if we're reading a sample record from a callgraph sample */ /* file, the next record should contain callgraph information */ /* which we will also want stored in memory for processing */ /* 16-jul-92 CMS */ // if( CallGraph && prefix.kind == SAMP_SAMPLES && // next_prefix->kind == SAMP_CALLGRAPH ) { // size = next_prefix->length; // /* reads callgraph data & next prefix */ // if( BigRead( fh, next_prefix, size ) != size ) { // errorIO(); // ProfFree( buff ); // ErrorMsg( LIT( Smp_File_IO_Err ), CurrSIOData->samp_file_name ); // return( false ); // } // next_prefix = (void *)( ((char *) next_prefix) + ( size - SIZE_PREFIX )); // } switch( prefix.kind ) { case SAMP_INFO: procInfoBlock( prefix.tick, buff ); break; case SAMP_SAMPLES: if( !procSampleBlock( prefix.tick, prefix.length, buff ) ) { return( false ); } break; case SAMP_MARK: procMarkBlock( prefix.tick, buff ); break; case SAMP_OVL_LOAD: procOverlayBlock( prefix.tick, buff ); break; case SAMP_ADDR_MAP: procAddrBlock( prefix.length, buff ); break; case SAMP_MAIN_LOAD: main_exe = true; /* fall through */ case SAMP_CODE_LOAD: procImageBlock( buff, main_exe ); main_exe = false; break; case SAMP_REMAP_SECTION: procRemapBlock( prefix.tick, prefix.length, buff ); break; case SAMP_CALLGRAPH: // printf( "sample callgraph\n" ); break; } prefix = *next_prefix; } ProfFree( buff ); return( true ); }