Thread: What am I overlooking with my test code?

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,307

    What am I overlooking with my test code?

    Been trying to learn opengl but the project I was adapting to it has become a mess so I created a new project with fresh code in mind, figured I'd refresh myself on the TCHAR crap that windows introduced but found there to not be a decent API for it (for example the StringCchLength that limits the length it will check for), so I decided to write my own and map the linux equiv to plain char, I got the string functions working fine (I think, didn't fully test but no problems thus far), however a problem appeared when I tried to load a file like so:
    Code:
    int main()
    {
    	char const *dir = getcwd(NULL,0);
    	BYTES size = strlen(dir) + 1;
    	BYTES want = size + strlen(__FILE__) + 1;
    	TCS *path = new_tcs( want );
    	TCF *file;
    	tch *line;
    
    	fprintf( stderr, "path = %p\n", path );
    
    	if ( !path )
    		return EXIT_FAILURE;
    
    	sprintf( path->addr, "%s/%s", dir, __FILE__ );
    	fprintf( stderr, "Opening '%s'\n", path->addr );
    
    	file = tcf_open( NULL, path->addr, 0444, 0, 0 );
    	del_tcs( path );
    
    	if ( !file )
    		return EXIT_FAILURE;
    
    	while ( (line = tcf_next_line( file )) )
    	{
    		puts(line);
    	}
    
    	return EXIT_SUCCESS;
    }
    tcf_open is defined like this (code that matters is at the bottom):
    Code:
    TCF* tcf_open( TCF *kept, tch const * const path, uint pref, BYTES size, bool make )
    {
    	TCF *file = kept ? kept : calloc( 1, sizeof(TCF) );
    	TCS *_temp, *_path;
    	BUFF *_buff;
    	INDEX leng;
    	uint flags = 0;
    	uint as = 0;
    	int err = 0;
    
    	if ( !file )
    		return NULL;
    
    	leng = tcslen( path );
    	size = size ? size : BUFSIZ;
    
    	_buff = alt_list( &(file->buff), size, 1, 1 );
    	_path = alt_list( &(file->path), leng + 1, 1, sizeof(tch) );
    
    	if ( !_buff || !_path )
    	{
    		tcf_shut( file, !!kept );
    		return NULL;
    	}
    
    	tcsncpy( _path->addr, path, _path->have );
    
    #ifdef _WIN32
    	as = make ? CREATE_ALWAYS : OPEN_EXISTING;
    
    	flags |= (pref & 04) ? GENERIC_READ : 0;
    	flags |= (pref & 02) ? GENERIC_WRITE : 0;
    	flags |= (pref & 01) ? GENERIX_EXECUTE : 0;
    
    	file->handle = CreateFile( _path->addr, flags, 0, NULL, as, 0, NULL );
    
    	if ( !(file->handle) )
    	{
    		tcf_shut( file, !!kept );
    		return NULL;
    	}
    #else
    	as = ( make && access( path, 0 ) != 0 ) ? O_CREAT : 0;
    
    	if ( (pref & TCF_PREF_OWN_RW) == TCF_PREF_OWN_RW )
    	{
    		flags |= O_RDWR;
    	}
    	else if ( pref & TCF_PREF_OWN_RD )
    	{
    		flags |= O_RDONLY;
    	}
    	else
    	{
    		flags |= O_WRONLY;
    	}
    	//flags |= (pref & 01) ? O_EXECUTE : 0;
    	flags |= (pref & TCF_PREF_AS_DIR) ? O_DIRECTORY : 0;
    	flags |= as;
    
    	EXEC( err, file->fd = open( _path->addr, flags ), file->fd > 0 );
    #endif
    
    	return file;
    }
    And this is the output (directory has been modfied to ~):
    Code:
    make rebuild run
    rm -f *.out *.o
    cc -D _LARGEFILE64_SOURCE  -o crafters.c.o -c crafters.c -l glfw -l GL -l GLEW
    cc -D _LARGEFILE64_SOURCE  -o data.c.o -c data.c -l glfw -l GL -l GLEW
    cc -D _LARGEFILE64_SOURCE  -o error.c.o -c error.c -l glfw -l GL -l GLEW
    cc -D _LARGEFILE64_SOURCE  -o main.c.o -c main.c -l glfw -l GL -l GLEW
    cc -D _LARGEFILE64_SOURCE  -o tcf.c.o -c tcf.c -l glfw -l GL -l GLEW
    cc -D _LARGEFILE64_SOURCE  -o tcs.c.o -c tcs.c -l glfw -l GL -l GLEW
    cc -o a.out crafters.c.o data.c.o error.c.o main.c.o tcf.c.o tcs.c.o -l glfw -l GL -l GLEW
    ./a.out
    path = 0x563b631d0d70
    Opening '~/opengl_example/main.c'
    tcf.c:89: file->fd = open( _path->addr, flags )
    Error 0x00000002 (2) 'No such file or directory'
    a.out: tcf.c:89: tcf_open: Assertion `file->fd > 0' failed.
    make: *** [GNUmakefile:29: run] Aborted (core dumped)
    Compilation failed.
    Any ideas as to why an attempt to open a file via an absolute path would somehow result in a not found scenario?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,658
    > And this is the output (directory has been modfied to ~):

    But you're not opening an absolute path.
    Opening '~/opengl_example/main.c'

    It's only your shell that understands ~ and variables like $HOME.

    API calls need /path/to/some/location/filename
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,307
    No, I used an absolute path, I simply replaced it with ~ before posting, I feel uncomfortable about putting my directories on the net.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,658
    OK, so run it in the debugger, put a breakpoint on line 61 and see what happens.

    Don't rely on %s telling you what's in _path
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,307
    While I was waiting for a response I worked on a pair of functions that extracted and concated variables from the path to a text buffer (_path in this case), somehow the problem went away after I did that and used them so I'm guessing I didn't properly copy the path the first time, thanks for the input anyways, probably come back with some opengl problems (assuming I don't get a response on official forum).

    Just in case someone was interested in those functions I spoke of, here they are:
    Code:
    TCS* concate_environment_value( TCS *text, tch const *name )
    {
    	INDEX leng, used;
    	char *value = getenv( name );
    
    	if ( !value )
    	{
    		int err;
    		errno = EINVAL;
    		EXEC
    		(
    			err
    			, fprintf
    			(
    				stderr
    				, "Environment value '%s' does not exist!"
    				, name
    			)
    			, true
    		);
    		return NULL;
    	}
    
    	leng = strlen(value);
    	used = text ? tcsnlen( text->addr, text->have ) : 0;
    	text = alt_list( text, leng + used + 1, 1, sizeof(tch) );
    
    	if ( !text )
    		return NULL;
    
    	tcsncat( text->addr, value, text->have );
    
    	return text;
    }
    
    TCS* extract_environment_value( TCS *TEXT, tch *text )
    {
    	char *name = text;
    
    	++text;
    
    	if ( *text != '(' )
    	{
    		if ( *text == '$' )
    		{
    			INDEX leng = TEXT ? tcslen( TEXT->addr ) : 0;
    			TCS *_temp = alt_tcs( TEXT, leng + 1, 1, 0 );
    
    			if ( !_temp )
    				return NULL;
    
    			text = _temp->addr;
    			*(text + leng) = '$';
    			return _temp;
    		}
    
    		*name = *text;
    	}
    	else
    	{
    		for ( name = text + 1; *text && *text != ')'; ++text );
    
    		if ( !text )
    		{
    			int err;
    			errno = EINVAL;
    			EXEC( err, fputs( "Expected ')'\n", stderr ), true );
    			return NULL;
    		}
    	}
    
    	*text = 0;
    
    	return concate_environment_value( TEXT, name );
    }
    
    TCS* get_absolute_path( TCS *TEMP, TCS *PATH, tch const *path )
    {
    	void *addr;
    	INDEX leng = path ? tcslen(path) : 0, need = 0;
    	TCS *_path = alt_list( PATH, leng + 1, 1, sizeof(tch) );
    	TCS *_temp = alt_list( TEMP, leng + 1, 1, sizeof(tch) );
    	tch sep = get_dir_sep(), *text, *from;
    	tch *PFX = NULL;
    
    	if ( !_temp || !_path )
    	{
    		fail:
    		if ( !TEMP && _temp )
    			del_tcs( _temp );
    
    		if ( !PATH && _path )
    			return del_tcs( _path );
    
    		return NULL;
    	}
    
    	_temp->used = leng;
    	_path->used = 0;
    	memset( _temp->addr, 0, _temp->size );
    	memset( _path->addr, 0, _path->size );
    	tcsncpy( _temp->addr, path, _temp->have );
    	text = _temp->addr;
    
    	if ( *text == '~' )
    	{
    		addr = concate_environment_value
    		(
    			_path
    #ifdef _WIN32
    			, "HOMEPATH"
    #else
    			, "HOME"
    #endif
    		);
    
    		if ( !addr )
    			goto fail;
    
    		_path = addr;
    	}
    	else if ( *text == '$' )
    	{
    		addr = extract_environment_value( _path, text );
    
    		if ( !addr )
    			goto fail;
    
    		_path = addr;
    	}
    
    	leng = tcslen( _path->addr );
    
    	while ( *text )
    	{
    		if ( *text == '$' )
    		{
    			addr = extract_environment_value( _path, text );
    
    			if ( !addr )
    				goto fail;
    
    			_path = addr;
    			leng = tcslen( _path->addr );
    		}
    		else
    		{
    			tch *chr = _path->addr, *end = chr + leng;
    			need = leng + 2;
    
    			if ( need >= _path->have )
    			{
    				addr = alt_tcs( _path, need + BUFSIZ, 1, 0 );
    
    				if ( !addr )
    					goto fail;
    
    				_path = addr;
    				chr = _path->addr;
    				end = chr + leng;
    			}
    
    			*end = (*text == '/' || *text == '\\') ? sep : *text;
    			++end;
    			++leng;
    			*end = 0;
    		}
    		++text;
    	}
    
    	if ( !TEMP )
    		del_tcs( _temp );
    
    	leng = tcslen( path );
    	addr = dec_tcs( _path, leng + 1 );
    	_path->used = leng;
    
    	return _path;
    }
    And because they're related:
    Code:
    typedef struct _LIST
    {
    	BYTES const perN;
    	BYTES size;
    	INDEX have;
    	INDEX used;
    	void *addr;
    } LIST, BUFF, STR, WCS, TCS;
    
    typedef struct _TCF
    {
    	uint line;
    	INDEX pos;
    	TCS temp, path;
    	BUFF buff;
    #ifdef _WIN32
    	HANDLE handle;
    #else
    	int fd;
    #endif
    } TCF;
    
    struct _LIST* alt_list( struct _LIST *list, INDEX want, int only, BYTES fixed )
    {
    	BYTES size, prev;
    	char *temp;
    
    	if ( !list )
    	{
    		size = fixed;
    		list = calloc( sizeof(LIST), 1 );
    
    		if ( !list )
    			return NULL;
    
    		memset( list, 0, sizeof(LIST) );
    
    		list->size = size * want;
    		list->addr = malloc( list->size );
    
    		if ( !(list->addr) )
    		{
    			free(list);
    			return NULL;
    		}
    
    		list->have = want;
    		*((BYTES*)list) = size;
    		return list;
    	}
    
    	fixed = fixed ? fixed : list->perN;
    
    	if ( !(list->addr) )
    		memset( list, 0, sizeof(LIST) );
    
    	if ( !(list->perN) )
    		*((BYTES*)list) = fixed;
    
    	prev = list->size;
    	size = list->perN * want;
    
    	if ( size == prev )
    		return list;
    
    	if ( only > 0 && size < prev )
    		return list;
    
    	if ( only < 0 && size > prev )
    		return NULL;
    
    	if ( !size )
    	{
    		if ( list->addr );
    			free( list->addr );
    
    		memset( list, 0, sizeof(LIST) );
    
    		if ( !fixed )
    			free( list );
    
    		return NULL;
    	}
    
    	temp = prev ? realloc( list->addr, size ) : malloc( size );
    
    	if ( !temp )
    		return NULL;
    
    	if ( size > prev )
    		memset( temp + prev, 0, size - prev );
    
    	list->size = size;
    	list->addr = temp;
    	list->have = size / list->perN;
    	return list;
    }
    Now I got some Japanese to revise then I'll have to track the cause of an infinite loop, if anyone cares to do that for me while I catch up on my studies (I'm not holding my breath on that one) then the faulty function is here:
    Code:
    tch* tcf_next_line( TCF *file )
    {
    	TCS *_temp;
    	BUFF *_buff = alt_list( &(file->buff), BUFSIZ, 1, 1 );
    	INDEX max;
    	ssize_t done = 0;
    	bool eof = false;
    	tch *line;
    
    	if ( !_buff )
    		return NULL;
    
    	max = _buff->size / sizeof(tch);
    
    	_temp = alt_list( &(file->temp), max + 1, 1, sizeof(tch) );
    
    	if ( !_temp )
    		return NULL;
    
    	line = _temp->addr;
    
    	while ( !eof )
    	{
    		tch *chr, *end;
    		char *_line, *_chr, *_end;
    		BYTES kept, lost;
    		int err = 0;
    
    		if ( !_temp )
    			return NULL;
    
    		/* This can change per loop so cannot store outside */
    		line = _temp->addr;
    		_line = _temp->addr;
    		_end = _line + _temp->size;
    		end = (tch*)end;
    
    		chr = line;
    
    		/* First we find where the start of our line string is */
    		if ( !done )
    		{
    			for ( chr = line; *chr; ++chr );
    
    			_chr = (char*)chr;
    
    			for ( ; chr < end; ++chr );
    
    			if ( chr < end )
    				_chr = (char*)chr;
    			else
    				chr = (tch*)_chr;
    
    			/* Now we move it forward */
    			if ( chr != line )
    			{
    				kept = (BYTES)(_end - _chr);
    				lost = (BYTES)(_chr - _line);
    				tcsnmov( line, chr, _temp->have );
    				memset( _line + kept, 0, lost );
    			}
    		}
    
    		/* Now we find the new line character */
    		for ( chr = line; *chr && *chr != '\n' && *chr != '\r'; ++chr );
    
    		if ( *chr )
    		{
    			for ( ; *chr == '\n' || *chr == '\r'; ++chr )
    			return line;
    		}
    
    		_chr = (char*)chr;
    		kept = (BYTES)(_chr - _line);
    		lost = (BYTES)(_end - _chr);
    		max = _temp->have + kept;
    
    		_temp = alt_list( &(file->temp), max + 1, 1, sizeof(tch) );
    
    #ifdef _WIN32
    		done = ReadFile( file->handle, _buff->size, _buff->size );
    #else
    		done = read( file->fd, _buff->addr, _buff->size );
    		err = errno;
    #endif
    		/* TODO: Implement conversion from base encoding to tch encoding */
    		memcpy( chr, _buff->addr, done );
    
    		eof = ( done < 0 || (BYTES)done < _buff->size );
    	}
    
    	return *line ? line : NULL;
    }

  6. #6
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,307
    For anyone that was looking for the fault in the bottom function in my previous post, I found it, turned out I had not cleared the remaining bytes correctly, here's the correct code for that section:
    Code:
    			/* Now we move it forward */
    			if ( chr != line )
    			{
    				tch *_tmp;
    				char *tmp;
    				kept = tcslen( chr );
    				tmp = chr + kept;
    				_tmp = (char*)tmp;
    				lost = (BYTES)(_end - _tmp);
    				tcsnmov( line, chr, _temp->have );
    				memset( _line + kept, 0, lost );
    			}

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,307
    Okay I'm encountering a strange bug now.

    This infinity loops:
    Code:
    	while ( (line = tcf_next_line( file )) )
    	{
    		puts( line );
    	}
    But this doesn't:
    Code:
    	while ( (line = tcf_next_line( file )) )
    	{
    		fputs( line, stdout );
    	}
    Now I very much doubt it's a bug with puts() so that leaves tcf_next_line(), however I don't see how that bugs out only on puts() but not fputs(), if someone spots the cause I'll very much appreciate it, for now though it's about time I started with OpenGL code, gonna take a break first though.

    Edit: Says he'll take a break, says he'll get started with OpenGL code, instead he debugs and finally uncovers the bug:
    Code:
    end = (tch*)_end;
    Was:
    Code:
    end = (tch*)end;

  8. #8
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,307
    Was testing my code with valgrind and there appears to be an issue with calloc & co on my system, at the very least I couldn't see anything in my code that would lead to it, rather according to some of the stacks reported by valgrind some of them actually start with glfw & various other functions where it is impossible for me to have indirectly affected it, but before I go off reporting an issue I figured I'd try writing my own handlers using mmap(), naturally some issues cropped up so here I am:

    Code:
    valgrind --leak-check=yes --track-origins=yes ./d.out
    ==50432== Memcheck, a memory error detector
    ==50432== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==50432== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
    ==50432== Command: ./d.out
    ==50432==
    ==50432== Invalid write of size 1
    ==50432==    at 0x4848138: memset (vg_replace_strmem.c:1270)
    ==50432==    by 0x10B494: paw_allocp (data.c:26)
    ==50432==    by 0x10B846: paw_realloc (data.c:153)
    ==50432==    by 0x10B951: new__list (data.c:194)
    ==50432==    by 0x10AE0A: load_and_init_crafters (crafters.c:199)
    ==50432==    by 0x10D530: init_opengl (main.c:519)
    ==50432==    by 0x10D21A: main (main.c:394)
    ==50432==  Address 0xffffffffffffffff is not stack'd, malloc'd or (recently) free'd
    ==50432==
    ==50432==
    ==50432== Process terminating with default action of signal 11 (SIGSEGV): dumping core
    ==50432==  Access not within mapped region at address 0xFFFFFFFFFFFFFFFF
    ==50432==    at 0x4848138: memset (vg_replace_strmem.c:1270)
    ==50432==    by 0x10B494: paw_allocp (data.c:26)
    ==50432==    by 0x10B846: paw_realloc (data.c:153)
    ==50432==    by 0x10B951: new__list (data.c:194)
    ==50432==    by 0x10AE0A: load_and_init_crafters (crafters.c:199)
    ==50432==    by 0x10D530: init_opengl (main.c:519)
    ==50432==    by 0x10D21A: main (main.c:394)
    ==50432==  If you believe this happened as a result of a stack
    ==50432==  overflow in your program's main thread (unlikely but
    ==50432==  possible), you can try to increase the size of the
    ==50432==  main thread stack using the --main-stacksize= flag.
    ==50432==  The main thread stack size used in this run was 8388608.
    Copying the entire log here seemed a bit stupid so the above is the top extract. Likewise I saw no need to copy the entire file here so I've given just the top extract below. The line that apparently segfaults is the one that clears the 1st few bytes of the page, considering I already checked for NULL I don't see why that happens, any ideas?

    Code:
    #include "example.h"
    #include <sys/mman.h>
    
    typedef struct _ADDR
    {
    	char desc[4];
    	size_t size;
    	struct _ADDR * prev;
    	struct _ADDR * next;
    } PAGE;
    
    size_t sizeof_pages( size_t size )
    {
    	size_t need = sysconf(_SC_PAGE_SIZE);
    	size = ((size / need) + !!(size % need)) * need;
    	return sizeof(PAGE) + size;
    }
    
    PAGE * paw_allocp( size_t size )
    {
    	size_t need = sizeof_pages(size);
    	PAGE *page = mmap( NULL, need, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0 );
    
    	if ( page )
    	{
    		memset( page, 0, sizeof(PAGE) );
    		page->size = need;
    		strcpy( page->desc, "MAP" );
    	}
    
    	return page;
    }
    
    PAGE * paw_freep( PAGE * page )
    {
    	munmap( page, page->size );
    }
    
    void * paw_realloc( void *ptr, size_t size )
    {
    	PAGE *temp = NULL;
    	struct _ADDR *addr = NULL, *prev = NULL, *next;
    	size_t need = size + sizeof(void*), offset;
    	void * tmp = NULL;
    
    	if ( ptr )
    	{
    		/* Does it look like an address we allocated? */
    		addr = (void*)(((char*)ptr) - sizeof(struct _ADDR));
    
    		if ( strcmp( addr->desc, "PTR" ) != 0 )
    			return NULL;
    
    		/* Does it look like a page we allocated? */
    		prev = addr;
    		for ( temp = prev; temp; prev = temp, temp = temp->prev );
    		temp = prev - 1;
    
    		if ( strcmp( temp->desc, "MAP" ) != 0 )
    			return NULL;
    
    		/* Should we free the pointer? */
    		if ( !size )
    		{
    			free_addr:
    			if ( addr->prev )
    				addr->prev->next = addr->next;
    
    			if ( addr->next )
    				addr->next->prev = addr->prev;
    
    			if ( !(addr->next) && !(addr->prev) )
    			{
    				temp = addr - 1;
    
    				if ( strcmp( temp->desc, "MAP" ) != 0 )
    					return NULL;
    
    				if ( temp->prev )
    					temp->prev->next = temp->next;
    
    				if ( temp->next )
    					temp->next->prev = temp->prev;
    
    				paw_freep( temp );
    			}
    
    			return NULL;
    		}
    
    		/* Can we make do with current pointer? */
    		if ( addr->next )
    		{
    			offset = ((char*)(addr->next)) - ((char*)ptr);
    
    			if ( offset >= size )
    			{
    				addr->size = size;
    				return ptr;
    			}
    		}
    
    		offset = ((char*)ptr) - ((char*)temp);
    		if ( !(addr->next) && (temp->size - offset) >= size )
    		{
    			if ( !size )
    				goto free_addr;
    
    			addr->size = size;
    			return ptr;
    		}
    	}
    
    	if ( temp )
    	{
    		use_page:
    
    		/* Look for available space */
    		for ( ; addr->next; addr = addr->next )
    		{
    			if ( addr->size || !(addr->next) )
    				continue;
    
    			tmp = addr + 1;
    			offset = (((char*)(addr->next)) - ((char*)tmp));
    
    			if ( offset < size )
    				continue;
    
    			addr->size = size;
    			strcpy( addr->desc, "PTR" );
    			return tmp;
    		}
    
    		/* Is the remaining space enough? */
    		prev = addr;
    		addr = (struct _ADDR*)(((char*)(addr + 1)) + addr->size);
    
    		tmp = addr + 1;
    		offset = ((char*)tmp) - ((char*)temp);
    
    		if ( !(addr->size) && (temp->size - offset) >= size )
    		{
    			use_addr:
    			addr->prev = prev;
    			addr->size = size;
    			addr->next = (void*)(((char*)tmp) + size);
    			return tmp;
    		}
    	}
    
    	/* Get new set of pages to work with */
    	next = paw_allocp( size + sizeof(struct _ADDR) );
    
    	if ( !(next) )
    		return NULL;
    
    	/* Should we free current page/s? */
    	addr = temp + 1;
    
    	if ( !(addr->next) && !(addr->size) )
    	{
    		next->prev = temp->prev;
    
    		if ( temp->prev )
    			temp->prev->next = next;
    
    		paw_freep( temp );
    	}
    	else
    	{
    		next->next = temp->next;
    		temp->next = next;
    		next->prev = temp;
    	}
    
    	next->size = size;
    	addr = next + 1;
    	memset( addr, 0, sizeof(struct _ADDR) );
    	temp = next;
    	goto use_page;
    }
    
    #define paw_malloc( size ) paw_realloc( NULL, size )
    #define paw_free( ptr ) paw_realloc( ptr, 0 )

  9. #9
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,307
    Okay now I know part of the reason why I was getting segfaults, I thought, like a numpty, that mmap would return NULL on failure since that is universally recognised as an invalid address, nope, it returns (void*)-1 on failure :|

    Anyways I now need to figure out why I'm getting a failure, while I'm doing that here's what shows up from valgrind now that I check for (void*)-1

    Code:
    ==53259== Memcheck, a memory error detector
    ==53259== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==53259== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
    ==53259== Command: ./d.out
    ==53259==
    ==53259==
    ==53259== HEAP SUMMARY:
    ==53259==     in use at exit: 345,932 bytes in 3,442 blocks
    ==53259==   total heap usage: 48,558 allocs, 45,116 frees, 19,349,259 bytes allocated
    ==53259==
    ==53259== 844 bytes in 1 blocks are definitely lost in loss record 2,336 of 2,362
    ==53259==    at 0x483E7C5: malloc (vg_replace_malloc.c:380)
    ==53259==    by 0x5B3D8BC: ???
    ==53259==    by 0x5B3DB97: ???
    ==53259==    by 0x49D0B89: glxewInit (in /usr/lib/libGLEW.so.2.2.0)
    ==53259==    by 0x49DC231: glewInit (in /usr/lib/libGLEW.so.2.2.0)
    ==53259==    by 0x10D156: main (main.c:386)
    ==53259==
    ==53259== LEAK SUMMARY:
    ==53259==    definitely lost: 844 bytes in 1 blocks
    ==53259==    indirectly lost: 0 bytes in 0 blocks
    ==53259==      possibly lost: 0 bytes in 0 blocks
    ==53259==    still reachable: 345,032 bytes in 3,439 blocks
    ==53259==         suppressed: 56 bytes in 2 blocks
    ==53259== Reachable blocks (those to which a pointer was found) are not shown.
    ==53259== To see them, rerun with: --leak-check=full --show-leak-kinds=all
    ==53259==
    ==53259== For lists of detected and suppressed errors, rerun with: -s
    ==53259== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
    Dunno about everyone else but I don't see any way that memory allocation issue could be from my own code.

    Edit: I had to defined if it was private or shared, should really just default to private if not defined.

  10. #10
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,307
    Attached a copy of file with faulty code, somewhere in the paw_realloc() path of logic I manage to mis-allocate memory, the main function that is relied upon is paw__realloc(), the rest are more for new memory allocations, someone mind taking a look please? I need a break and I'm not seeing the cause anyways.

    Edit: I should mention that this code at line 356 near the bottom of the file is how I realised I mis-allocated memory:

    Code:
    memset( temp + prev, 0, size - prev );
    Overwrites the list->perN parameter to 0 causing a SIG_FPE later.
    Attached Files Attached Files

  11. #11
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,307
    I think I fixed it:

    Code:
    void * paw__realloc( PAGE *page, struct _ADDR *addr, size_t size )
    {
    	char *ptr, *end, *nxt, *tmp;
    
    	if ( !size )
    	{
    		if ( addr->prev )
    			addr->prev->next = addr->next;
    
    		if ( addr->next )
    			addr->next->prev = addr->prev;
    
    		addr->size = 0;
    		return NULL;
    	}
    
    	end = ((char*)page) + page->size;
    	ptr = (char*)(addr + 1);
    	nxt = ptr + size;
    	tmp = addr->next ? (char*)(addr->next) : end;
    
    	/* Can we make do with current pointer? */
    	if ( nxt > tmp )
    		return NULL;
    
    	addr->desc = ADDR_DESC;
    	addr->size = size;
    
    	if ( addr->next )
    		return ptr;
    
    	tmp = end - (sizeof(struct _ADDR*) + 1);
    
    	if ( nxt < tmp )
    	{
    		addr->next = memset( nxt, 0, sizeof(struct _ADDR) );
    		addr->next->prev = addr;
    	}
    
    	return ptr;
    }
    Get's further but either it or another piece of code is faulty because a line that succeeded before I started this code is now failing, the only reason for failure is not getting the buffers it's expecting, however lines before it that get buffers do succeed so I'm at least along the right path of logic.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What am I overlooking with my library?
    By awsdert in forum C Programming
    Replies: 26
    Last Post: 05-01-2021, 04:42 AM
  2. Overlooking Something in an Array
    By Feralix in forum C Programming
    Replies: 8
    Last Post: 07-09-2016, 01:37 AM
  3. Replies: 8
    Last Post: 12-10-2014, 03:00 PM
  4. Overlooking something in a comparison
    By csharp100 in forum C Programming
    Replies: 7
    Last Post: 04-29-2012, 09:21 PM
  5. probably something simple I'm overlooking
    By tomasc in forum C++ Programming
    Replies: 3
    Last Post: 05-19-2008, 11:07 PM

Tags for this Thread