I'm learning assembler (FASM) and I have weird problem, whenever i want to call gtk_main_quit() it always ends with "segmentation fault".
Why call gtk_main_quit causes segmentation fault?
format ELF
extrn gtk_init
extrn gtk_main
extrn gtk_main_quit
extrn gtk_window_new
extrn gtk_widget_show
extrn g_signal_connect_data
public main
on_window_close:
call gtk_main_quit ; <- segmentation fault
ret
main:
push 0
push 0
call gtk_init
add esp, 8
push 0
call gtk_window_new
add esp, 4
mov [window_handle], eax
push 0
push 0
push 0
push on_window_close
push on_close_signal
push [window_handle]
call g_signal_connect_data
add esp, 24
push [window_handle]
call gtk_widget_show
add esp, 8
call gtk_main
window_handle dd 0
on_close_signal db 'destroy', 0
all:
~/apps/fasm/fasm ./test.asm
gcc -o test test.o `pkg-config --cflags --libs gtk+-3.0`
When making function calls always ensure that you restore the stack properly after a call. Your code does this:
push [window_handle]
call gtk_widget_show
add esp, 8
You push one DWORD onto the stack as a parameter which is correct, but after your call to gtk_widget_show
you add 8 to ESP. Since you only pushed 4 bytes on the stack, this restores ESP improperly. A side effect will be that the return address of the function main
will now be in the wrong place which would likely yield a segmentation fault when your main
function returns. The code should have been:
push [window_handle]
call gtk_widget_show
add esp, 4
That brings up the second issue. Your code:
call gtk_main
window_handle dd 0
on_close_signal db 'destroy', 0
After gtk_main
returns it will start executing whatever instructions appear in memory after. In this case it happens to be some variables and whatever else is in memory. Since the C runtime called your function main
like any other function, you should use ret
to return back to the C runtime and let it shutdown your program cleanly.
The code would look like:
call gtk_main
ret
window_handle dd 0
on_close_signal db 'destroy', 0