NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lib/51635: td_thr_iter in <pthread_dbg.h> seems broken



>Number:         51635
>Category:       lib
>Synopsis:       td_thr_iter in <pthread_dbg.h> seems broken
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 18 22:45:00 +0000 2016
>Originator:     Kamil Rytarowski
>Release:        NetBSD 7.99.42 amd64
>Organization:
TNF
>Environment:
NetBSD chieftec 7.99.42 NetBSD 7.99.42 (GENERIC) #0: Thu Nov 17 17:11:44 CET 2016  root@chieftec:/tmp/netbsd-tmp/sys/arch/amd64/compile/GENERIC amd64
>Description:
I'm trying to use td_thr_iter() however it doesn't work for me.

Example test:

#include <sys/cdefs.h>

#include <dlfcn.h>
#include <pthread.h>
#include <pthread_dbg.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>


#define ATF_REQUIRE(a) assert(a)
#define ATF_REQUIRE_MSG(a,b,...) assert(a)



#define PTHREAD_REQUIRE(x) \
    do { \
        int ret = (x); \
        ATF_REQUIRE_MSG(ret == 0, "%s: %s", #x, strerror(ret)); \
    } while (0)

#define PTHREAD_REQUIRE_STATUS(x, v) \
    do { \
        int ret = (x); \
        ATF_REQUIRE_MSG(ret == (v), "%s: %s", #x, strerror(ret)); \
    } while (0)

static int __used
dummy_proc_read(void *arg, caddr_t addr, void *buf, size_t size)
{
        return TD_ERR_ERR;
}

static int __used
dummy_proc_write(void *arg, caddr_t addr, void *buf, size_t size)
{
        return TD_ERR_ERR;
}

static int __used
dummy_proc_lookup(void *arg, const char *sym, caddr_t *addr)
{
        return TD_ERR_ERR;
}

static int __used
dummy_proc_regsize(void *arg, int regset, size_t *size)
{
        return TD_ERR_ERR;
}
 
static int __used
dummy_proc_getregs(void *arg, int regset, int lwp, void *buf)   
{
        return TD_ERR_ERR;
}

static int __used
dummy_proc_setregs(void *arg, int regset, int lwp, void *buf)
{
        return TD_ERR_ERR;
}

/* Minimalistic basic implementation */

static int __used
basic_proc_read(void *arg, caddr_t addr, void *buf, size_t size)
{
        memcpy(addr, buf, size);

        return TD_ERR_OK;
}

static int __used
basic_proc_write(void *arg, caddr_t addr, void *buf, size_t size)
{
        memcpy(addr, buf, size);

        return TD_ERR_OK;
}

static int __used
basic_proc_lookup(void *arg, const char *sym, caddr_t *addr)
{
        void *handle;
        void *symbol;

        ATF_REQUIRE_MSG((handle = dlopen(NULL, RTLD_LOCAL | RTLD_LAZY))
            != NULL, "dlopen(3) failed: %s", dlerror());

        symbol = dlsym(handle, sym);

        ATF_REQUIRE_MSG(dlclose(handle) == 0, "dlclose(3) failed: %s",
            dlerror());

        if (!symbol)
                return TD_ERR_NOSYM;

        *addr = (caddr_t)(uintptr_t)symbol;

        return TD_ERR_OK;
}

static int exiting;

static void *
busyFunction1(void *arg)
{

        while (exiting == 0)
                usleep(50000);

        return NULL;
}

static int
iterateThreads1(td_thread_t *thread, void *arg)
{

        return TD_ERR_OK;
}

int
main(int argc, char **argv)
{
        struct td_proc_callbacks_t dummy_callbacks;
        td_proc_t *main_ta;
        const size_t max_threads = 10;
        size_t i;
        pthread_t threads[max_threads];

        dummy_callbacks.proc_read       = basic_proc_read;
        dummy_callbacks.proc_write      = basic_proc_write;
        dummy_callbacks.proc_lookup     = basic_proc_lookup;
        dummy_callbacks.proc_regsize    = dummy_proc_regsize;
        dummy_callbacks.proc_getregs    = dummy_proc_getregs;
        dummy_callbacks.proc_setregs    = dummy_proc_setregs;

        for (i = 0; i < max_threads; i++) {
                printf("Creating thread %zu\n", i);
                PTHREAD_REQUIRE
                    (pthread_create(&threads[i], NULL, busyFunction1, NULL));
        }

        printf("Calling td_open(3)\n");
        ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK);

        ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads1, NULL) == TD_ERR_OK);

        exiting = 1;

        printf("Calling td_close(3)\n");
        ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK);
}


Result in gdb(1), pointer ptqe_next is invalid.

(gdb) p ((pthread_t)next)->pt_allq 
$7 = {ptqe_next = 0xfffff977e8004010, ptqe_prev = 0x10020077105c7}
(gdb) p ((pthread_t)next)->pt_allq.ptqe_next 
$8 = (struct __pthread_st *) 0xfffff977e8004010
(gdb) p ((pthread_t)next)
$9 = (struct __pthread_st *) 0x400da1 <iterateThreads1>
>How-To-Repeat:
cd /usr/src/tests/lib/libpthread_dbg
atf-run t_threads | atf-report
>Fix:
N/A



Home | Main Index | Thread Index | Old Index