다음은 프로그램 초기화시 생성 된 동적으로 할당 된 구조의 수를 모니터하는 C 프로그램입니다. 구조체는 현재 (fd) 베어 본 요구 사항을 가지고 있습니다. 그것은 파일 기술자에게 C Valgrind stacktrace fail, 구조체의 선형 malloc 배열
- 효과적으로
,
문제는 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
[최소 테스트 케이스] (http://stackoverflow.com/help/mcve)를 구성하십시오. –
Oliver, 업데이트했습니다. – mcdoomington
MCVE ([MCVE])를 만드는 방법을 읽어보십시오. MCVE는 자체 포함 (자체 데이터를 생성 또는 포함)하거나 사용 된 데이터를 지정해야합니다. 보고 된 오류는 간단합니다. Valgrind는 할당 된 구조의 끝을 넘어 서면 쓰고 있음을 확인하고 있습니다. 'dev_con_state_t * tmp = conn_list + (sizeof (dev_con_state_t) * current_elements);'- 왜 크기를 곱한거야? C는 이미 개체의 크기만큼 포인터 연산을 조정합니다. 당신은'dev_con_state_t * temp = conn_list + current_elements; '를 의미합니다. –