LINUX.ORG.RU

mreamap() режет указатель до 32-битного

 , ,


0

2

Приветствую. Накидал такой код:

		void* fileMem, *pos;
		int fd, res;
		long int flen, fpos;
		size_t i,o,p;
	fd = open( "myfile.txt", O_RDONLY );
	if( fd < 0 )
		exit(1);
	flen = lseek64( fd, 0, SEEK_END );
	if( -1 == flen ){
		perror("llseek(): ");
		exit(1);
	}
	lseek64( fd, 0, SEEK_SET );

	fileMem = mmap( 0, pageLimit, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0 );
	if( fileMem == MAP_FAILED ){
		perror("llseek(): ");
		exit(1);
	}
	memset( fileMem, 'a', pageLimit );
	//fileMem = mremap(fileMem, pageLimit, pageLimit*2, 1 );  //Incorrect pointer
	fileMem = syscall(SYS_mremap, fileMem, pageLimit, pageLimit*2, 1 );  //Correct pointer
	if( fileMem == MAP_FAILED ){
		switch(errno){
			case ENOMEM:
				printf("NO memory\n");
				break;
			case EINVAL:
				printf("Invalid args\n");
				break;
		}
		perror("mremap(): ");
		exit(1);
	}

	memset( fileMem + pageLimit, 'b', pageLimit );
	write( 1, fileMem, pageLimit*2 );
И столкнулся с проблемой, библиотечная mremap() возвращает не 64-х битный указатель, а 32-х битный, что естественно влечет за собой SIGSEGV. Однако вызов mremap посредством syscall() возвращает корректный 64-х битный указатель. Кто подскажет как лечить? Можно конечно остановиться на использовании syscall(), но хочется разобраться чем вызвано такое поведение. strace показывает что системный вызов возвращает к примеру 0x7ff97af82000, а SIGSEGV происходит при обращении к адресу 0x7af83000. Следовательно именно mreamap вернула урезанное значение.

p.s. компилятор ругается на оба способа вызова mremap() так: "warning: assignment makes pointer from integer without a cast" p.p.s. список всех заголовков в коде:

#define _LARGEFILE64_SOURCE
#include <stdio.h> //printf
	#include <linux/sched.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
	#include <limits.h>
#include <errno.h>
#include <error.h>
#include <signal.h>
	#include <sys/mman.h>
#include <resolv.h>
#include <netdb.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>

p.s. компилятор ругается на оба способа вызова mremap() так: «warning: assignment makes pointer from integer without a cast»

Может он декларацию этой функции не видит? Отсюда и int взялся.

anonymous
()

А это glibc или что-то другое ?

В glibc без «#define _GNU_SOURCE» не будет прототипа mremap

vel ★★★★★
()
Ответ на: комментарий от anonymous

100%

Оп, надо включать и читать ворнинги.

anonymous
()
Ответ на: комментарий от KIR_PRO

т.е.

echo -e "#define _GNU_SOURCE\n#include <sys/mman.h>" | gcc -E - | grep mremap
ничего не выдает ?

А что за libc - glibc/uclib/eglibc

«man mremap» что говорит ?

vel ★★★★★
()
Ответ на: комментарий от vel

Выдает нормально: extern void *mremap (void *__addr, size_t __old_len, size_t __new_len,

В man написано:

#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <sys/mman.h>

OC Debian jessie. должна быть glibc

KIR_PRO
() автор топика
Ответ на: комментарий от KIR_PRO

т.е. даже добавив этот дефайн в исходник или в опции компиляции оно продолжает выдавать предупреждение и резать адрес до 32-х бит? Не верю!

vel ★★★★★
()

Добавь к опциям компилятора

-Werror=implicit-function-declaration
И лечи все сообщения об ошибках.

kawaii_neko ★★★★
()
Ответ на: комментарий от KIR_PRO

Этот дефайн нужно вписывать в исходник до всех инклюдов, или вообще компилировать с gcc -D_GNU_SOURCE=1.

intelfx ★★★★★
()
Ответ на: комментарий от KIR_PRO

https://bugs.launchpad.net/ubuntu/ source/glibc/ bug/175533

Without seeing a definition of mremap the compiler is assuming it returns an int.
Then because it's assuming that mremap returns an int, then itgets cast when it fills in the pointer.

If you put a #define __USE_GNU before the include of sys/mman.h (and an undef after it) it picks up the mremap definition and all works fine.
(Always use -Wall !)

art_corp
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.