2013-09-03 28 views
6

Tôi có một vấn đề rất bực bội. Ứng dụng của tôi chạy trên một vài máy hoàn hảo trong một tháng. Tuy nhiên, có một máy mà ứng dụng của tôi bị treo gần như mỗi ngày do sự phân đoạn. Nó luôn luôn treo tại địa chỉ lệnh tương tự:segfault trong khi ghi vào khu vực realloc'd

segfault at 7fec33ef36a8 ip 000000000041c16d sp 00007fec50a55c80 error 6 in myapp[400000+f8000] 

điểm địa chỉ này để memcpy gọi.

Dưới đây, có một đoạn trích # 1 từ ứng dụng của tôi:

.... 
uint32_t size = messageSize - sizeof(uint64_t) + 1; 

stack->trcData = (char*)Realloc(stack->trcData,(stack->trcSize + size + sizeof(uint32_t))); 
char* buffer = stack->trcData + stack->trcSize; 

uint32_t n_size = htonl(size); 
memcpy(buffer,&n_size,sizeof(uint32_t)); /* ip 000000000041c16d points here*/ 
buffer += sizeof(uint32_t); 

.... 
stack->trcSize += size + sizeof(uint32_t); 
.... 

nơi stack là một cấu trúc:

struct Stack{ 
    char*  trcData;  
    uint32_t trcSize;  
    /* ... some other elements */ 
}; 

Realloc là một wrapper realloc:

#define Realloc(x,y) _Realloc((x),(y),__LINE__) 

void* _Realloc(void* ptr,size_t size,int line){ 

    void *tmp = realloc(ptr,size); 
    if(tmp == NULL){ 
    fprintf(stderr,"R%i: Out of memory: trying to allocate: %lu.\n",line,size); 
    exit(EXIT_FAILURE); 
    } 
    return tmp; 
} 

messageSize làLoạivà giá trị của nó luôn lớn hơn 44 byte. Mã số 1 chạy trong một vòng lặp. stack->trcData chỉ là một bộ đệm thu thập một số dữ liệu cho đến khi một số điều kiện được đáp ứng. stack->trcData luôn được khởi tạo thành NULL. Ứng dụng được biên dịch với gcc với tối ưu hóa -O3 được bật. Khi tôi chạy nó trong gdb, tất nhiên nó không sụp đổ, như tôi mong đợi;)

Tôi đã hết ý tưởng tại sao myapp gặp sự cố trong khi gọi memcpy. Realloc trả về không có lỗi, vì vậy tôi đoán nó phân bổ đủ không gian và tôi có thể viết thư cho khu vực này. Valgrind

valgrind --leak-check=full --track-origins=yes --show-reachable=yes myapp 

hiển thị hoàn toàn không có lần đọc/ghi không hợp lệ.

Có thể trên máy tính cụ thể này bản thân bộ nhớ bị hỏng và gây ra các lỗi này thường xuyên không? Hoặc có lẽ tôi bị hỏng bộ nhớ ở một nơi khác trong myapp, nhưng nếu đây là trường hợp, tại sao nó không sụp đổ trước đó, khi viết không hợp lệ được thực hiện?

Cảm ơn trước vì đã được trợ giúp.

hội mảnh:

41c164: 00 
41c165: 48 01 d0    add %rdx,%rax 
41c168: 44 89 ea    mov %r13d,%edx 
41c16b: 0f ca     bswap %edx 
41c16d: 89 10     mov %edx,(%rax) 
41c16f: 0f b6 94 24 47 10 00 movzbl 0x1047(%rsp),%edx 
41c176: 00 

Tôi không chắc chắn cho dù thông tin này là có liên quan nhưng tất cả các máy móc, ứng dụng của tôi chạy trên thành công, có bộ xử lý Intel trong khi một gây ra vấn đề có AMD.

+0

Bạn/nơi đặt 'stack-> trcData' ban đầu như thế nào? Làm thế nào/nơi là 'messageSize' thiết lập? Segfault của bạn có thể là do lỗi quản lý bộ nhớ trong mã của bạn, nhưng bạn không có đủ phần ở đây để xác định điều đó. – lurker

+4

Tôi sẽ không loại trừ phần cứng bị lỗi. Yêu cầu quản trị viên hệ thống của bạn chạy thử nghiệm bộ nhớ nặng trên máy tính nơi mã của bạn gặp sự cố và xem họ có thể cho bạn biết điều gì thú vị không. – dasblinkenlight

+0

@mbratch 'stack-> trcData' được đặt thành' NULL' ban đầu. Giá trị được gán cho 'messageSize' và nó luôn được chọn. –

Trả lời

0

Đây là nguyên nhân gây ra sự cố của tôi. Vấn đề là ở một số bước vòng lặp stack->trcSize + size vượt quá UINT32_MAX. Điều đó có nghĩa là Realloc trên thực tế co lại stc->trcData. Tiếp theo, tôi xác định buffer mà bây giờ là xa phía sau khu vực được phân bổ. Do đó, khi tôi viết vào bộ đệm, tôi nhận được segfault. Tôi đã kiểm tra nó và nó thực sự là nguyên nhân.

Các vấn đề liên quan