Thread: Retrieving information just outside a duplicate function

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

    Retrieving information just outside a duplicate function

    So I have been plugging in freeglut to lua for my own purposes (wanted to use IUP or CEGUI but neither is compiling/installing) and have been working on the callback section since I can create and destroy windows just fine, had a working version before but that only applied to 1 window/control, in my attempts to make that support multiple windows I've had to implement my own memory allocator (which I suspect most of the readers of this post will already know about my difficulty with), after getting that working I've tried to actually use it for the original purpose (one permanent allocation while the window exists and then just hook the allocation whenever told to), unfortunately freeglut segfaults deep down the line, I think it's because of how I'm attempting to retrieve the window id
    Code:
    typedef enum foo_cb_id {
    	foo_cb_id_close,
    	foo_cb_id_display,
    	foo_cb_id_idle,
    	foo_cb_id_keyboard,
    	foo_cb_id_reshape,
    	foo_cb_id_special,
    	foo_cb_id_count,
    } foo_cb_id_t;
    foo_cb_info_t foo_callbacks[foo_cb_id_count] = {{0}};
    typedef struct foo_window {
    	int window_id;
    	int parent_id;
    	int lua_cb[foo_cb_id_count];
    	void *foo_cb[foo_cb_id_count];
    } foo_window_t;
    std_list g_window_list = {0};
    foo_window_t **g_windows = NULL;
    int g_current_window = 0;
    long g_foo_window_size = 0;
    ...
    void foo_cb_display() {
    	volatile int *lua_cb = (int*)(((uintptr_t)(&lua_cb)
    		- foo_callbacks[foo_cb_id_display].pos)
    		+ (sizeof(int) * 2) + (sizeof(int) * foo_cb_id_display));
    	if ( *lua_cb == 0 ) return;
    	lua_rawgeti( g_L, LUA_REGISTRYINDEX, *lua_cb );
    	lua_pushvalue( g_L, 1 );
    	if ( 0 != lua_pcall( g_L, 0, 0, 0 ) )
    		printf("%s\n", lua_tostring( g_L, -1 ) );
    }
    int foo_glutDisplayFunc( lua_State *L ) {
    	foo_window_t *window = g_windows[g_current_window];
    	if ( lua_isfunction(L,-1) ) {
    		window->lua_cb[foo_cb_id_display] =
    			luaL_ref( L, LUA_REGISTRYINDEX );
    		glutDisplayFunc(
    			(void (*)(void))(window->foo_cb[foo_cb_id_display]));
    		lua_pushboolean(L,1);
    	}
    	else {
    		window->lua_cb[foo_cb_id_display] = 0;
    		glutDisplayFunc(NULL);
    		lua_pushboolean(L,0);
    	}
    	return 1;
    }
    ...
    int foo_need_window() {
    	uchar *mem;
    	size_t pos, i, need;
    	foo_cb_info_t *info;
    	foo_window_t *window;
    	std_list list = g_window_list;
    	std_data data = {0};
    	int w;
    	list.perN = sizeof(foo_window_t*);
    	if ( list.upto < 0 ) list.upto = 0;
    	if ( list.used > list.upto ) list.used = list.upto;
    	g_window_list = list;
    	for ( w = 0; w < list.used; ++w ) {
    		if ( !(g_windows[w]) ) break;
    	}
    	if ( w == list.upto ) {
    		if ( (errno = alloc_std_list( &list, list.used + 100 ))
    			!= EXIT_SUCCESS )
    			return errno;
    		g_window_list = list;
    		g_windows = (foo_window_t**)(list.data.data);
    	}
    	pos = sizeof(foo_window_t);
    	for ( i = 0; i < foo_cb_id_count; ++i ) {
    		info = &(foo_callbacks[i]);
    		if ( !info->size ) {
    			puts("info->size was 0!");
    			exit(ERANGE);
    			return ERANGE;
    		}
    		info->pos = pos;
    		need = info->size + (sizeof(int) - (info->size % sizeof(int)));
    		pos += need;
    	}
    	g_foo_window_size = pos;
    	if ( (errno = alloc_foo_data( &data, pos ))
    		!= EXIT_SUCCESS )
    		return errno;
    	g_windows[w] = window = data.data;
    	(void)memset( window, 0, pos );
    	window->parent_id = g_current_window;
    	window->window_id = w;
    	mem = data.data;
    	for ( i = 0; i < foo_cb_id_count; ++i ) {
    		info = &(foo_callbacks[i]);
    		window->foo_cb[i] = &mem[info->pos];
    		(void)memcpy(
    			&(mem[info->pos]),
    			info->cb,
    			info->size );
    	}
    	g_current_window = w;
    	return EXIT_SUCCESS;
    }
    int foo_glutCreateWindow( lua_State *L ) {
    	int ret = foo_need_window();
    	char const *title = foo_getstring( L, -1 );
    	foo_window_t *window = NULL;
    	if ( !title ) title = "main";
    	if ( ret != EXIT_SUCCESS ) {
    		failed:
    		printf( "Error: %s() 0x%08X %s\n",
    			__func__, errno, strerror(ret) );
    		lua_pushinteger(L,-1);
    		return 1;
    	}
    	window = g_windows[g_current_window];
    	window->window_id = glutCreateWindow(title);
    	if ( window->window_id < 0 ) {
    		ret = errno;
    		goto failed;
    	}
    	lua_pushinteger(L,g_current_window);
    	return 1;
    }
    int foo_glutCreateSubWindow( lua_State *L ) {
    	int ret = foo_need_window();
    	int argc, args[5], pos;
    	foo_window_t *window = NULL;
    	if ( ret != EXIT_SUCCESS ) {
    		failed:
    		printf("Error: %s() 0x%08X %s\n",
    			__func__, ret, strerror(ret) );
    		lua_pushinteger(L,-1);
    		return 1;
    	}
    	for ( argc = 0, pos = -1; argc < 5; ++argc, --pos ) {
    		if ( lua_isinteger(L,pos) || lua_isnumber(L,pos) )
    			args[argc] = lua_tointeger(L,pos);
    		else {
    			printf("Argument %d was not an integer\n", -pos);
    			luaL_error(L,
    				"Usage: glut.CreateSubWindow( parent, x, y, w, h )");
    			ret = EINVAL;
    			goto failed;
    		}
    	}
    	window = g_windows[g_current_window];
    	window->window_id =
    		glutCreateSubWindow(args[4],args[3],args[2],args[1],args[0]);
    	if ( window->window_id < 0 ) {
    		ret = errno;
    		goto failed;
    	}
    	lua_pushinteger(L,g_current_window);
    	return 1;
    }
    I'm gonna go eat something since it will probably take a while for peops to look through that, let me know of where you need comments added in to get a clearer picture of what is going on

  2. #2
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Code:
        volatile int *lua_cb = (int*)(((uintptr_t)(&lua_cb)
            - foo_callbacks[foo_cb_id_display].pos)
            + (sizeof(int) * 2) + (sizeof(int) * foo_cb_id_display));
    what is that?

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by Hodor View Post
    Code:
        volatile int *lua_cb = (int*)(((uintptr_t)(&lua_cb)
            - foo_callbacks[foo_cb_id_display].pos)
            + (sizeof(int) * 2) + (sizeof(int) * foo_cb_id_display));
    what is that?
    That's where I store the lua index given when lua calls foo_glutDisplayFunc like in this snippet:
    Code:
    glut.DisplayFunc(
    	function()
    		gl.Clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT)
    		--glut.PostRedisplay()
    		--gl.Flush()
    		glut.SwapBuffers()
    	end
    )
    Basically I'm trying to make the results of the lua api similar to what one would expect if they called the same function in c like below:
    Code:
    ...
    parent = glutCreateWindow( title )
    glutDisplayFunc( parent_ondisplay );
    edit = glutCreateSubWindow( parent, 15, 15, 100, 20 )
    glutDisplayFunc( edit_ondisplay );
    Edit: The predefined foo_cb_display doesn't get called, only the copy of it gets called, that copy allocated along side a foo_window_t object to allow it to retrieve the window it is supposed to be dealing with
    Last edited by awsdert; 01-07-2020 at 05:57 AM.

  4. #4
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    I don't understand. I've written heaps of code that uses Lua and never had to resort to something like the snippet I've quoted. Is this another example of abstraction?

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Decided the other way was not only unclear but more likely to be wrong, so I've now changed things a bit so the index of the foo_window_t object is placed straight after each duplicate function and then changed each predefined callback to look like this:
    Code:
    void foo_cb_display() {
    	foo_cb_info_t *info = &(foo_callbacks[foo_cb_id_display]);
    	int wid = ((uintptr_t)&wid) + (info->size - sizeof(int));
    	foo_window_t *window = g_windows[wid];
    	int lua_cb = window->lua_cb[foo_cb_id_display];
    	if ( lua_cb == 0 ) return;
    	lua_rawgeti( g_L, LUA_REGISTRYINDEX, lua_cb );
    	lua_pushvalue( g_L, 1 );
    	if ( 0 != lua_pcall( g_L, 0, 0, 0 ) )
    		printf("%s\n", lua_tostring( g_L, -1 ) );
    }

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Out of curiosity, but why are you using the address of a local variable to compute wid, which is then immediately used in the expression g_windows[wid]? This is with reference to:
    Code:
    int wid = ((uintptr_t)&wid) + (info->size - sizeof(int));
    For this to work correctly, the address of the local variable + (info->size - sizeof(int)) must somehow be a valid index for g_windows, which seems rather strange as addresses of local variables tend to be rather incidental.

    EDIT:
    Besides the problem of the address of the local variable being something that is beyond your control and hence unrelated to the range of valid indices for g_windows, I note that the conversion from uintptr_t to int may result in loss of information.
    Last edited by laserlight; 01-07-2020 at 06:48 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by Hodor View Post
    I don't understand. I've written heaps of code that uses Lua and never had to resort to something like the snippet I've quoted. Is this another example of abstraction?
    No, its a work around, glut doesn't provide the window id when calling the function so I've no choice but to copy the same function into allocated memory and set a variable allocated with it and pass that to glut*Func functions instead otherwise the lua handler can only handle setting a function for a single window which is not the same as the original

    Edit: Meant to add a valgrind output since I'm still struggling, this is what came out before I managed to close the app or it crashed, one of the two
    valgrind_output.log - Google Drive
    Last edited by awsdert; 01-07-2020 at 06:44 AM.

  8. #8
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by laserlight View Post
    Out of curiosity, but why are you using the address of a local variable to compute wid, which is then immediately used in the expression g_windows[wid]? This is with reference to:
    Code:
    int wid = ((uintptr_t)&wid) + (info->size - sizeof(int));
    For this to work correctly, the address of the local variable + (info->size - sizeof(int)) must somehow be a valid index for g_windows, which seems rather strange as addresses of local variables tend to be rather incidental.

    EDIT:
    Besides the problem of the address of the local variable being something that is beyond your control and hence unrelated to the range of valid indices for g_windows, I note that the conversion from uintptr_t to int may result in loss of information.
    I've just change that line to this because I realised I was definitely calculating too far:
    Code:
    int wid = ((uintptr_t)&info) + (info->size - sizeof(int));
    If I try as just "int wid;" and overwrite the variable during duplication then the compiler will just complain uninitialized variable usage during compile and if I set the value before compile how do I know the resulting function won't just override my override?

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by awsdert
    I've just change that line to this because I realised I was definitely calculating too far:
    You still have the same problem: info is a local variable, and you're taking the address of this local variable to compute an index into g_windows. You have no way of knowing beforehand if that computed index is valid. If you're unlucky -- and we should assume that you're unlucky -- you'll end up accessing g_windows out of bounds, which could cause a segfault.

    Quote Originally Posted by awsdert
    If I try as just "int wid;" and overwrite the variable during duplication then the compiler will just complain uninitialized variable usage during compile and if I set the value before compile how do I know the resulting function won't just override my override?
    Basically, you want wid to be a random index into g_windows?

    Since you don't seem to have included the definition of foo_cb_info_t in your code snippet, it may be helpful to explain what is info->size and why you're subtracting sizeof(int) from it.
    Last edited by laserlight; 01-07-2020 at 07:11 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by laserlight View Post
    You have no way of knowing beforehand if that computed index is valid
    ...
    Basically, you want wid to be a random index into g_windows?
    Not random, when I allocate the memory for the copy of these functions I also allocate memory for where these functions will access and fill the values there, the snippet with the change I made (in foo_need_window which I renamed to alloc_foo_window for quick find in symbols list):
    Code:
    	for ( i = 0; i < foo_cb_id_count; ++i ) {
    		info = &(foo_callbacks[i]);
    		window->foo_cb[i] = &mem[info->pos];
    		(void)memcpy(
    			&(mem[info->pos]),
    			info->cb,
    			info->size );
    		*((int*)&(mem[info->pos + info->size])) = w;
    	}
    Quote Originally Posted by laserlight View Post
    Since you don't seem to have included the definition of foo_cb_info_t in your code snippet, it may be helpful to explain what is info->size and why you're subtracting sizeof(int) from it.
    Wasn't relevant to the problem but I'll go ahead and give it since you want it
    Code:
    typedef struct foo_cb_info {
    	size_t pos;
    	size_t size;
    	char *name;
    	void *cb;
    } foo_cb_info_t;
    #define FOO_CB_INFO(NAME) {0,0,#NAME,(void*)NAME}
    ...
    int main( int argc, char *argv[] ) {
    	int w;
    	std_data data;
    	foo_cb_info_t callbacks[foo_cb_id_count] = {
    		FOO_CB_INFO(foo_cb_close),
    		FOO_CB_INFO(foo_cb_display),
    		FOO_CB_INFO(foo_cb_idle),
    		FOO_CB_INFO(foo_cb_keyboard),
    		FOO_CB_INFO(foo_cb_reshape),
    		FOO_CB_INFO(foo_cb_special),
    	};
    ...
    	memcpy( foo_callbacks, callbacks, sizeof(foo_cb_info_t) * foo_cb_id_count );
    	get_cb_sizes(argv[0]);
    And since you're bound to ask for it:
    Code:
    #if __INTPTR_WIDTH__ == 32
    #define ELF_T( NAME ) Elf32_##NAME
    #elif __INTPTR_WIDTH__ == 64
    #define ELF_T( NAME ) Elf64_##NAME
    #else
    #define ELF_T( NAME ) Elf_##NAME
    #endif
    void get_cb_sizes( char *name ) {
    #ifdef __ELF__
    	size_t prev = BUFSIZ, need = prev, info = 0, symtabi = 0,
    		symtabs_used = 0, strtabs_used = 0, strtabs_upto = 10;
    	std_data data = {0};
    	uchar *buff = NULL;
    	char *text;
    	if ( (errno = alloc_std_data( &data, need )) != EXIT_SUCCESS ) {
    		exit(errno);
    		return;
    	}
    	buff = data.data;
    	FILE *file = fopen(name,"r");
    	if ( !file ) {
    		(void)alloc_std_data(&data,0);
    		exit(errno);
    		return;
    	}
    	fread( buff, prev, 1, file );
    	ELF_T(Ehdr) *elf_header = (ELF_T(Ehdr) *)buff;
    	ELF_T(Shdr) *sec_headers = NULL, *sec_header = NULL;
    	ELF_T(Sym) *syms = NULL, *sym = NULL;
    	ELF_T(Half) sectioni, symi, sym_count = 0,
    		symtabs[10] = {0}, strtabs[10] = {0};
    	foo_cb_id_t foo_cb_id;
    	sec_headers = (ELF_T(Shdr)*)elf_header->e_shoff;
    	if ( elf_header->e_phoff > elf_header->e_shoff )
    		need = elf_header->e_phoff +
    			(elf_header->e_phnum * sizeof(ELF_T(Phdr)));
    	else
    		need = elf_header->e_shoff +
    			(elf_header->e_shnum * sizeof(ELF_T(Shdr)));
    	if ( elf_header->e_shstrndx + BUFSIZ > need )
    		need = elf_header->e_shstrndx + BUFSIZ;
    	if ( elf_header->e_entry > need )
    		need = elf_header->e_entry;
    	if ( need > prev ) {
    		if ( (errno = alloc_std_data( &data, need )) != EXIT_SUCCESS )
    			goto failed;
    		buff = data.data;
    		fseek( file, 0, SEEK_SET );
    		fread( buff, need, 1, file );
    		prev = need;
    		elf_header = (ELF_T(Ehdr)*)buff;
    		sec_headers = (ELF_T(Shdr)*)&(buff[elf_header->e_shoff]);
    	}
    	if ( sec_headers ) {
    		for (
    			sectioni = 0;
    			sectioni < elf_header->e_shnum;
    			++sectioni
    		)
    		{
    			sec_header = &(sec_headers[sectioni]);
    			if ( (sec_header->sh_type == SHT_STRTAB ||
    				sectioni == elf_header->e_shstrndx)
    				&& strtabs_used < strtabs_upto ) {
    				strtabs[strtabs_used++] = sectioni;
    				info = sec_header->sh_offset + sec_header->sh_size;
    				if ( info > need ) need = info;
    			}
    			if ( (sec_header->sh_type == SHT_SYMTAB
    				|| sec_header->sh_type == SHT_DYNSYM)
    				&& symtabs_used < strtabs_upto ) {
    				symtabs[symtabs_used++] = sectioni;
    				info = sec_header->sh_offset + sec_header->sh_size;
    				if ( info > need ) need = info;
    			}
    		}
    		if ( symtabs_used == 0 ) {
    			puts("Section '.symtab' missing!");
    			goto failed;
    		}
    		if ( need > prev ) {
    			if ( (errno = alloc_std_data( &data, need )) != EXIT_SUCCESS )
    				goto failed;
    			buff = data.data;
    			fseek( file, 0, SEEK_SET );
    			fread( buff, need, 1, file );
    			prev = need;
    			elf_header = (ELF_T(Ehdr)*)buff;
    			sec_headers = (ELF_T(Shdr)*)&(buff[elf_header->e_shoff]);
    		}
    	}
    	if ( symtabs_used ) {
    		for ( symtabi = 0; symtabi < symtabs_used; ++symtabi )
    		{
    			printf("Entering symbol list %zu...\n", symtabi );
    			sec_header = &(sec_headers[symtabs[symtabi]]);
    			syms = (ELF_T(Sym)*)&(buff[sec_header->sh_offset]);
    			sym_count = sec_header->sh_size / sizeof(ELF_T(Sym));
    			sec_header = &(sec_headers[sec_header->sh_link]);
    			text = (char*)&(buff[sec_header->sh_offset]);
    			for ( symi = 0; symi < sym_count; ++symi )
    			{
    				sym = &(syms[symi]);
    				name = &(text[sym->st_name]);
    				//printf("Checking symbol %u '%s'...\n", symi, name );
    				for (
    					foo_cb_id = 0;
    					foo_cb_id < foo_cb_id_count;
    					++foo_cb_id
    				)
    				{
    					if ( strcmp(name,foo_callbacks[foo_cb_id].name) ==0) {
    						foo_callbacks[foo_cb_id].size = sym->st_size;
    					}
    				}
    			}
    		}
    	}
    	data.data = buff;
    	data.size = prev;
    	(void)alloc_std_data(&data,0);
    	if ( file ) fclose(file);
    	return;
    	failed:
    	data.data = buff;
    	data.size = prev;
    	(void)alloc_std_data(&data,0);
    	if ( file ) fclose(file);
    	exit(errno);
    #else
    	puts("Must be compiled as an elf!");
    	exit(EXIT_FAILURE);
    #endif
    }
    Last edited by awsdert; 01-07-2020 at 10:02 AM. Reason: Closed quote incorrectly as I'm in the habit of closing code statements

  11. #11
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Occured to me that maybe the functions didn't actually exist yet when I attempted to copy them (tried adding a printf statement to see wid only to find it never gets reaches it before the segfault) so I tried to copy from the addresses given by sym->st_value (which segfaulted) then tried creating a buffer (which is currently a leak but no biggie for now) and that crashed the app saying invalid size, when I looked at the value in the debugger it seemed valid but was an odd number so I added to the size before allocation to make it a multiple of sizeof(long) which still crashed, here's the snippet of code using it and the function it relies on:
    Code:
    int alloc_std_data( std_data *data, long want ) {
    	void *temp;
    	if ( !data )
    		return EDESTADDRREQ;
    	if ( want <= 0 ) {
    		if ( data->data ) free( data->data );
    		data->data = NULL;
    		data->size = 0;
    		return EXIT_SUCCESS;
    	}
    	want += sizeof(long) - (want % sizeof(long));
    	if ( data->data ) temp = realloc( data->data, want );
    	else temp = malloc( want );
    	if ( !temp )
    		return (errno == EXIT_SUCCESS) ? EXIT_FAILURE : errno;
    	if ( data->size < want )
    		(void)memset( &(((uchar*)temp)[data->size]),
    		0, want - data->size );
    	data->data = temp;
    	data->size = want;
    	return EXIT_SUCCESS;
    }
    ...
    				for (
    					foo_cb_id = 0;
    					foo_cb_id < foo_cb_id_count;
    					++foo_cb_id
    				)
    				{
    					if ( strcmp(name,foo_callbacks[foo_cb_id].name) ==0) {
    						foo_callbacks[foo_cb_id].cb = (void*)need;
    						need += foo_callbacks[foo_cb_id].size = sym->st_size;
    						if ( (errno = alloc_std_data( &foo_cb_copies, need )) != EXIT_SUCCESS ) {
    							exit(errno);
    							return;
    						}
    						
    						fseek( file, sym->st_value, SEEK_SET );
    						fread( &(((uchar*)(foo_cb_copies.data))[need]),
    							sym->st_size, 1, file );
    					}
    				}
    			}
    		}
    	}
    	for (
    		foo_cb_id = 0;
    		foo_cb_id < foo_cb_id_count;
    		++foo_cb_id
    	)
    	{
    		foo_callbacks[foo_cb_id].cb =
    			&(((uchar*)(foo_cb_copies.data))
    			[(uintptr_t)(foo_callbacks[foo_cb_id].cb)]);
    	}
    It crashes when it gets to realloc but doesn't do that when lua calls it, the final value attempt was 632
    Last edited by awsdert; 01-07-2020 at 11:07 AM. Reason: typo and missed tabs

  12. #12
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Gave up using standard allocation for that function, switch it to my own function, still get the segfault when glut attempts to redraw the window however

  13. #13
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    PROGRESS!
    I added this line to the setup loop:
    Code:
    *((uchar*)&(mem[(info->pos + info->size)-1])) = 0xC3;
    And no more segfault, however got this instead:
    Code:
    Error: foo_atexit() 0x0000000B Resource temporarily unavailable
    Edit: Turns out reading from the file got me now-where in regards the execution bytes, was somehow 0 every time, went back to using the pointers given by the compiler and that got me executable bytes, currently attempting to override the return statement with an add instruction and put a new return instruction after instead in an attempt to stop the segfault
    Last edited by awsdert; 01-07-2020 at 01:01 PM.

  14. #14
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Can't seem to quell this bug, does anyone have any experience with appending data to compiled functions?

    Edit: Managed to print the end bytes of the callbacks before and after they are modified, maybe someone can understand the result better than I can:
    Code:
    E8 67 D9 FF FF 00 00 00 00 00 00 00
    E8 67 D9 FF FF 81 07 00 00 00 00 C3
    E8 A8 D7 FF FF 00 00 00 00 00 00 00
    E8 A8 D7 FF FF 81 07 00 00 00 00 C3
    E8 00 D6 FF FF 00 00 00 00 00 00 00
    E8 00 D6 FF FF 81 07 00 00 00 00 C3
    E8 01 D4 FF FF 00 00 00 00 00 00 00
    E8 01 D4 FF FF 81 07 00 00 00 00 C3
    E8 5A D2 FF FF 00 00 00 00 00 00 00
    E8 5A D2 FF FF 81 07 00 00 00 00 C3
    E8 74 D0 FF FF 00 00 00 00 00 00 00
    E8 74 D0 FF FF 81 07 00 00 00 00 C3
    Decided a compare was safer instruction to add there and appending a return should've been fine but still segfaulting, I guess that one earlier only stopped segfaulting because of the 0'd out block
    Last edited by awsdert; 01-07-2020 at 03:11 PM.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    By the way, it would be more readable if instead of casting, accessing by index and then taking the address like this:
    Code:
    (void)memset( &(((uchar*)temp)[data->size]),
        0, want - data->size );
    or this:
    Code:
    fread( &(((uchar*)(foo_cb_copies.data))[need]),
        sym->st_size, 1, file );
    You just cast then use pointer arithmetic like this:
    Code:
    (void)memset( (uchar*)temp + data->size, 0, want - data->size );
    or this:
    Code:
    fread( (uchar*)foo_cb_copies.data + need, sym->st_size, 1, file );
    On a related style note, since you're not using the return value of fread, why don't you cast it to void to be consistent? The purpose of casting return values to void is to indicate that they are deliberately unused; if you cast some but not others, then it stands to reason that when you fail to cast and yet the return value is unused, it is indicative of a potential bug because you accidentally forgot to check the return value. So, either always cast deliberately unused return values to void, or don't cast them at all and just ignore them.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem retrieving information from a file line by line.
    By inu11byte in forum C Programming
    Replies: 5
    Last Post: 11-12-2012, 04:31 PM
  2. Retrieving information from the internet
    By frshca in forum C Programming
    Replies: 1
    Last Post: 01-09-2010, 06:01 PM
  3. Function template specialization and duplicate symbols
    By krappa in forum C++ Programming
    Replies: 7
    Last Post: 07-29-2009, 11:53 AM
  4. Retrieving a varible from a different function
    By lilrayray in forum C++ Programming
    Replies: 17
    Last Post: 08-24-2006, 04:05 PM
  5. String duplicate function - small problem
    By larry in forum C++ Programming
    Replies: 8
    Last Post: 09-29-2001, 01:55 PM

Tags for this Thread