如何捕获“致命信号11(SIGSEGV)”?

4
在我的安卓OpenGL ES项目中,最近在着色器代码中出现了一个错误,这显然导致OpenGL线程中的“致命信号11(SIGSEGV)”:
GLES32.glCompileShader(glShaderHandle);

我已经解决了错误,现在它可以正常工作了,但是我花了很长时间才找出这个错误来自哪里。当然,我试图像这样捕捉shader错误:

GLES32.glGetShaderiv(glShaderHandle, GLES32.GL_COMPILE_STATUS, result, 0);

然而,在出现SIGSEGV错误的情况下,Java代码甚至没有到达那个点。尝试使用try/catch捕获错误也没有起作用。无论如何,应用程序仍然崩溃。我猜这个错误发生在本地c代码中。

有没有一种方法可以从Java代码处理此类错误,以防止应用程序崩溃?

1个回答

7

你无法捕获它。这是一个segfault,是C中的崩溃。它不会转化为Java堆栈跟踪,而是被Linux视为硬错误,并立即终止应用程序。

你可能能够编写C信号处理程序并进行一些处理,但我真的不建议这样做。你也无法从此时继续应用程序,因为应用程序现在处于未定义状态。

如果你确实想尝试(我真的不建议),请阅读如何编写信号处理程序以捕获SIGSEGV?了解相关问题的概述。


这个程序是否出现了段错误并且生成了核心转储文件?能否分析核心文件以确定错误发生的位置,获取类似于Java堆栈跟踪的信息? - markspace
通常情况下,您可以在logcat中的该行正下方获得部分转储。 - Gabe Sechan
但我真的不建议这样做。为了调试目的,似乎没问题,但为什么不呢? - Some Name
@SomeName 因为这很困难,让它在不同的Linux版本中运行良好更加困难,而且当你处于这种状态时实际上无法做太多事情——应用程序不能安全地继续运行和假设正常工作。你知道至少有一个无效指针,如果不是整个内存损坏。你正在赌博,赌什么都在内存中,包括应用程序代码本身,仍然有效。而且做错了会禁用已经存在的堆栈转储。 - Gabe Sechan
好的。无论如何,我的手机上的OpenGLES实现似乎存在一个错误。当着色器代码中有错误时,不应该出现分段错误,而是应该通过GL_COMPILE_STATUS读取消息。我将研究信号处理程序以便学习,但我不会在应用程序中实现它。 - theCNG27

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接