diff -r 000000000000 -r 6474c204b198 tools/trace-malloc/adreader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/trace-malloc/adreader.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,132 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "adreader.h" + +#include +#include +#include + +ADLog::ADLog() + : mEntryCount(0) +{ + mEntries.mNext = static_cast(&mEntries); + mEntries.mPrev = static_cast(&mEntries); +} + +ADLog::~ADLog() +{ + for (const_iterator entry = begin(), entry_end = end(); + entry != entry_end; ++entry) { + free((void*) (*entry)->type); + free((char*) (*entry)->data); + free((char*) (*entry)->allocation_stack); + } + + for (EntryBlock *b = mEntries.mNext, *next; b != &mEntries; b = next) { + next = b->mNext; + delete b; + } +} + +bool +ADLog::Read(const char* aFileName) +{ + FILE *in = fopen(aFileName, "r"); + if (!in) { + return false; + } + + while (!feof(in)) { + unsigned int ptr; + char typebuf[256]; + int datasize; + int res = fscanf(in, "%x %s (%d)\n", &ptr, typebuf, &datasize); + if (res == EOF) + break; + if (res != 3) { + return false; + } + + size_t data_mem_size = ((datasize + sizeof(unsigned long) - 1) / + sizeof(unsigned long)) * sizeof(unsigned long); + char *data = (char*)malloc(data_mem_size); + + for (size_t *cur_data = (size_t*) data, + *cur_data_end = (size_t*) ((char*)data + data_mem_size); + cur_data != cur_data_end; ++cur_data) { + res = fscanf(in, " %zX\n", cur_data); + if (res != 1) { + return false; + } + } + + char stackbuf[100000]; + stackbuf[0] = '\0'; + + char *stack = stackbuf; + int len; + do { + fgets(stack, sizeof(stackbuf) - (stack - stackbuf), in); + len = strlen(stack); + stack += len; + } while (len > 1); + + if (mEntryCount % ADLOG_ENTRY_BLOCK_SIZE == 0) { + EntryBlock *new_block = new EntryBlock(); + new_block->mNext = static_cast(&mEntries); + new_block->mPrev = mEntries.mPrev; + mEntries.mPrev->mNext = new_block; + mEntries.mPrev = new_block; + } + + size_t typelen = strlen(typebuf); + char *type = (char*)malloc(typelen-1); + strncpy(type, typebuf+1, typelen-2); + type[typelen-2] = '\0'; + + Entry *entry = + &mEntries.mPrev->entries[mEntryCount % ADLOG_ENTRY_BLOCK_SIZE]; + entry->address = (Pointer) (uintptr_t) ptr; + entry->type = type; + entry->datasize = datasize; + entry->data = data; + entry->allocation_stack = strdup(stackbuf); + + ++mEntryCount; + } + + return true; +} + +ADLog::const_iterator::const_iterator(ADLog::EntryBlock *aBlock, + size_t aOffset) +{ + SetBlock(aBlock); + mCur = mBlockStart + aOffset; +} + +ADLog::const_iterator& +ADLog::const_iterator::operator++() +{ + ++mCur; + if (mCur == mBlockEnd) { + SetBlock(mBlock->mNext); + mCur = mBlockStart; + } + + return *this; +} + +ADLog::const_iterator& +ADLog::const_iterator::operator--() +{ + if (mCur == mBlockStart) { + SetBlock(mBlock->mPrev); + mCur = mBlockEnd; + } + --mCur; + + return *this; +}