Wątek przeniesiony 2015-10-10 20:31 z Nietuzinkowe tematy przez Rev.

Naruszenie ochrony pamięci, prosty program, Debian

0

Witam,
Przedstawiam Wam zminimalizowany do minimum program, który po cięciach jest bez sensu, ale gdzieś w nim(?) jest błąd:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>


static void * sender(void * dev){
	char frame[64];
	char * line;
	char * arg;
	char fmt[64]; // po wywaleniu - OK
	
	size_t len;
	
	char * pd;
	
	FILE * f = fopen("test-file", "w");
	pd = frame; // jesli zakomentowane - OK
	while(getline(&line, &len, stdin)>0){
		
		arg = line; // jesli zakomentowane - OK
	}
	fclose(f);
	printf("END STDIN\n");
	for(;;) sleep(1);
}

int main(int argc, char * argv[]){
	pthread_t sender_thread;
	pthread_create(&sender_thread, NULL, sender, NULL);
	for(;;) sleep(1);
	return 0;
}

Po migracji z Slackware na Debiana, program przestał działać, efektem jest:

$ gcc -lpthread -o main main.c && echo asd | ./main
Naruszenie ochrony pamięci

strace & uname:

$ gcc -lpthread -o main main.c && echo asd | strace -f ./main
execve("./main", ["./main"], [/* 45 vars */]) = 0
brk(0)                                  = 0x213d000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe8725d1000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=123230, ...}) = 0
mmap(NULL, 123230, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe8725b2000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20o\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=137440, ...}) = 0
mmap(NULL, 2213008, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe872196000
mprotect(0x7fe8721ae000, 2093056, PROT_NONE) = 0
mmap(0x7fe8723ad000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7fe8723ad000
mmap(0x7fe8723af000, 13456, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe8723af000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1729984, ...}) = 0
mmap(NULL, 3836448, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe871ded000
mprotect(0x7fe871f8c000, 2097152, PROT_NONE) = 0
mmap(0x7fe87218c000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19f000) = 0x7fe87218c000
mmap(0x7fe872192000, 14880, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe872192000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe8725b1000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe8725b0000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe8725af000
arch_prctl(ARCH_SET_FS, 0x7fe8725b0700) = 0
mprotect(0x7fe87218c000, 16384, PROT_READ) = 0
mprotect(0x7fe8723ad000, 4096, PROT_READ) = 0
mprotect(0x7fe8725d3000, 4096, PROT_READ) = 0
munmap(0x7fe8725b2000, 123230)          = 0
set_tid_address(0x7fe8725b09d0)         = 1618
set_robust_list(0x7fe8725b09e0, 24)     = 0
rt_sigaction(SIGRTMIN, {0x7fe87219c9f0, [], SA_RESTORER|SA_SIGINFO, 0x7fe8721a58d0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x7fe87219ca80, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x7fe8721a58d0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fe8715ec000
brk(0)                                  = 0x213d000
brk(0x215e000)                          = 0x215e000
mprotect(0x7fe8715ec000, 4096, PROT_NONE) = 0
clone(child_stack=0x7fe871debff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fe871dec9d0, tls=0x7fe871dec700, child_tidptr=0x7fe871dec9d0) = 1619
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, Process 1619 attached
 <unfinished ...>
[pid  1619] set_robust_list(0x7fe871dec9e0, 24) = 0
[pid  1619] mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7fe8695ec000
[pid  1619] munmap(0x7fe8695ec000, 44122112) = 0
[pid  1619] munmap(0x7fe870000000, 22986752) = 0
[pid  1619] mprotect(0x7fe86c000000, 135168, PROT_READ|PROT_WRITE) = 0
[pid  1619] open("test-file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
[pid  1619] fstat(0, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
[pid  1619] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe8725d0000
[pid  1619] read(0, "asd\n", 4096)      = 4
[pid  1619] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x7fe871df6920} ---
[pid  1619] +++ killed by SIGSEGV +++
+++ killed by SIGSEGV +++
Naruszenie ochrony pamięci

$ uname -a
Linux darkstar 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1+deb8u3 (2015-08-04) x86_64 GNU/Linux

Wygląda jakby dla wątków był przydzielany mały stos, ale bez przesady...
Co może być nie tak?

1

Masz UB. Cytat z mana-a funkcji getline:
http://man7.org/linux/man-pages/man3/getline.3.html

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate a buffer for storing the line. (...)
Alternatively, before calling getline(), *lineptr can contain a pointer to a malloc(3)-allocated buffer *n bytes in size.

1 użytkowników online, w tym zalogowanych: 0, gości: 1