C Valgrind stacktrace失败,线性malloc结构数组

时间:2016-08-28 17:25:28

标签: c memory data-structures valgrind

这是我想要创建的C程序,它监视一组动态分配的结构(在程序初始化时创建)。结构现在具有裸骨要求(fd)。

有效地,

  1. 初始化N个结构的内存
  2. 填写
  3. 在中搜索匹配的文件描述符
  4. 在适当情况下进行匹配,如果有太多
  5. ,则会循环播放

    问题在于valgrind ......我不知道我的指针,结构等在做错了什么......

    以下是代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <unistd.h>
    #include <time.h>
    #include <ctype.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netdb.h>
    
    #define NO_ERROR 0
    #define DEFAULT_ERROR -1
    
    typedef struct dev_conn_state_s {
        int fd;
    } dev_con_state_t;
    
    int current_elements = 0;
    int max_elements = 0;
    
    int init_datastruct_commhandler(int size, dev_con_state_t ** conn_list);
    dev_con_state_t *new_datastruct_commhandler_element(int fd, dev_con_state_t * conn_list);
    dev_con_state_t *search_datastruct_commhandler_element(int fd, dev_con_state_t * conn_list);
    
    dev_con_state_t *build_insert_element(dev_con_state_t * conn_list, int fd);
    dev_con_state_t *build_search_element(dev_con_state_t * conn_list, int fd);
    
    void set_max_conns(int max);
    extern inline int get_max_conns(void);
    
    /**
     * init_datastruct_commhandler(int size, dev_con_state_t ** conn_list)
     * 
     * @brief initializes large heap and buffer for each device to be tracked
     * @param size
     * @param conn_list
     * @return (-1) for error, 0 for success
     */
    int init_datastruct_commhandler(int size, dev_con_state_t ** conn_list)
    {
        printf("Init datahandler memory heap\n");
    
        // Quick param check
        if (size <= 0) {
            return DEFAULT_ERROR;
        }
        current_elements = 0;
        *conn_list = malloc(sizeof(dev_con_state_t) * size);
    
        // Check if malloc failed
        if (*conn_list == NULL) {
            printf("stack malloc failed\n");
            return DEFAULT_ERROR;
        }
    
        memset(*conn_list, 0, sizeof(dev_con_state_t) * size);
    
        printf("Completed datahandler memory heap\n");
    
        return NO_ERROR;
    }
    
    /**
     * build_insert_element(dev_con_state_t *conn_list, struct sockaddr_rc in_addr)
     * @brief Build a static element in the heap and insert
     * @param conn_list
     * @param fd
     * @param in_addr
     * @param conn if built
     */
    dev_con_state_t *build_insert_element(dev_con_state_t * conn_list, int fd)
    {
        //~ dev_con_state_t conn = { 0 };
        //~ printf("ob %p\n",fd);
        //~ conn.fd = fd;
        //conn.last_activity = time(NULL);
        printf("a %p %p\n",conn_list,&conn_list);
    
        return new_datastruct_commhandler_element(fd, conn_list);
    }
    
    /**
     * build_search_element(dev_con_state_t *conn_list)
     * @brief Build a static element in the heap and search
     * @param conn_list
     * @param fd
     * @param in_addr
     * @param conn if built
     */
    dev_con_state_t *build_search_element(dev_con_state_t * conn_list, int fd)
    {
    
        return search_datastruct_commhandler_element(fd, conn_list);
    }
    
    /**
     * new_datastruct_commhandler_element(dev_con_state_t * conn, dev_con_state_t * conn_list)
     * 
     * @brief Adds new datastruct to connection tracker heap
     * @param conn
     * @param conn_list
     * @return (-1) for error, 0 for success
     */
    dev_con_state_t *new_datastruct_commhandler_element(int fd, dev_con_state_t * conn_list)
    {
    
        //int size = sizeof(dev_con_state_t) * current_elements;
        printf("%p %p\n",conn_list,&conn_list);
    
        dev_con_state_t *tmp = conn_list + (sizeof(dev_con_state_t) * current_elements);
    
        int last_elements = current_elements;
    
        if (current_elements == (max_elements)) {
            tmp->fd = fd;
            current_elements = 0;
        } else {
            tmp->fd = fd;
            current_elements++;
        }
    
        return (dev_con_state_t *) conn_list + (sizeof(dev_con_state_t) * last_elements);
    }
    
    /**
     * search_datastruct_commhandler_element(dev_con_state_t * conn, dev_con_state_t * conn_list)
     * 
     * @brief Searches for datastruct in connection tracker heap
     * @note  USES FD (file descriptor) for NOW!
     * @param conn
     * @param conn_list
     * @return NULL for error, non-NULL for success (aka the element we were tracking)
     */
    dev_con_state_t *search_datastruct_commhandler_element(int fd, dev_con_state_t * conn_list)
    {
        int i = 0;
        dev_con_state_t *tmp = NULL;
        for (i = 0; i < get_max_conns(); i++) {
            tmp = (conn_list + (sizeof(dev_con_state_t) * i));
    
            if (tmp->fd == fd) {
                return ((dev_con_state_t *) conn_list + (sizeof(dev_con_state_t) * i));
            }
    
        }
        return (NULL);
    }
    
    /**
     * cleanup_connection_tracker(dev_con_state_t **conn_list)
     * 
     * @brief Cleanup connection tracker function
     * @param conn_list
     */
    void cleanup_connection_tracker(dev_con_state_t ** conn_list)
    {
    
        if (*conn_list != NULL) {
            free(*conn_list);
            *conn_list = NULL;
        }
    }
    
    /**
     * set_max_conns(int max)
     * @brief set max
     * @param max
     */
    void set_max_conns(int max)
    {
        max_elements = max;
    }
    
    /**
     * get_max_conns(void)
     * @brief get max
     * @return max
     */
    inline int get_max_conns(void)
    {
        return max_elements;
    }
    
    //#ifdef CODE_TEST
    #define MAX_DEVS 8
    int main(int argc, char **argv)
    {
        int size = MAX_DEVS;
        dev_con_state_t *conn_list = NULL;
    
        printf("initial address: %p\n", conn_list);
        printf("initial address: %p\n", &conn_list);
    
        set_max_conns(size);
    
        if (init_datastruct_commhandler(size, &conn_list) < 0) {
            return (-1);
        }
        printf("init address: %p\n", conn_list);
        printf("init address: %p\n", &conn_list);
    
        dev_con_state_t conn_array[MAX_DEVS] = { 0 };
    
        dev_con_state_t *ptr = NULL;
        int i = 0;
        for (i = 0; i < get_max_conns(); i++) {
            conn_array[i].fd = i;
            //~ if ((ptr = new_datastruct_commhandler_element(conn_array[i].fd, conn_list)) == NULL) {
            //~ return (-1);
            //~ }
            /// test will error -> we looped around
            if ((ptr = build_insert_element(conn_list, conn_array[i].fd)) == NULL) {
                printf("error finding element\n");
            } else {
                printf("found: %d\n", ptr->fd);
            }
    
            printf("inserted: %d\n", ptr->fd);
        }
    
        if ((ptr = search_datastruct_commhandler_element(conn_array[5].fd, conn_list)) != NULL) {
            printf("found: %d\n", ptr->fd);
        } else {
            printf("NOT found: %d\n", conn_array[5].fd);
        }
    
        if ((ptr = search_datastruct_commhandler_element(conn_array[3].fd, conn_list)) != NULL) {
            printf("found: %d\n", ptr->fd);
        } else {
            printf("NOT found: %d\n", conn_array[3].fd);
        }
    
        /// Still visible out here?
        //~ dev_con_state_t *ptr2 =(&conn_list + sizeof(dev_con_state_t));
        //~ printf("test: %d\n", ptr2->fd);
    
        /// test for searching for last element
        if ((ptr = build_search_element(conn_list, conn_array[6].fd)) == NULL) {
            printf("error finding element\n");
        } else {
            printf("found: %d\n", ptr->fd);
        }
    
        /// test for finding a number that doesnt exist
        if ((ptr = build_search_element(conn_list, 9)) == NULL) {
            printf("error finding element\n");
        } else {
            printf("found: %d\n", ptr->fd);
        }
    
        if ((ptr = build_insert_element(conn_list, conn_array[6].fd)) == NULL) {
            printf("error finding element\n");
        } else {
            printf("inserted: %d\n", ptr->fd);
        }
    
        /// test will error -> we looped around
        if ((ptr = build_search_element(conn_list, conn_array[0].fd)) == NULL) {
            printf("error finding element\n");
        } else {
            printf("found: %d\n", ptr->fd);
        }
    
        cleanup_connection_tracker(&conn_list);
    
        printf("Done\n");
        return (0);
    }
    
    //#endif
    

    我不知道,是什么导致了这个...是我的malloc还是我执行arithmitic的方式?

     valgrind --tool=memcheck --leak-check=yes ./test
    ==27353== Memcheck, a memory error detector
    ==27353== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
    ==27353== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
    ==27353== Command: ./test
    ==27353== 
    initial address: (nil)
    initial address: 0xffefffdc8
    Init datahandler memory heap
    Completed datahandler memory heap
    init address: 0x5202040
    init address: 0xffefffdc8
    a 0x5202040 0xffefffd78
    0x5202040 0xffefffd40
    found: 0
    inserted: 0
    a 0x5202040 0xffefffd78
    0x5202040 0xffefffd40
    found: 1
    inserted: 1
    a 0x5202040 0xffefffd78
    0x5202040 0xffefffd40
    ==27353== Invalid write of size 4
    ==27353==    at 0x400784: new_datahub_commhandler_element (test.c:119)
    ==27353==    by 0x4006E9: build_insert_element (test.c:80)
    ==27353==    by 0x400968: main (test.c:213)
    ==27353==  Address 0x5202060 is 0 bytes after a block of size 32 alloc'd
    ==27353==    at 0x4C2BBCF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==27353==    by 0x400656: init_datahub_commhandler (test.c:49)
    ==27353==    by 0x4008D3: main (test.c:197)
    ==27353== 
    ==27353== Invalid read of size 4
    ==27353==    at 0x400984: main (test.c:216)
    ==27353==  Address 0x5202060 is 0 bytes after a block of size 32 alloc'd
    ==27353==    at 0x4C2BBCF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==27353==    by 0x400656: init_datahub_commhandler (test.c:49)
    ==27353==    by 0x4008D3: main (test.c:197)
    ==27353== 
    found: 2
    ==27353== Invalid read of size 4
    ==27353==    at 0x40099B: main (test.c:219)
    ==27353==  Address 0x5202060 is 0 bytes after a block of size 32 alloc'd
    ==27353==    at 0x4C2BBCF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==27353==    by 0x400656: init_datahub_commhandler (test.c:49)
    ==27353==    by 0x4008D3: main (test.c:197)
    ==27353== 
    inserted: 2
    a 0x5202040 0xffefffd78
    0x5202040 0xffefffd40
    found: 3
    inserted: 3
    a 0x5202040 0xffefffd78
    0x5202040 0xffefffd40
    found: 4
    inserted: 4
    a 0x5202040 0xffefffd78
    0x5202040 0xffefffd40
    found: 5
    inserted: 5
    a 0x5202040 0xffefffd78
    0x5202040 0xffefffd40
    found: 6
    inserted: 6
    a 0x5202040 0xffefffd78
    0x5202040 0xffefffd40
    found: 7
    inserted: 7
    ==27353== Invalid read of size 4
    ==27353==    at 0x4007EA: search_datahub_commhandler_element (test.c:142)
    ==27353==    by 0x4009CC: main (test.c:222)
    ==27353==  Address 0x5202060 is 0 bytes after a block of size 32 alloc'd
    ==27353==    at 0x4C2BBCF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==27353==    by 0x400656: init_datahub_commhandler (test.c:49)
    ==27353==    by 0x4008D3: main (test.c:197)
    ==27353== 
    
    valgrind: m_mallocfree.c:303 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
    valgrind: Heap block lo/hi size mismatch: lo = 4, hi = 17179869184.
    This is probably caused by your program erroneously writing past the
    end of a heap block and corrupting heap metadata.  If you fix any
    invalid writes reported by Memcheck, this assertion failure will
    probably go away.  Please try that before reporting this as a bug.
    
    
    host stacktrace:
    ==27353==    at 0x38083F98: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
    ==27353==    by 0x380840B4: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
    ==27353==    by 0x38084241: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
    ==27353==    by 0x38091AEC: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
    ==27353==    by 0x3807D653: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
    ==27353==    by 0x3807BEE3: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
    ==27353==    by 0x380800BA: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
    ==27353==    by 0x3807B47A: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
    ==27353==    by 0x380593E1: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
    ==27353==    by 0x802D490EB: ???
    ==27353==    by 0x802CA9F2F: ???
    ==27353==    by 0x80200831F: ???
    ==27353==    by 0x4009CC: main (test.c:222)
    
    sched status:
      running_tid=1
    
    Thread 1: status = VgTs_Runnable (lwpid 27353)
    ==27353==    at 0x4009DC: main (test.c:223)
    
    
    Note: see also the FAQ in the source distribution.
    It contains workarounds to several common problems.
    In particular, if Valgrind aborted or crashed after
    identifying problems in your program, there's a good chance
    that fixing those problems will prevent Valgrind aborting or
    crashing, especially if it happened in m_mallocfree.c.
    
    If that doesn't help, please report this bug to: www.valgrind.org
    
    In the bug report, send all the above text, the valgrind
    version, and what OS and version you are using.  Thanks.
    

    任何帮助都会很棒!我在键盘上砸了一下......看起来很有效。给出这个输出

        ./test 
    initial address: (nil)
    initial address: 0x7fff41386a68
    Init datahandler memory heap
    Completed datahandler memory heap
    init address: 0x650010
    init address: 0x7fff41386a68
    a 0x650010 0x7fff41386a18
    0x650010 0x7fff413869e0
    found: 0
    inserted: 0
    a 0x650010 0x7fff41386a18
    0x650010 0x7fff413869e0
    found: 1
    inserted: 1
    a 0x650010 0x7fff41386a18
    0x650010 0x7fff413869e0
    found: 2
    inserted: 2
    a 0x650010 0x7fff41386a18
    0x650010 0x7fff413869e0
    found: 3
    inserted: 3
    a 0x650010 0x7fff41386a18
    0x650010 0x7fff413869e0
    found: 4
    inserted: 4
    a 0x650010 0x7fff41386a18
    0x650010 0x7fff413869e0
    found: 5
    inserted: 5
    a 0x650010 0x7fff41386a18
    0x650010 0x7fff413869e0
    found: 6
    inserted: 6
    a 0x650010 0x7fff41386a18
    0x650010 0x7fff413869e0
    found: 7
    inserted: 7
    found: 5
    found: 3
    found: 6
    error finding element
    a 0x650010 0x7fff41386a18
    0x650010 0x7fff413869e0
    inserted: 6
    found: 0
    Done
    

