/*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This source code is provided to illustrate the usage of a given feature
* or technique and has been deliberately simplified. Additional steps
* required for a production-quality application, such as security checks,
* input validation and proper error handling, might not be present in
* this sample code.
*/
/* Functionality for checking hprof format=b output. */
/* ONLY used with logflags=4. */
/* Verifies and write a verbose textual version of a format=b file.
* Textual output file is gdata->checkfilename, fd is gdata->check_fd.
* Buffer is in gdata too, see gdata->check* variables.
* Could probably be isolated to a separate library or utility.
*/
#include "hprof.h"
#include "hprof_b_spec.h"
/* For map from HPROF_UTF8 to a string */
typedef struct UmapInfo {
char *str;
} UmapInfo;
/* Field information */
typedef struct Finfo {
} Finfo;
/* Class information map from class ID (ClassIndex) to class information */
typedef struct CmapInfo {
int max_finfo;
int n_finfo;
int inst_size;
} CmapInfo;
/* Read raw bytes from the file image, update the pointer */
static void
{
while ( len > 0 ) {
buf++;
(*pp)++;
len--;
}
}
/* Read various sized elements, properly converted from big to right endian.
* File will contain big endian format.
*/
static unsigned
{
unsigned char b;
return b;
}
static unsigned
{
unsigned short s;
return md_htons(s);
}
static unsigned
{
unsigned int u;
return md_htonl(u);
}
static jlong
{
unsigned int high;
unsigned int low;
jlong x;
x = high;
x = (x << 32) | low;
return x;
}
static HprofId
{
}
/* System error routine */
static void
{
details[0] = 0;
if ( errnum != 0 ) {
} else if ( rc >= 0 ) {
}
if ( details[0] == 0 ) {
}
}
/* Write to a fd */
static void
{
int res;
HPROF_ASSERT(fd>=0);
}
}
/* Flush check buffer */
static void
check_flush(void)
{
return;
}
if (gdata->check_buffer_index) {
gdata->check_buffer_index = 0;
}
}
/* Read out a given typed element */
static jvalue
{
switch ( ty ) {
case 0:
case HPROF_ARRAY_OBJECT:
case HPROF_NORMAL_OBJECT:
break;
case HPROF_BYTE:
case HPROF_BOOLEAN:
break;
case HPROF_CHAR:
case HPROF_SHORT:
break;
case HPROF_FLOAT:
case HPROF_INT:
break;
case HPROF_DOUBLE:
case HPROF_LONG:
break;
default:
break;
}
return val;
}
/* Move arbitrary byte stream into gdata->check_fd */
static void
{
return;
}
if ( len <= 0 ) {
return;
}
check_flush();
return;
}
}
}
/* Printf for gdata->check_fd */
static void
{
return;
}
}
/* Printf of an element for gdata->check_fd */
static void
{
switch ( ty ) {
case HPROF_ARRAY_OBJECT:
break;
case HPROF_NORMAL_OBJECT:
break;
case HPROF_BOOLEAN:
break;
case HPROF_CHAR:
if ( long_form ) {
} else {
}
} else {
} else {
}
}
break;
case HPROF_FLOAT:
break;
case HPROF_DOUBLE:
break;
case HPROF_BYTE:
break;
case HPROF_SHORT:
break;
case HPROF_INT:
break;
case HPROF_LONG:
break;
}
}
/* Printf of a string for gdata->check_fd */
static void
{
int len;
int i;
check_printf("<null>");
}
check_printf("\"");
for (i = 0; i < len; i++) {
unsigned char c;
c = str[i];
if ( isprint(c) ) {
check_printf("%c", c);
} else {
check_printf("\\x%02x", c);
}
}
check_printf("\"");
}
/* Printf of a utf8 id for gdata->check_fd */
static void
{
if ( id == 0 ) {
} else {
if ( uindex == 0 ) {
} else {
}
}
}
/* Add a instance field information to this cmap. */
static void
{
int i;
int osize;
if ( i == 0 ) {
} else {
}
}
}
/* LookupTable callback for cmap entry cleanup */
static void
{
return;
}
}
}
/* Case label for a switch on hprof heap dump elements */
static int
{
int nrecords;
unsigned char *p;
unsigned char *psave;
char *label;
unsigned tag;
int num_elements;
int num_bytes;
int npos;
int i;
int inst_size;
/* First pass over heap records just fills in the CmapInfo table */
nrecords = 0;
p = pstart;
nrecords++;
/*LINTED*/
switch ( tag ) {
break;
break;
thread_serial_num = read_u4(&p);
break;
thread_serial_num = read_u4(&p);
break;
thread_serial_num = read_u4(&p);
break;
break;
thread_serial_num = read_u4(&p);
break;
break;
thread_serial_num = read_u4(&p);
trace_serial_num = read_u4(&p);
break;
trace_serial_num = read_u4(&p);
{
}
num_elements = read_u2(&p);
for(i=0; i<num_elements; i++) {
(void)read_u2(&p);
}
num_elements = read_u2(&p);
for(i=0; i<num_elements; i++) {
(void)read_id(&p);
}
num_elements = read_u2(&p);
for(i=0; i<num_elements; i++) {
}
break;
trace_serial_num = read_u4(&p);
p += num_bytes;
break;
trace_serial_num = read_u4(&p);
num_elements = read_u4(&p);
p += num_elements*(int)sizeof(HprofId);
break;
trace_serial_num = read_u4(&p);
num_elements = read_u4(&p);
break;
default:
label = "UNKNOWN";
check_printf("H#%d@%d %s: ERROR!\n",
break;
}
}
/* Scan again once we have our cmap */
nrecords = 0;
p = pstart;
nrecords++;
/*LINTED*/
switch ( tag ) {
check_printf("H#%d@%d %s: id=0x%x\n",
break;
check_printf("H#%d@%d %s: id=0x%x, id2=0x%x\n",
break;
thread_serial_num = read_u4(&p);
check_printf("H#%d@%d %s: id=0x%x, thread_serial_num=%u, fr=0x%x\n",
break;
thread_serial_num = read_u4(&p);
check_printf("H#%d@%d %s: id=0x%x, thread_serial_num=%u, fr=0x%x\n",
break;
thread_serial_num = read_u4(&p);
check_printf("H#%d@%d %s: id=0x%x, thread_serial_num=%u\n",
break;
check_printf("H#%d@%d %s: id=0x%x\n",
break;
thread_serial_num = read_u4(&p);
check_printf("H#%d@%d %s: id=0x%x, thread_serial_num=%u\n",
break;
check_printf("H#%d@%d %s: id=0x%x\n",
break;
thread_serial_num = read_u4(&p);
trace_serial_num = read_u4(&p);
check_printf("H#%d@%d %s: id=0x%x, thread_serial_num=%u,"
" trace_serial_num=%u\n",
break;
trace_serial_num = read_u4(&p);
check_printf("H#%d@%d %s: id=0x%x, trace_serial_num=%u\n",
{
check_printf(" su=0x%x, ld=0x%x, si=0x%x,"
" pr=0x%x, re1=0x%x, re2=0x%x\n",
}
num_elements = read_u2(&p);
for(i=0; i<num_elements; i++) {
unsigned cpi;
check_printf(" constant_pool %d: cpi=%d, ty=%d, val=",
check_printf("\n");
}
num_elements = read_u2(&p);
for(i=0; i<num_elements; i++) {
check_printf(" static field %d: ", i);
check_printf("\n");
}
num_elements = read_u2(&p);
for(i=0; i<num_elements; i++) {
check_printf(" instance_field %d: ", i);
}
break;
trace_serial_num = read_u4(&p);
check_printf("H#%d@%d %s: id=0x%x, trace_serial_num=%u,"
" cid=0x%x, nbytes=%d\n",
/* This is a packed set of bytes for the instance fields */
if ( num_bytes > 0 ) {
int ifield;
HPROF_ASSERT(cindex!=0);
psave = p;
ifield = 0;
do {
HPROF_ASSERT(ty!=0);
HPROF_ASSERT(id!=0);
check_printf("\n");
ifield++;
}
cindex = 0;
if ( id2 != 0 ) {
HPROF_ASSERT(cindex!=0);
}
}
break;
trace_serial_num = read_u4(&p);
num_elements = read_u4(&p);
check_printf("H#%d@%d %s: id=0x%x, trace_serial_num=%u, nelems=%d, eid=0x%x\n",
for(i=0; i<num_elements; i++) {
}
break;
trace_serial_num = read_u4(&p);
num_elements = read_u4(&p);
psave = p;
check_printf("H#%d@%d %s: id=0x%x, trace_serial_num=%u, "
"nelems=%d, ty=%d\n",
if ( num_elements > 0 ) {
int count;
int long_form;
int max_count;
char *quote;
quote = "";
long_form = 1;
max_count = 8;
count = 0;
switch ( ty ) {
case HPROF_CHAR:
long_form = 0;
max_count = 72;
quote = "\"";
/*FALLTHRU*/
case HPROF_INT:
case HPROF_DOUBLE:
case HPROF_LONG:
case HPROF_BYTE:
case HPROF_BOOLEAN:
case HPROF_SHORT:
case HPROF_FLOAT:
for(i=0; i<num_elements; i++) {
if ( i > 0 && count == 0 ) {
}
count += 1;
check_printf("\"\n");
count = 0;
}
}
if ( count != 0 ) {
}
break;
}
}
break;
default:
label = "UNKNOWN";
check_printf("H#%d@%d %s: ERROR!\n",
break;
}
}
return nrecords;
}
/* LookupTable cleanup callback for utab */
static void
{
return;
}
}
}
/* Check all the heap tags in a heap dump */
static int
{
unsigned char *p;
int nrecord;
check_printf("\nCHECK TAGS: starting\n");
/* Walk the tags, assumes UTF8 tags are defined before used */
p = pstart;
nrecord = 0;
unsigned tag;
unsigned size;
int nheap_records;
int npos;
char *label;
unsigned flags;
unsigned depth;
float cutoff;
unsigned temp;
nrecord++;
/*LINTED*/
(void)read_u4(&p); /* microsecs */
switch ( tag ) {
check_printf("#%d@%d: %s, sz=%d, name_id=0x%x, \"",
check_raw(p, num_elements);
check_printf("\"\n");
/* Create entry in umap */
p += num_elements;
break;
class_serial_num = read_u4(&p);
trace_serial_num = read_u4(&p);
check_printf("#%d@%d: %s, sz=%d, class_serial_num=%u,"
" id=0x%x, trace_serial_num=%u, name_id=0x%x\n",
break;
class_serial_num = read_u4(&p);
check_printf("#%d@%d: %s, sz=%d, class_serial_num=%u\n",
break;
class_serial_num = read_u4(&p);
check_printf(" name_id=0x%x, sig_id=0x%x, source_id=0x%x,"
" class_serial_num=%u, lineno=%d\n",
break;
trace_serial_num = read_u4(&p);
num_elements = read_u4(&p);
check_printf("#%d@%d: %s, sz=%d, trace_serial_num=%u,"
" thread_serial_num=%u, nelems=%d [",
for(i=0; i< num_elements; i++) {
}
check_printf("]\n");
break;
num_elements = read_u4(&p);
check_printf("#%d@%d: %s, sz=%d, flags=0x%x, cutoff=%g,"
" nblive=%d, nilive=%d, tbytes=(%d,%d),"
" tinsts=(%d,%d), num_elements=%d\n",
for(i=0; i< num_elements; i++) {
class_serial_num = read_u4(&p);
trace_serial_num = read_u4(&p);
check_printf("\t %d: ty=%d, class_serial_num=%u,"
" trace_serial_num=%u, nblive=%d, nilive=%d,"
" tbytes=%d, tinsts=%d\n",
}
break;
check_printf("#%d@%d: %s, sz=%d,"
" nblive=%d, nilive=%d, tbytes=(%d,%d),"
" tinsts=(%d,%d)\n",
break;
thread_serial_num = read_u4(&p);
trace_serial_num = read_u4(&p);
check_printf("#%d@%d: %s, sz=%d, thread_serial_num=%u,"
" id=0x%x, trace_serial_num=%u, ",
check_printf(" trace_serial_num=%u, nm=0x%x,"
" gr=0x%x, gn=0x%x\n",
break;
thread_serial_num = read_u4(&p);
check_printf("#%d@%d: %s, sz=%d, thread_serial_num=%u\n",
break;
check_printf("#%d@%d: BEGIN: %s, sz=%d\n",
check_printf("#%d@%d: END: %s, sz=%d, nheap_recs=%d\n",
p += size;
break;
check_printf("#%d@%d: BEGIN SEGMENT: %s, sz=%d\n",
check_printf("#%d@%d: END SEGMENT: %s, sz=%d, nheap_recs=%d\n",
p += size;
break;
check_printf("#%d@%d: SEGMENT END: %s, sz=%d\n",
break;
total_samples = read_u4(&p);
trace_count = read_u4(&p);
check_printf("#%d@%d: %s, sz=%d, total_samples=%d,"
" trace_count=%d\n",
for(i=0; i< trace_count; i++) {
num_elements = read_u4(&p);
trace_serial_num = read_u4(&p);
check_printf("\t %d: samples=%d, trace_serial_num=%u\n",
}
break;
check_printf("#%d@%d: %s, sz=%d, flags=0x%x, depth=%d\n",
break;
default:
label = "UNKNOWN";
check_printf("#%d@%d: %s, sz=%d\n",
p += size;
break;
}
}
check_flush();
return nrecord;
}
/* Read the entire file into memory */
static void *
{
unsigned char *image;
int fd;
int nread;
*pnbytes = 0;
CHECK_FOR_ERROR(fd>=0);
}
}
/* Read the entire file image into memory */
if ( nread <= 0 ) {
}
return image;
}
/* ------------------------------------------------------------------ */
void
{
unsigned char *image;
unsigned char *p;
unsigned idsize;
int nbytes;
int nrecords;
return;
}
p = image;
check_printf("Filename=%s, nbytes=%d, header=\"%s\"\n",
p+=((int)strlen((char*)p)+1);
(void)read_u4(&p);
(void)read_u4(&p);
/* LINTED */
}