【问题标题】:Call to gtk_main_quit causes "segmentation fault" in assembler code调用 gtk_main_quit 导致汇编代码中出现“分段错误”
【发布时间】:2016-03-26 12:01:58
【问题描述】:

我正在学习汇编程序 (FASM),但遇到了奇怪的问题,每当我想调用 gtk_main_quit() 时,它总是以“分段错误”结束。

为什么调用 gtk_main_quit 会导致分段错误?

test.asm

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`

【问题讨论】:

  • @MichaelPetch 哈哈,它有帮助,谢谢:D

标签: assembly x86 segmentation-fault gtk gtk3


【解决方案1】:

在进行函数调用时,请始终确保在调用后正确恢复堆栈。您的代码执行此操作:

push [window_handle]
call gtk_widget_show
add esp, 8

您将一个 DWORD 作为正确的参数压入堆栈,但在调用 gtk_widget_show 之后,您将 8 添加到 ESP。由于您只在堆栈上压入了 4 个字节,因此这会不正确地恢复 ESP。一个副作用是函数main 的返回地址现在将位于错误的位置,这可能会在您的main 函数返回时产生分段错误。代码应该是:

push [window_handle]
call gtk_widget_show
add esp, 4

这就引出了第二个问题。你的代码:

    call gtk_main

window_handle dd 0
on_close_signal db 'destroy', 0

gtk_main 返回后,它将开始执行内存中出现的任何指令。在这种情况下,它恰好是一些变量以及内存中的任何其他内容。由于C 运行时调用你的函数main 就像任何其他函数一样,你应该使用ret 返回到C 运行时并让它干净地关闭你的程序。

代码如下:

    call gtk_main
    ret

window_handle dd 0
on_close_signal db 'destroy', 0

【讨论】:

  • @BPS: 而不是call / ret,你应该tailcall优化到jmp gtk_main
【解决方案2】:

gtk_main_quit 的调用导致gtk_main 返回,在调用执行窗口句柄之后继续执行,可能还有文本“destroy”。很难准确预测会发生什么。

call gtk_main 之后添加ret

【讨论】:

  • 好点,但是在“call gtk_main”之后添加“ret”后,仍然存在分段错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 2022-01-04
相关资源
最近更新 更多