コード例 #1
0
ファイル: malloc_hook.c プロジェクト: xinzhao3/ucx
/* Has to be called with install_mutex held */
static void ucm_malloc_test(int events)
{
    static const size_t small_alloc_count = 128;
    static const size_t small_alloc_size  = 4096;
    static const size_t large_alloc_size  = 4 * UCS_MBYTE;
    ucm_event_handler_t handler;
    void *p[small_alloc_count];
    int out_events;
    int i;

    ucm_debug("testing malloc...");

    /* Install a temporary event handler which will add the supported event
     * type to out_events bitmap.
     */
    handler.events   = events;
    handler.priority = -1;
    handler.cb       = ucm_mmap_event_test_callback;
    handler.arg      = &out_events;
    out_events       = 0;

    ucm_event_handler_add(&handler);

    /* Trigger both small and large allocations
     * TODO check address / stop all threads */
    for (i = 0; i < small_alloc_count; ++i) {
        p[i] = malloc(small_alloc_size);
    }
    for (i = 0; i < small_alloc_count; ++i) {
        free(p[i]);
    }
    p[0] = malloc(large_alloc_size);
    p[0] = realloc(p[0], large_alloc_size * 2);
    free(p[0]);

    if (ucm_malloc_hook_state.hook_called) {
        ucm_dlmalloc_trim(0);
    }

    ucm_event_handler_remove(&handler);

    ucm_malloc_hook_state.installed_events |= out_events;

    ucm_debug("malloc test: have 0x%x out of 0x%x, hooks were%s called",
              ucm_malloc_hook_state.installed_events, events,
              ucm_malloc_hook_state.hook_called ? "" : " not");
}
コード例 #2
0
ファイル: malloc_hook.c プロジェクト: xinzhao3/ucx
static void ucm_malloc_install_mallopt()
{
    /* copy values of M_MMAP_THRESHOLD and M_TRIM_THRESHOLD
     * if they were overriden by the user
     */
    char *p;

    p = getenv("MALLOC_TRIM_THRESHOLD_");
    if (p) {
        ucm_debug("set trim_thresh to %d", atoi(p));
        ucm_dlmallopt(M_TRIM_THRESHOLD, atoi(p));
    }

    p = getenv("MALLOC_MMAP_THRESHOLD_");
    if (p) {
        ucm_debug("set mmap_thresh to %d", atoi(p));
        ucm_dlmallopt(M_MMAP_THRESHOLD, atoi(p));
    }
}
コード例 #3
0
ファイル: install.c プロジェクト: LenaO/ucx
/* Called with lock held */
static ucs_status_t ucm_mmap_test(int events)
{
    static int installed_events = 0;
    ucm_event_handler_t handler;
    int out_events;
    void *p;

    if (ucs_test_all_flags(installed_events, events)) {
        /* All requested events are already installed */
        return UCS_OK;
    }

    /* Install a temporary event handler which will add the supported event
     * type to out_events bitmap.
     */
    handler.events   = events;
    handler.priority = -1;
    handler.cb       = ucm_mmap_event_test_callback;
    handler.arg      = &out_events;
    out_events       = 0;

    ucm_event_handler_add(&handler);

    if (events & (UCM_EVENT_MMAP|UCM_EVENT_MUNMAP|UCM_EVENT_MREMAP)) {
        p = mmap(NULL, 0, 0, 0, -1 ,0);
        p = mremap(p, 0, 0, 0);
        munmap(p, 0);
    }

    if (events & (UCM_EVENT_SHMAT|UCM_EVENT_SHMDT)) {
        p = shmat(0, NULL, 0);
        shmdt(p);
    }

    if (events & UCM_EVENT_SBRK) {
        (void)sbrk(0);
    }

    ucm_event_handler_remove(&handler);

    /* TODO check address / stop all threads */
    installed_events |= out_events;
    ucm_debug("mmap test: got 0x%x out of 0x%x, total: 0x%x", out_events, events,
              installed_events);

    /* Return success iff we caught all wanted events */
    if (!ucs_test_all_flags(out_events, events)) {
        return UCS_ERR_UNSUPPORTED;
    }

    return UCS_OK;
}
コード例 #4
0
ファイル: install.c プロジェクト: LenaO/ucx
/* Called with lock held */
static ucs_status_t ucs_mmap_install_reloc(int events)
{
    static int installed_events = 0;
    ucm_mmap_func_t *entry;
    ucs_status_t status;

    if (!ucm_global_config.enable_mmap_reloc) {
        ucm_debug("installing mmap relocations is disabled by configuration");
        return UCS_ERR_UNSUPPORTED;
    }

    for (entry = ucm_mmap_funcs; entry->patch.symbol != NULL; ++entry) {
        if (!(entry->event_type & events)) {
            /* Not required */
            continue;
        }

        if (entry->event_type & installed_events) {
            /* Already installed */
            continue;
        }

        ucm_debug("mmap: installing relocation table entry for %s = %p for event 0x%x",
                  entry->patch.symbol, entry->patch.value, entry->event_type);

        status = ucm_reloc_modify(&entry->patch);
        if (status != UCS_OK) {
            ucm_warn("failed to install relocation table entry for '%s'",
                     entry->patch.symbol);
            return status;
        }

        installed_events |= entry->event_type;
    }

    return UCS_OK;
}
コード例 #5
0
ファイル: install.c プロジェクト: LenaO/ucx
ucs_status_t ucm_mmap_install(int events)
{
    static pthread_mutex_t install_mutex = PTHREAD_MUTEX_INITIALIZER;
    ucs_status_t status;

    pthread_mutex_lock(&install_mutex);

    status = ucm_mmap_test(events);
    if (status == UCS_OK) {
        goto out_unlock;
    }

    status = ucs_mmap_install_reloc(events);
    if (status != UCS_OK) {
        ucm_debug("failed to install relocations for mmap");
        goto out_unlock;
    }

    status = ucm_mmap_test(events);

out_unlock:
    pthread_mutex_unlock(&install_mutex);
    return status;
}
コード例 #6
0
ファイル: sys.c プロジェクト: alex--m/ucx
size_t ucm_get_shm_seg_size(const void *shmaddr)
{
    unsigned long start_addr, end_addr;
    char *ptr, *newline;
    size_t read_offset;
    char buffer[1024];
    size_t seg_size;
    ssize_t nread;
    int fd;
    int ret;

    seg_size = 0;

    fd = open(UCM_PROCESS_MAPS_FILE, O_RDONLY);
    if (fd < 0) {
        ucm_debug("cannot open %s for reading: %m", UCM_PROCESS_MAPS_FILE);
        goto out;
    }

    read_offset = 0;
    for (;;) {
        nread = read(fd, buffer + read_offset, sizeof(buffer) - 1 - read_offset);
        if (nread < 0) {
            if (errno == EINTR) {
                continue;
            } else {
                ucm_debug("failed to read from %s: %m", UCM_PROCESS_MAPS_FILE);
                goto out_close;
            }
        } else if (nread == 0) {
            goto out_close;
        } else {
            buffer[nread + read_offset] = '\0';
        }

        ptr = buffer;
        while ( (newline = strchr(ptr, '\n')) != NULL ) {
            /* 00400000-0040b000 r-xp ... \n */
            ret = sscanf(ptr, "%lx-%lx ", &start_addr, &end_addr);
            if (ret != 2) {
                ucm_debug("Failed to parse `%s'", ptr);
                continue;
            }

            if (start_addr == (uintptr_t)shmaddr) {
                seg_size = end_addr - start_addr;
                goto out_close;
            }

            newline = strchr(ptr, '\n');
            if (newline == NULL) {
                break;
            }

            ptr = newline + 1;
        }

        read_offset = strlen(ptr);
        memmove(buffer, ptr, read_offset);
    }

out_close:
    close(fd);
out:
    return seg_size;
}
コード例 #7
0
ファイル: malloc_hook.c プロジェクト: xinzhao3/ucx
ucs_status_t ucm_malloc_install(int events)
{
    ucs_status_t status;

    pthread_mutex_lock(&ucm_malloc_hook_state.install_mutex);

    events &= UCM_EVENT_MMAP | UCM_EVENT_MUNMAP | UCM_EVENT_MREMAP | UCM_EVENT_SBRK;

    if (ucs_malloc_is_ready(events)) {
        goto out_succ;
    }

    ucm_malloc_test(events);
    if (ucs_malloc_is_ready(events)) {
        goto out_succ;
    }

    if (!ucm_malloc_hook_state.hook_called) {
        /* Try to leak less memory from original malloc */
        malloc_trim(0);
    }

    if (!(ucm_malloc_hook_state.install_state & UCM_MALLOC_INSTALLED_SBRK_EVH)) {
        ucm_debug("installing malloc-sbrk event handler");
        ucm_event_handler_add(&ucm_malloc_sbrk_handler);
        ucm_malloc_hook_state.install_state |= UCM_MALLOC_INSTALLED_SBRK_EVH;
    }

    /* When running on valgrind, don't even try malloc hooks.
     * We want to release original blocks to silence the leak check, so we must
     * have a way to call the original free(), also these hooks don't work with
     * valgrind anyway.
     */
#if HAVE_MALLOC_HOOK
    if (ucm_global_config.enable_malloc_hooks) {
        /* Install using malloc hooks.
         * TODO detect glibc support in configure-time.
         */
        if (!(ucm_malloc_hook_state.install_state & UCM_MALLOC_INSTALLED_HOOKS)) {
            ucm_debug("installing malloc hooks");
            __free_hook     = ucm_free;
            __realloc_hook  = ucm_realloc;
            __malloc_hook   = ucm_malloc;
            __memalign_hook = ucm_memalign;
            ucm_malloc_hook_state.install_state |= UCM_MALLOC_INSTALLED_HOOKS;
        }

        /* Just installed the hooks, test again. */
        ucm_malloc_test(events);
        if (ucm_malloc_hook_state.hook_called) {
            goto out_install_opt_syms;
        }
    } else
#endif
    {
        ucm_debug("using malloc hooks is disabled by configuration");
    }

    /* Install using malloc symbols */
    if (ucm_global_config.enable_malloc_reloc) {
        if (!(ucm_malloc_hook_state.install_state & UCM_MALLOC_INSTALLED_MALL_SYMS)) {
            ucm_debug("installing malloc relocations");
            ucm_malloc_populate_glibc_cache();
            ucm_malloc_install_symbols(ucm_malloc_symbol_patches);
            ucs_assert(ucm_malloc_symbol_patches[0].value == ucm_free);
            ucm_malloc_hook_state.free           = ucm_malloc_symbol_patches[0].prev_value;
            ucm_malloc_hook_state.install_state |= UCM_MALLOC_INSTALLED_MALL_SYMS;
        }
    } else {
        ucm_debug("installing malloc relocations is disabled by configuration");
    }

    /* Just installed the symbols, test again */
    ucm_malloc_test(events);
    if (ucm_malloc_hook_state.hook_called) {
        goto out_install_opt_syms;
    }

    status = UCS_ERR_UNSUPPORTED;
    goto out_unlock;

out_install_opt_syms:
    ucm_malloc_install_optional_symbols();
    ucm_malloc_install_mallopt();
out_succ:
    status = UCS_OK;
out_unlock:
    pthread_mutex_unlock(&ucm_malloc_hook_state.install_mutex);
    return status;
}