다음과 같이 작은 바이너리 데이터를 저장하는 데 사용되는 큐를 만들었습니다. queue_read() 및 queue_del()은 읽기 및 삭제 작업을 수행하는 큐의 한쪽에서 작동합니다. queue_add()는 큐의 다른 쪽 끝에 데이터를 추가합니다. 이 코드를 다른 코드에서 사용하여 데이터를 저장하면 세그멘테이션 오류 문제가 발생합니다. 하지만 gdb를 사용하여 세분화 문제를 일으키는 원인을 찾을 수 없었습니다. 대부분의 시간은 malloc-> memalign 문제처럼 진행되지만 null 포인터는 찾을 수 없습니다. 이 코드를 개별적으로 테스트하면 문제를 찾을 수 없습니다. 구현에 문제가있는 경우 누군가가 지적 할 수 있다는 점이 좋습니다. 감사합니다큐 알고리즘을 사용한 분할 오류
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct queue_node {
struct queue_node *next;
unsigned char data;
};
struct queue {
struct queue_node *first;
struct queue_node *last;
};
/* initialize the queue */
void init_queue(struct queue *q) {
q->first = q->last = NULL;
}
/* check if the queue is empty or not */
int queue_empty_p(const struct queue *q) {
return q->first == NULL;
}
/* Reading 'len' bytes data from queue to buffer variable 'value'
*
* RETURNS bytes read which can be less than or equal to the requested
* value of 'len'
*/
int queue_read(struct queue *q, unsigned char *read_buffer, unsigned int len) {
unsigned int i;
struct queue_node *tmp = (struct queue_node *) malloc(
sizeof(struct queue_node));
tmp = q->first;
for (i = 0; i < len; i++) {
if (tmp == NULL) {
read_buffer[i] = 0;
return (i);
}
read_buffer[i] = tmp->data;
tmp = tmp->next;
}
return len;
}
/* Deleting specified no of bytes from queue. Usually done after queue_read() */
int queue_del(struct queue *q, unsigned int no_of_bytes) {
unsigned int i;
for (i = 0; i < no_of_bytes; i++) {
if (!q->first) {
return 1;
}
struct queue_node *tmp = q->first;
if (q->first == q->last)
q->first = q->last = NULL;
else
q->first = q->first->next;
free(tmp);
}
return 0;
}
/* Adding 'len' bytes of data contained in the variable 'value' to the queue */
int queue_add(struct queue *q, unsigned char *value, unsigned int len) {
struct queue_node *node;
unsigned int i;
for (i = 0; i < len; i++) {
node = (struct queue_node *) malloc(sizeof(struct queue_node));
if (node == NULL) {
return 1;
}
node->data = *(value + i);
if (q->first == NULL)
q->first = q->last = node;
else {
q->last->next = node;
q->last = node;
}
node->next = NULL;
}
return 0;
}
int main() {
struct queue left_queue;
char *buffer = (char *)malloc(100);
int read_bytes;
strcpy(buffer, "This is a test");
init_queue(&left_queue);
queue_add(&left_queue, (unsigned char *) buffer, strlen(buffer));
queue_del(&left_queue, 3);
read_bytes = queue_read(&left_queue, (unsigned char *)buffer, 1500);
buffer[read_bytes]=0;
printf("Buffer: %s \nBytes read %d \n", (unsigned char *)buffer, read_bytes);
return 0;
}
편집 : Valgrind의의 gdb를 역 추적 출력
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb6ef3b70 (LWP 2678)]
0x0012f4df in memalign() from /usr/lib/libefence.so.0
#0 0x0012f4df in memalign() from /usr/lib/libefence.so.0
#1 0x0012f88b in malloc() from /usr/lib/libefence.so.0
#2 0x08049576 in queue_add (q=0xb7f21fc8,
value=0xb7f2da28 "GET /wiki/Special:Search?search=rohc&sourceid=Mozilla-search HTTP/1.1\r\nHost: en.wikipedia.org\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Fire"...,
len=440) at pep_core.h:248
#3 0x0804cc81 in fn_process_tcp() at pep_core.c:584
#4 0x0013b96e in start_thread() from /lib/tls/i686/cmov/libpthread.so.0
#5 0x00228a4e in clone() from /lib/tls/i686/cmov/libc.so.6
#0 0x0012f4df in memalign() from /usr/lib/libefence.so.0
No symbol table info available.
#1 0x0012f88b in malloc() from /usr/lib/libefence.so.0
No symbol table info available.
#2 0x08049576 in queue_add (q=0xb7f21fc8,
value=0xb7f2da28 "GET /wiki/Special:Search?search=rohc&sourceid=Mozilla-search HTTP/1.1\r\nHost: en.wikipedia.org\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Fire"...,
len=440) at pep_core.h:248
node = 0xb661bff8
i = 245
#3 0x0804cc81 in fn_process_tcp() at pep_core.c:584
ip_queue_table = 0xb7f2d9fc
tmp_ip_queue_table = 0x0
tcp_conn = 0xb7f21fa8
tmp_tcp_conn = 0x0
tcphdrs = 0xb7f2da14
iphdrs = 0xb7f2da00
packet_data = 0xb7f2da28 "GET /wiki/Special:Search?search=rohc&sourceid=Mozilla-search HTTP/1.1\r\nHost: en.wikipedia.org\r\nUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Fire"...
read_buffer = 0xb7f17a24 ""
read_bytes = 0
payload_size = 440
ret = 0
rawfd = 9
one = 1
#4 0x0013b96e in start_thread() from /lib/tls/i686/cmov/libpthread.so.0
No symbol table info available.
#5 0x00228a4e in clone() from /lib/tls/i686/cmov/libc.so.6
No symbol table info available.
출력
난 당신이 제안 Valgrind의 실행 다음과 같은
Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
위의 오류가 4 볼 수 있어요 번 다음 메시지는
(210)==3159== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==3159== Bad permissions for mapped region at address 0x5AD2FFC
==3159== at 0x804962F: queue_read (pep_core.h:279)
==3159== by 0x804D672: fn_thread_pep_left_sctp_client (pep_core.c:856)
==3159== by 0x403D96D: start_thread (pthread_create.c:300)
==3159== by 0x412AA4D: clone (clone.S:130)
segfault가 반드시 NULL 포인터로 인해 생성 된 것은 아닙니다. 당신은 gdb를 사용했다고 말했습니까? 세그 폴트 이후 백 트레이스를 제공 할 수 있습니까? – Florian
문제가 두 번째 프로그램이 아닌 것이 확실합니까? 내 생각 엔 잘못된 길이를'queue_read'에 전달하고 뭔가를 덮어 쓰는 것입니다. 당신이 그랬던 것처럼. –
valgrind로 테스트 해 보았습니까? 그렇다면 valgrind의 출력을 줄 수 있습니다. – tune2fs