static void snapshot(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) { struct Allocator_admin_pvt* ctx = Identity_check((struct Allocator_admin_pvt*)vcontext); uint64_t* includeAllocations = Dict_getIntC(args, "includeAllocations"); Allocator_snapshot(ctx->alloc, (includeAllocations && *includeAllocations != 0)); Dict d = Dict_CONST(String_CONST("error"), String_OBJ(String_CONST("none")), NULL); Admin_sendMessage(&d, txid, ctx->admin); }
Gcc_NORETURN static void failure(struct Allocator_pvt* context, const char* message, const char* fileName, int lineNum) { Allocator_snapshot(&context->pub, 1); Assert_failure("%s:%d Fatal error: [%s]", fileName, lineNum, message); }
static void unroll(struct Allocator_pvt* context, int includeAllocations, struct Unroller* unroller) { writeUnroller(unroller); const char* ident = (context->pub.fileName) ? context->pub.fileName : "UNKNOWN"; fprintf(stderr, "%s:%d [%lu] bytes%s\n", ident, context->pub.lineNum, context->allocatedHere, (context->pub.isFreeing) ? " (freeing)" : ""); struct Unroller childUnroller = { .content = ((context->nextSibling) ? "| " : " "), .last = unroller }; if (context->firstChild) { unroll(context->firstChild, includeAllocations, &childUnroller); } struct Allocator_Allocation_pvt* allocation = context->allocations; while (allocation && includeAllocations) { writeUnroller(&childUnroller); fprintf(stderr, "%s:%d [%lu] bytes at [0x%lx]\n", allocation->pub.fileName, allocation->pub.lineNum, allocation->pub.size, (long)(uintptr_t)allocation); allocation = allocation->next; } if (context->nextSibling) { unroll(context->nextSibling, includeAllocations, unroller); } } void Allocator_snapshot(struct Allocator* alloc, int includeAllocations) { // get the root allocator. struct Allocator_pvt* rootAlloc = Identity_check((struct Allocator_pvt*)alloc); while (rootAlloc->parent && rootAlloc->parent != rootAlloc) { rootAlloc = rootAlloc->parent; } fprintf(stderr, "----- %scjdns memory snapshot -----\n", ""); unroll(rootAlloc, includeAllocations, NULL); fprintf(stderr, "totalBytes [%ld] remaining [%ld]\n", (long)rootAlloc->rootAlloc->maxSpace, (long)rootAlloc->rootAlloc->spaceAvailable); fprintf(stderr, "----- %scjdns memory snapshot -----\n", "end "); } Gcc_NORETURN static void failure(struct Allocator_pvt* context, const char* message, const char* fileName, int lineNum) { Allocator_snapshot(&context->pub, 1); Assert_failure("%s:%d Fatal error: [%s]", fileName, lineNum, message); }