Я экспериментировал с ассемблером и библиотеками GTK + 3, когда обнаружил, что мое приложение превращается в зомби, если я не связываю объектный файл с gcc
против стандартной библиотеки. Вот мой код stdlib
применения свободном отПочему я получаю зомби, когда я связываю код сборки без stdlib?
%include "gtk.inc"
%include "glib.inc"
global _start
SECTION .data
destroy db "destroy", 0 ; const gchar*
strWindow db "Window", 0 ; const gchar*
SECTION .bss
window resq 1 ; GtkWindow *
SECTION .text
_start:
; gtk_init (&argc, &argv);
xor rdi, rdi
xor rsi, rsi
call gtk_init
; window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
xor rdi, rdi
call gtk_window_new
mov [window], rax
; gtk_window_set_title (GTK_WINDOW (window), "Window");
mov rdi, rax
mov rsi, strWindow
call gtk_window_set_title
; g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
mov rdi, [window]
mov rsi, destroy
mov rdx, gtk_main_quit
xor rcx, rcx
xor r8, r8
xor r9, r9
call g_signal_connect_data
; gtk_widget_show (window);
mov rdi, [window]
call gtk_widget_show
; gtk_main();
call gtk_main
mov rax, 60 ; SYS_EXIT
xor rdi, rdi
syscall
А вот тот же код предназначен для слинкованы стандартной библиотеки
%include "gtk.inc"
%include "glib.inc"
global main
SECTION .data
destroy db "destroy", 0 ; const gchar*
strWindow db "Window", 0 ; const gchar*
SECTION .bss
window resq 1 ; GtkWindow *
SECTION .text
main:
push rbp
mov rbp, rsp
; gtk_init (&argc, &argv);
xor rdi, rdi
xor rsi, rsi
call gtk_init
; window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
xor rdi, rdi
call gtk_window_new
mov [window], rax
; gtk_window_set_title (GTK_WINDOW (window), "Window");
mov rdi, rax
mov rsi, strWindow
call gtk_window_set_title
; g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
mov rdi, [window]
mov rsi, destroy
mov rdx, gtk_main_quit
xor rcx, rcx
xor r8, r8
xor r9, r9
call g_signal_connect_data
; gtk_widget_show (window);
mov rdi, [window]
call gtk_widget_show
; gtk_main();
call gtk_main
pop rbp
ret
Оба приложения создают GtkWindow
. Однако, когда окно закрыто, они ведут себя по-другому. Первый приводит к процессу зомби, и мне нужно нажать Ctrl+C
. Последний показывает ожидаемое поведение, то есть приложение прекращается, как только окно закрывается.
Я чувствую, что стандартная библиотека выполняет некоторые важные операции, которые я игнорирую в первом примере кода, но я не могу сказать, что это такое.
Так что мой вопрос: что отсутствует в первом примере кода?
'mov rax, 60; SYS_EXIT xor rdi, rdi Syscall' замыкает цепь на нормальную процедуру выключения. Поскольку вы не показываете, как вы собираете/связываете, и это не является минимальным проверяемым примером (заголовки, которые вы используете, не являются частью вопроса), сказать сложно. Одна из возможностей заключается в том, что нужно вызвать библиотеку '' '' ''. –
Даже без вызова sys_exit я все еще получаю зомби. Файлы, включенные в%, тривиальны для генерации: они просто включают объявления extern для внешних символов. Я использовал «nasm -f elf64 ...» и «ld -I/path/to/interpreter» pkg-config -libs gtk + -3.0' ... ». Я подозреваю, что мне нужно назвать что-то еще, что, вероятно, является своего рода очисткой процесса, выполненной с помощью C. Однако я не уверен, что это за чистка. Я попытался включить вызов sys_wait4 с -1 как pid, но даже с этим я все равно получаю зомби. – Phoenix87
Если вы просто удалите 'mov rax, 60; SYS_EXIT xor rdi, rdi syscall', который не сработает, потому что тогда ваша программа, скорее всего, будет проходить случайную память. Функция «exit» в _C_ library, о которой я упоминал, обычно выполняет очистку, которая может потребоваться (что может отличать ваши программы отдельно), чтобы GTK нормально закрывался (на мой взгляд, также будет выполняться очистка, связанная с потоком). 'gtk.inc', а другой inc может быть тривиальным для генерации, но если вы хотите, чтобы кто-то серьезно воспринял это (или попробовал ваш код), вы можете их предоставить. Без них это не является минимальным полным проверяемым примером. –