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