표준 라이브러리에 대해 gcc
과 오브젝트 파일을 연결하지 않으면 응용 프로그램이 좀비가된다는 것을 발견했을 때 어셈블리 코드와 GTK + 3 라이브러리를 실험하고있었습니다. 여기에 표준 라이브러리stdlib없이 어셈블리 코드를 링크 할 때 왜 좀비가 생깁니 까?
%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
을 만들에 링크하기위한 것 같은 코드가 여기에있는 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
내 코드와. 그러나 두 창은 창을 닫을 때 다르게 동작합니다. 전자는 좀비 프로세스로 연결되며 Ctrl+C
을 눌러야합니다. 후자는 예상되는 동작을 나타내며, 즉, 윈도우가 닫히 자마자 애플리케이션이 종료된다.
표준 lib가 첫 번째 코드 샘플에서 간과하고있는 몇 가지 필수 작업을 수행하고 있지만 제 생각에는 그 것이 무엇인지 알 수 없습니다.
제 질문은 : 첫 번째 코드 샘플에 무엇이 누락 되었습니까?
: 빌드
: 그것을 자신을 시도하려는 사람들을 위해,이 변화는
gtk.inc
A에 대한 찾고 이동하려면 당신이 필요없이 구축 할 수 있습니다 'mov rax, 60; SYS_EXIT xor rdi, rdi syscall' 정상적인 종료 절차를 단락시킵니다. 당신이 조립하는 법/링크를 보여주지 않았기 때문에 이것은 최소한의 입증 가능한 예제는 아닙니다 (사용하는 헤더는 질문의 일부가 아닙니다). 말하기 어렵습니다. 한 가지 가능성은 _C_ 라이브러리'exit'가 호출되어야한다는 것입니다. –sys_exit을 호출하지 않아도 나는 여전히 좀비로 끝납니다. 포함 된 % 파일은 생성하기 쉽지만 외부 기호에 대한 extern 선언 만 포함합니다. 나는 "nasm -f elf64 ..."와 "ld -I/path/to/interpreter'pkg-config --libs gtk + -3.0' ..."을 사용했다. 나는 다른 것을 호출 할 필요가 있다고 생각하는데 아마도 C의 종료에 의해 수행 된 일종의 프로세스 정리 일 것이다. 그러나 나는이 정리가 무엇인지 잘 모릅니다. 나는 -1과 함께 sys_wait4 호출을 pid로 포함 시키려고했지만, 심지어는 여전히 좀비를 얻는다. – Phoenix87
'mov rax, 60;을 제거하면, SYS_EXIT xor rdi, rdi syscall'은 프로그램이 임의의 메모리를 걸러 낼 가능성이 있기 때문에 작동하지 않을 것입니다. 내가 언급 한 _C_ 라이브러리'exit' 함수는 보통 (GTK가 제대로 종료 될 수 있도록) 프로그램을 따로 설정할 필요가있는 클린업을 수행합니다 (리콜 할 때 일부 스레드 관련 정리를 수행합니다). 'gtk.inc'와 다른 inc는 생성하기가 쉽지 않지만 누군가가 이것을 심각하게 받아들이 길 원한다면 (또는 여러분의 코드를 시도해보십시오) 여러분은 그것을 제공하기를 원할 수 있습니다. 그들 없이는 이것은 최소한의 완전한 검증 가능한 예가 아닙니다. –