1 个答案:

答案 0 :(得分:0)

以下是我最简单的解决方案的代码,这里有一些史诗评论。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>

typedef struct mystruct_s {
    int fd;
    int a;
    int b;
} mystruct_t;

int current_elements = 0;
int max_elements = 0;

int init(int size, mystruct_t ** conn_list)
{
    if (size <= 0) {
        return (-1);
    }
    current_elements = 0;

    *conn_list = malloc(max_elements *sizeof(mystruct_t));

    if (*conn_list == NULL) {
        return (-1);
    }

    return (0);
}

void insert(int fd, mystruct_t ** conn_list, mystruct_t ** res)
{

    *res = NULL;

    if (current_elements == (max_elements)) {
        (*conn_list)[current_elements].fd = fd;
        (*conn_list)[current_elements].a = fd;
        (*conn_list)[current_elements].b = fd;
        *res = &(*conn_list)[current_elements];
        current_elements = 0;
    } else {
        (*conn_list)[current_elements].fd = fd;
        (*conn_list)[current_elements].a = fd;
        (*conn_list)[current_elements].b = fd;
        *res = &(*conn_list)[current_elements];
        current_elements++;
    }
}

int search(int fd, mystruct_t ** conn_list, mystruct_t ** res)
{
    int i = 0;
    if (*conn_list == NULL) {
        *res = NULL;        
        return (-1);
    }
    for (i = 0; i < max_elements; i++) {
        if ((*conn_list)[i].fd == fd) {
            *res = &(*conn_list)[i];
            return (1);
        }

    }
    *res = NULL;
    return (-1);
}

#define MAX_ELEMENTS 8
int main(int argc, char **argv)
{
    int size = MAX_ELEMENTS;
    mystruct_t conn_array[MAX_DEVS] = { 0 };
    mystruct_t *conn_list = NULL;

    max_elements = MAX_DEVS;

    if (init(size, &conn_list) < 0) {
        return (-1);
    }

    mystruct_t *ptr = NULL;
    int i = 0;
    for (i = 0; i < max_elements; i++) {
        conn_array[i].fd = i;
        insert(conn_array[i].fd, &conn_list, &ptr);
    }

    if ((search(conn_array[5].fd, &conn_list, &ptr)) > 0) {
        printf("Found: %d\n", ptr->fd);
    } else {
        printf("NOT found: %d\n", conn_array[5].fd);
    }

    if (conn_list != NULL) {
        free(conn_list);
    }
    return (0);
}