tools/trace-malloc/adreader.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/trace-malloc/adreader.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,132 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include "adreader.h"
     1.9 +
    1.10 +#include <stdio.h>
    1.11 +#include <stdint.h>
    1.12 +#include <string.h>
    1.13 +
    1.14 +ADLog::ADLog()
    1.15 +    : mEntryCount(0)
    1.16 +{
    1.17 +    mEntries.mNext = static_cast<EntryBlock*>(&mEntries);
    1.18 +    mEntries.mPrev = static_cast<EntryBlock*>(&mEntries);
    1.19 +}
    1.20 +
    1.21 +ADLog::~ADLog()
    1.22 +{
    1.23 +    for (const_iterator entry = begin(), entry_end = end();
    1.24 +         entry != entry_end; ++entry) {
    1.25 +        free((void*) (*entry)->type);
    1.26 +        free((char*) (*entry)->data);
    1.27 +        free((char*) (*entry)->allocation_stack);
    1.28 +    }
    1.29 +
    1.30 +    for (EntryBlock *b = mEntries.mNext, *next; b != &mEntries; b = next) {
    1.31 +        next = b->mNext;
    1.32 +        delete b;
    1.33 +    }
    1.34 +}
    1.35 +
    1.36 +bool
    1.37 +ADLog::Read(const char* aFileName)
    1.38 +{
    1.39 +    FILE *in = fopen(aFileName, "r");
    1.40 +    if (!in) {
    1.41 +        return false;
    1.42 +    }
    1.43 +
    1.44 +    while (!feof(in)) {
    1.45 +        unsigned int ptr;
    1.46 +        char typebuf[256];
    1.47 +        int datasize;
    1.48 +        int res = fscanf(in, "%x %s (%d)\n", &ptr, typebuf, &datasize);
    1.49 +        if (res == EOF)
    1.50 +            break;
    1.51 +        if (res != 3) {
    1.52 +            return false;
    1.53 +        }
    1.54 +
    1.55 +        size_t data_mem_size = ((datasize + sizeof(unsigned long) - 1) /
    1.56 +                               sizeof(unsigned long)) * sizeof(unsigned long);
    1.57 +        char *data = (char*)malloc(data_mem_size);
    1.58 +
    1.59 +        for (size_t *cur_data = (size_t*) data,
    1.60 +                *cur_data_end = (size_t*) ((char*)data + data_mem_size);
    1.61 +             cur_data != cur_data_end; ++cur_data) {
    1.62 +            res = fscanf(in, " %zX\n", cur_data);
    1.63 +            if (res != 1) {
    1.64 +                return false;
    1.65 +            }
    1.66 +        }
    1.67 +
    1.68 +        char stackbuf[100000];
    1.69 +        stackbuf[0] = '\0';
    1.70 +
    1.71 +        char *stack = stackbuf;
    1.72 +        int len;
    1.73 +        do {
    1.74 +            fgets(stack, sizeof(stackbuf) - (stack - stackbuf), in);
    1.75 +            len = strlen(stack);
    1.76 +            stack += len;
    1.77 +        } while (len > 1);
    1.78 +
    1.79 +        if (mEntryCount % ADLOG_ENTRY_BLOCK_SIZE == 0) {
    1.80 +            EntryBlock *new_block = new EntryBlock();
    1.81 +            new_block->mNext = static_cast<EntryBlock*>(&mEntries);
    1.82 +            new_block->mPrev = mEntries.mPrev;
    1.83 +            mEntries.mPrev->mNext = new_block;
    1.84 +            mEntries.mPrev = new_block;
    1.85 +        }
    1.86 +
    1.87 +        size_t typelen = strlen(typebuf);
    1.88 +        char *type = (char*)malloc(typelen-1);
    1.89 +        strncpy(type, typebuf+1, typelen-2);
    1.90 +        type[typelen-2] = '\0';
    1.91 +
    1.92 +        Entry *entry =
    1.93 +            &mEntries.mPrev->entries[mEntryCount % ADLOG_ENTRY_BLOCK_SIZE];
    1.94 +        entry->address = (Pointer) (uintptr_t) ptr;
    1.95 +        entry->type = type;
    1.96 +        entry->datasize = datasize;
    1.97 +        entry->data = data;
    1.98 +        entry->allocation_stack = strdup(stackbuf);
    1.99 +
   1.100 +        ++mEntryCount;
   1.101 +    }
   1.102 +
   1.103 +    return true;
   1.104 +}
   1.105 +
   1.106 +ADLog::const_iterator::const_iterator(ADLog::EntryBlock *aBlock,
   1.107 +                                      size_t aOffset)
   1.108 +{
   1.109 +    SetBlock(aBlock);
   1.110 +    mCur = mBlockStart + aOffset;
   1.111 +}
   1.112 +
   1.113 +ADLog::const_iterator&
   1.114 +ADLog::const_iterator::operator++()
   1.115 +{
   1.116 +    ++mCur;
   1.117 +    if (mCur == mBlockEnd) {
   1.118 +        SetBlock(mBlock->mNext);
   1.119 +        mCur = mBlockStart;
   1.120 +    }
   1.121 +
   1.122 +    return *this;
   1.123 +}
   1.124 +
   1.125 +ADLog::const_iterator&
   1.126 +ADLog::const_iterator::operator--()
   1.127 +{
   1.128 +    if (mCur == mBlockStart) {
   1.129 +        SetBlock(mBlock->mPrev);
   1.130 +        mCur = mBlockEnd;
   1.131 +    }
   1.132 +    --mCur;
   1.133 +
   1.134 +    return *this;
   1.135 +}

mercurial