Hprof.c revision 6bf992c9d51f1e12aa37fe4c791c156402a9b79b
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Preparation and completion of hprof data generation. The output is 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * written into two files and then combined. This is necessary because 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we generate some of the data (strings and classes) while we dump the 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * heap, and some analysis tools require that the class and string data 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appear first. 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Hprof.h" 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h> 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h> 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/time.h> 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <time.h> 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kHeadSuffix "-hptemp" 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecthprof_context_t * 366bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFaddenhprofStartup(const char *outputFileName, bool directToDdms) 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 386bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden FILE* fp = NULL; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 406bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden if (!directToDdms) { 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = strlen(outputFileName); 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char fileName[len + sizeof(kHeadSuffix)]; 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Construct the temp file name. This wasn't handed to us by the 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * application, so we need to be careful about stomping on it. 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(fileName, "%s" kHeadSuffix, outputFileName); 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (access(fileName, F_OK) == 0) { 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("hprof: temp file %s exists, bailing\n", fileName); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fp = fopen(fileName, "w+"); 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fp == NULL) { 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("hprof: can't open %s: %s.\n", fileName, strerror(errno)); 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (unlink(fileName) != 0) { 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("hprof: WARNING: unable to remove temp file %s\n", fileName); 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* keep going */ 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("hprof: dumping VM heap to \"%s\".\n", fileName); 636bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden } 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 656bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofStartup_String(); 666bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofStartup_Class(); 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if WITH_HPROF_STACK 686bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofStartup_StackFrame(); 696bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofStartup_Stack(); 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 726bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprof_context_t *ctx = malloc(sizeof(*ctx)); 736bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden if (ctx == NULL) { 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("hprof: can't allocate context.\n"); 756bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden if (fp != NULL) 766bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden fclose(fp); 776bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden return NULL; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 806bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden /* pass in "fp" for the temp file, and the name of the output file */ 816bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofContextInit(ctx, strdup(outputFileName), fp, false, directToDdms); 826bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden 836bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden assert(ctx->fp != NULL); 846bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ctx; 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy the entire contents of "srcFp" to "dstFp". 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns "true" on success. 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectcopyFileToFile(FILE *dstFp, FILE *srcFp) 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[65536]; 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t dataRead, dataWritten; 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataRead = fread(buf, 1, sizeof(buf), srcFp); 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataRead > 0) { 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataWritten = fwrite(buf, 1, dataRead, dstFp); 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataWritten != dataRead) { 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("hprof: failed writing data (%d of %d): %s\n", 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataWritten, dataRead, strerror(errno)); 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (feof(srcFp)) 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("hprof: failed reading data (res=%d): %s\n", 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataRead, strerror(errno)); 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 11899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 11999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Finish up the hprof dump. Returns true on success. 12099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 12199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectbool 1226bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFaddenhprofShutdown(hprof_context_t *tailCtx) 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1246bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden FILE *fp = NULL; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* flush output to the temp file, then prepare the output file */ 1276bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofFlushCurrentRecord(tailCtx); 1286bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden 1296bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden LOGI("hprof: dumping heap strings to \"%s\".\n", tailCtx->fileName); 1306bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden if (!tailCtx->directToDdms) { 1316bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden fp = fopen(tailCtx->fileName, "w"); 1326bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden if (fp == NULL) { 1336bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden LOGE("can't open %s: %s\n", tailCtx->fileName, strerror(errno)); 1346bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofFreeContext(tailCtx); 1356bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden return false; 1366bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden } 1376bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden } 1386bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden 1396bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden /* 1406bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden * Create a new context struct for the start of the file. We 1416bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden * heap-allocate it so we can share the "free" function. 1426bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden */ 1436bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprof_context_t *headCtx = malloc(sizeof(*headCtx)); 1446bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden if (headCtx == NULL) { 1456bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden LOGE("hprof: can't allocate context.\n"); 1466bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden if (fp != NULL) 1476bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden fclose(fp); 1486bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofFreeContext(tailCtx); 1496bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden return NULL; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1516bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofContextInit(headCtx, strdup(tailCtx->fileName), fp, true, 1526bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden tailCtx->directToDdms); 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1546bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofDumpStrings(headCtx); 1556bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofDumpClasses(headCtx); 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Write a dummy stack trace record so the analysis 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * tools don't freak out. 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1606bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofStartNewRecord(headCtx, HPROF_TAG_STACK_TRACE, HPROF_TIME); 1616bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofAddU4ToRecord(&headCtx->curRec, HPROF_NULL_STACK_TRACE); 1626bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofAddU4ToRecord(&headCtx->curRec, HPROF_NULL_THREAD); 1636bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofAddU4ToRecord(&headCtx->curRec, 0); // no frames 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if WITH_HPROF_STACK 1666bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofDumpStackFrames(headCtx); 1676bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofDumpStacks(headCtx); 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1706bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofFlushCurrentRecord(headCtx); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofShutdown_Class(); 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofShutdown_String(); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if WITH_HPROF_STACK 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofShutdown_Stack(); 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hprofShutdown_StackFrame(); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1796bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden if (tailCtx->directToDdms) { 1806bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden /* flush to ensure memstream pointer and size are updated */ 1816bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden fflush(headCtx->fp); 1826bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden fflush(tailCtx->fp); 1836bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden 1846bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden /* send the data off to DDMS */ 1856bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden struct iovec iov[2]; 1866bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden iov[0].iov_base = headCtx->fileDataPtr; 1876bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden iov[0].iov_len = headCtx->fileDataSize; 1886bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden iov[1].iov_base = tailCtx->fileDataPtr; 1896bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden iov[1].iov_len = tailCtx->fileDataSize; 1906bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden dvmDbgDdmSendChunkV(CHUNK_TYPE("HPDS"), iov, 2); 1916bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden } else { 1926bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden /* 1936bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden * Append the contents of the temp file to the output file. The temp 1946bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden * file was removed immediately after being opened, so it will vanish 1956bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden * when we close it. 1966bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden */ 1976bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden rewind(tailCtx->fp); 1986bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden if (!copyFileToFile(headCtx->fp, tailCtx->fp)) { 1996bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden LOGW("hprof: file copy failed, hprof data may be incomplete\n"); 2006bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden /* finish up anyway */ 2016bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden } 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2046bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofFreeContext(headCtx); 2056bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden hprofFreeContext(tailCtx); 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* throw out a log message for the benefit of "runhat" */ 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGI("hprof: heap dump completed, temp file removed\n"); 20999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project return true; 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2116bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden 2126bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden/* 2136bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden * Free any heap-allocated items in "ctx", and then free "ctx" itself. 2146bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden */ 2156bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFaddenvoid 2166bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFaddenhprofFreeContext(hprof_context_t *ctx) 2176bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden{ 2186bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden assert(ctx != NULL); 2196bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden 2206bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden if (ctx->fp != NULL) 2216bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden fclose(ctx->fp); 2226bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden free(ctx->curRec.body); 2236bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden free(ctx->fileName); 2246bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden free(ctx->fileDataPtr); 2256bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden free(ctx); 2266bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden} 2276bf992c9d51f1e12aa37fe4c791c156402a9b79bAndy McFadden 228