smpdump.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 306 行
C
306 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Execution Sampler data file dump utility.
*
****************************************************************************/
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <malloc.h>
#include <time.h>
#include "watcom.h"
#include "banner.h"
#include "bool.h"
#include "sample.h"
char *Types[] = {
"INFO:",
"SAMPLES:",
"MARK:",
"OVL_LOAD:",
"CODE_LOAD:",
"ADDR_MAP:",
"MAIN_LOAD:",
"LAST:",
"REMAP_SECTIONS:",
"CALLGRAPH:",
""
};
#if defined( __SMALL__ ) || defined( __MEDIUM__ )
#error must be compiled with a large data model
#endif
#define COND_SWAP_16( a ) if( byte_swap ) SWAP_16( a );
#define COND_SWAP_32( a ) if( byte_swap ) SWAP_32( a );
static char path[_MAX_PATH];
static char drv[_MAX_DRIVE];
static char dir[_MAX_DIR];
static char name[_MAX_FNAME];
static char ext[_MAX_EXT];
int main( int argc, char **argv )
{
char quiet;
int fd;
unsigned wanted;
unsigned i, j, k, l;
int length = 0;
off_t head_off;
char * record_type;
samp_block * data;
auto samp_header head;
cgraph_sample * sptr;
auto struct stat file_stat;
time_t stamp;
count_info *count;
bool byte_swap = FALSE;
puts( banner1w( "Sample File Dump Utility", _WSAMP_VERSION_ ) );
puts( banner2( "1989" ) );
puts( banner3 );
puts( banner3a );
if( argc != 2 && argc != 3 ) {
puts( "usage: smpdump <sample_file> [-q]" );
exit( 1 );
}
data = malloc( 63L * 1024 + 512 );
quiet = 0;
if( argc == 3 && strcmp( argv[2], "-q" ) == 0 ) {
quiet = 1;
}
_splitpath( argv[ 1 ], drv, dir, name, ext );
if( ext[ 0 ] == '\0' ) {
strcpy( ext, ".smp" );
}
_makepath( path, drv, dir, name, ext );
fd = open( path, O_BINARY | O_RDONLY, 0 );
if( fd == -1 )
return( 1 );
head_off = lseek( fd, -(long)SIZE_HEADER, SEEK_END );
if( head_off == -1 )
return( 1 );
read( fd, &head, SIZE_HEADER );
if( head.signature != SAMP_SIGNATURE ) {
SWAP_16( head.signature );
if( head.signature == SAMP_SIGNATURE ) {
byte_swap = TRUE;
SWAP_32( head.sample_start );
} else {
return( 1 );
}
}
printf( "Sample file version: %u.%u\n", head.major_ver, head.minor_ver );
lseek( fd, head.sample_start, SEEK_SET );
for( ;; ) {
/* read the prefix of record */
wanted = sizeof( data->pref );
if( read( fd, &data->pref, wanted ) != wanted ) break;
COND_SWAP_32( data->pref.tick );
COND_SWAP_16( data->pref.length );
COND_SWAP_16( data->pref.kind );
/* read the rest of the record */
wanted = data->pref.length - sizeof( data->pref );
if( read( fd, &data->d, wanted ) != wanted ) break;
/* dump common record data */
record_type = "** UNKNOWN **";
if( data->pref.kind < NUM_BLOCK_KINDS ) {
record_type = Types[ data->pref.kind ];
}
printf( "%s tick %lu length %u\n", record_type,
data->pref.tick, data->pref.length );
/* dump specific record data */
switch( data->pref.kind ) {
case SAMP_INFO:
COND_SWAP_32( data->d.info.timer_rate );
printf( " timer rate %ld ms\n", data->d.info.timer_rate / 1000 );
l = data->pref.length;
if( head.major_ver == 2 && head.minor_ver <= 1 ) {
count = &data->d.old_info.count[0];
l -= offsetof( samp_block, d.old_info.count );
} else {
COND_SWAP_16( data->d.info.config.mad );
printf( " cpu=%d, fpu=%d, os_maj=%d, os_min=%d, os=%d, mad=%d\n",
data->d.info.config.cpu, data->d.info.config.fpu,
data->d.info.config.osmajor, data->d.info.config.osminor,
data->d.info.config.os, data->d.info.config.mad );
count = &data->d.info.count[0];
l -= offsetof( samp_block, d.info.count );
}
l /= sizeof( count_info );
for( i = 0; i < l; ++i ) {
COND_SWAP_32( count[i].number );
COND_SWAP_32( count[i].size );
printf( " %s number %lu size %lu\n", Types[i],
count[i].number, count[i].size );
}
break;
case SAMP_SAMPLES:
j = data->pref.length;
j -= offsetof( samp_block, d.sample.sample );
j /= sizeof( samp_address );
COND_SWAP_16( data->d.sample.thread_id );
printf( " thread id %u #samples %u\n",
data->d.sample.thread_id, j );
if( quiet ) {
printf( " ....\n ....\n ....\n" );
} else {
for( i = 0; i < j; ++i ) {
COND_SWAP_16( data->d.sample.sample[i].segment );
COND_SWAP_32( data->d.sample.sample[i].offset );
printf( " - %.4x:%.8lx\n",
data->d.sample.sample[i].segment,
data->d.sample.sample[i].offset );
}
}
break;
case SAMP_MARK:
COND_SWAP_16( data->d.sample.thread_id );
COND_SWAP_16( data->d.mark.addr.segment );
COND_SWAP_32( data->d.mark.addr.offset );
printf( " thread %u - %.4x:%.8lx \"%s\"\n",
data->d.mark.thread_id, data->d.mark.addr.segment,
data->d.mark.addr.offset, data->d.mark.mark_string );
break;
case SAMP_OVL_LOAD:
if( data->d.ovl.req_section & OVL_RETURN ) {
printf( " section %u (RETURN)\n",
data->d.ovl.req_section & (~ OVL_RETURN) );
} else {
printf( " section %u\n", data->d.ovl.req_section );
}
printf( " - requesting address = %.4x:%.8lx\n",
data->d.ovl.addr.segment, data->d.ovl.addr.offset );
j = data->pref.length;
j -= offsetof( samp_block, d.ovl.ovl_map );
j /= sizeof( uint_8 );
printf( " - loaded overlay sections = " );
// printf( "%.2x", data->d.ovl.ovl_map[0] );
for( i = 0; i < j; ++i ) {
printf( "%.2x", data->d.ovl.ovl_map[i] );
}
printf( "\n" );
break;
case SAMP_CODE_LOAD:
case SAMP_MAIN_LOAD:
stamp = data->d.code.time_stamp;
COND_SWAP_32( stamp );
COND_SWAP_16( data->d.code.ovl_tab.segment );
COND_SWAP_32( data->d.code.ovl_tab.offset );
printf( " name = \"%s\"\n", data->d.code.name );
printf( " overlay table = %.4x:%.8lx\n",
data->d.code.ovl_tab.segment, data->d.code.ovl_tab.offset );
printf( " time stamp %lx -> %s", stamp,
ctime( &stamp ) );
if( stat( data->d.code.name, &file_stat ) == 0 ) {
printf( " actual time stamp %lx -> %s", file_stat.st_mtime,
ctime( &(file_stat.st_mtime) ) );
}
break;
case SAMP_ADDR_MAP:
j = data->pref.length;
j -= offsetof( samp_block, d.map );
j /= sizeof( data->d.map );
for( i = 0; i < j; ++i ) {
COND_SWAP_16( data->d.map.data[i].map.segment );
COND_SWAP_32( data->d.map.data[i].map.offset );
COND_SWAP_16( data->d.map.data[i].actual.segment );
COND_SWAP_32( data->d.map.data[i].actual.offset );
printf( " - %.4x:%.8lx -> %.4x:%.8lx\n",
data->d.map.data[i].map.segment,
data->d.map.data[i].map.offset,
data->d.map.data[i].actual.segment,
data->d.map.data[i].actual.offset );
}
break;
case SAMP_LAST:
break;
case SAMP_REMAP_SECTION:
j = data->pref.length;
j -= offsetof( samp_block, d.remap );
j /= sizeof( data->d.remap );
for( i = 0; i < j; ++i ) {
COND_SWAP_16( data->d.remap.data[i].section );
COND_SWAP_16( data->d.remap.data[i].segment );
printf( " - %.4x -> %.4x\n",
data->d.remap.data[i].section,
data->d.remap.data[i].segment );
}
break;
case SAMP_CALLGRAPH:
j = data->d.cgraph.number;
printf( " thread id %u #samples %u\n",
data->d.cgraph.thread_id, j );
if( quiet ) {
printf( " ....\n ....\n ....\n" );
} else {
sptr = &data->d.cgraph.sample[0];
for( i = 0; i < j; i++ ) {
if( sptr->push_n != (uint_16)-1 || sptr->pop_n != (uint_16)-1 ) {
length -= sptr->pop_n;
if( length < 0 ) {
printf( "\n** Error: stack exhausted!\n\n" );
} else {
for( k = 0; k < length; k++ ) {
printf( " - " );
}
}
for( k=sptr->push_n; k > 0; k-- ) {
printf( "%.4x:%.8lx ",
sptr->addr[k - 1].segment,
sptr->addr[k - 1].offset );
}
length += sptr->push_n;
printf( "\n" );
sptr = (cgraph_sample *) &(sptr->addr[sptr->push_n]);
} else {
printf( "** Unknown callgraph info\n" );
sptr = (cgraph_sample *) &(sptr->addr[0]);
}
}
}
break;
}
if( data->pref.kind == SAMP_LAST ) break;
}
close( fd );
return( 0 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?