我正在通过 Wine 运行 Windows 程序(即wine example.exe
)。该程序(或者更可能是 Wine)有一个有趣的行为,当我关闭应用程序时,它没有完全退出,而是抛出一个读取访问异常;我的终端显示:
wine: Unhandled page fault on read access to 0x00000018 at address 0x7f7969ea (thread 0009), starting debugger...
结果,程序无法完全退出,我必须在终端中按 Control-C 或kill -9
它来关闭程序。
问题:有没有办法让 wine 进程在出现未处理的页面错误时退出,而不是像终端输出所示那样启动调试器? (顺便说一句:调试器实际上并没有启动;随后有一条消息抱怨启动 wine 调试器时出错。)
答案1
执行此操作的规范方法是创建 HKEY_LOCAL_MACHINE\Software\Wine\winedbg 项并将 DWORD 值 ShowCrashDialog 设置为 0。
答案2
此 python 脚本实现了 @chzzh 在评论中建议的解决方法。基本上,它读取wine进程的stderr,并在找到指定的字符串时强制终止它,例如,当它starting debugger...
在stderr中找到该字符串时。
使用方法如下:将下面的脚本另存为watcher.py
(任何名称都可以)。然后
python3 ./watcher.py 'starting debugger...' wine <arguments and exe path for wine>
我已经测试过这个并且它对我来说效果很好。
这是脚本:
#!/bin/python3
import sys
import io
import select
from subprocess import Popen, PIPE, DEVNULL, STDOUT
from sys import argv
def kill_when_found(process, needle, size = io.DEFAULT_BUFFER_SIZE):
if isinstance(needle, str):
needle = needle.encode()
assert isinstance(needle, bytes)
stream = process.stderr
assert stream is not None
poll = select.poll()
poll.register(stream, select.POLLIN)
output_buffer = b''
while process.poll() is None:
result = poll.poll(100)
if not result:
continue
output = stream.read1(size)
sys.stdout.buffer.write(output)
output_buffer += output
if needle in output_buffer:
process.kill()
return process.poll()
if len(output_buffer) >= len(needle):
output_buffer = output_buffer[-len(needle):]
return process.poll()
if __name__ == '__main__':
if len(argv) <= 3:
print("""
Usage: Pass in at least 2 arguments, the first argument is the search
string;
the remaining arguments form the command to be executed (and watched over).
""")
sys.exit(0)
else:
process = Popen(argv[2:], stderr = PIPE)
retcode = kill_when_found(process, argv[1])
sys.exit(retcode)