Example #1
0
malloc_stack_entry *
get_stack_history_for_address (const void * addr, int history)
{
    std::vector<malloc_stack_entry> empty;
    g_malloc_stack_history.swap(empty);
    if (!stack_logging_enable_logging || (history && !stack_logging_dontcompact))
    {
        if (history)
            strncpy(g_error_string, "error: stack history logging is not enabled, set MallocStackLoggingNoCompact=1 in the environment when launching to enable stack history logging.", sizeof(g_error_string));
        else
            strncpy(g_error_string, "error: stack logging is not enabled, set MallocStackLogging=1 in the environment when launching to enable stack logging.", sizeof(g_error_string));
        return NULL;
    }
    kern_return_t err;
    task_t task = mach_task_self();
    if (history)
    {
        err = __mach_stack_logging_enumerate_records (task,
                                                      (mach_vm_address_t)addr, 
                                                      get_stack_for_address_enumerator,
                                                      &task);
    }
    else
    {
        uint32_t num_frames = 0;
        err = __mach_stack_logging_get_frames(task, (mach_vm_address_t)addr, g_stack_frames, MAX_FRAMES, &num_frames);
        if (err == 0 && num_frames > 0)
        {
            g_malloc_stack_history.resize(1);
            g_malloc_stack_history.back().address = addr;
            g_malloc_stack_history.back().type_flags = stack_logging_type_alloc;
            g_malloc_stack_history.back().argument = 0;
            if (num_frames > 0)
                g_malloc_stack_history.back().frames.assign(g_stack_frames, g_stack_frames + num_frames);
            g_malloc_stack_history.back().frames.push_back(0); // Terminate the frames with zero
        }
    }
    // Append an empty entry
    if (g_malloc_stack_history.empty())
        return NULL;
    g_malloc_stack_history.resize(g_malloc_stack_history.size() + 1);
    g_malloc_stack_history.back().address = 0;
    g_malloc_stack_history.back().type_flags = 0;
    g_malloc_stack_history.back().argument = 0;
    return g_malloc_stack_history.data();
}
Example #2
0
malloc_stack_entry *
get_stack_history_for_address (const void * addr, int history)
{
    if (!stack_logging_enable_logging)
        return NULL;
    g_malloc_stack_history.clear();
    kern_return_t err;
    task_t task = mach_task_self();
    if (history)
    {
        err = __mach_stack_logging_enumerate_records (task,
                                                      (mach_vm_address_t)addr, 
                                                      get_stack_for_address_enumerator,
                                                      &task);
    }
    else
    {
        malloc_stack_entry *stack_entry = g_malloc_stack_history.next();
        if (stack_entry)
        {
            stack_entry->address = addr;
            stack_entry->type_flags = stack_logging_type_alloc;
            stack_entry->argument = 0;
            stack_entry->num_frames = 0;
            stack_entry->frames[0] = 0;
            err = __mach_stack_logging_get_frames(task, (mach_vm_address_t)addr, stack_entry->frames, MAX_FRAMES, &stack_entry->num_frames);
            if (err == 0 && stack_entry->num_frames > 0)
            {
                // Terminate the frames with zero if there is room
                if (stack_entry->num_frames < MAX_FRAMES)
                    stack_entry->frames[stack_entry->num_frames] = 0;
            }
            else
            {
                g_malloc_stack_history.clear();                
            }
        }
    }
    // Return data if there is any
    return g_malloc_stack_history.data();
}