有什么方法可以捕获在CGO代码中触发的致命错误?

我们的应用程序正在使用 odbc 驱动程序来访问Impala数据库。 我们发现,在某些难以复制的情况下,驱动程序将在其cgo代码内触发一个段错误,一旦它通过驱动程序传播并传播到我们的代码,则该错误将显示为致命错误。 由于我们希望在这种情况下进行一些清理和警报,因此我实现了一个延迟的紧急捕获器,希望它可以捕获它们。</ p>

但是,它不起作用。 致命错误一直持续到包含 recover()</ code>调用的延迟函数之后(尽管打印输出看起来很相似,所以显然这不是惊慌),尽管它确实捕获了 other </ em> 恐慌。 一个github问题提示无法捕获cgo信号,并且应用程序应立即正常运行 如果发生崩溃。 对于我们的生产应用程序来说,这是一个无法接受的崩溃案例,所以我想知道这在过去6年中是否有所变化,或者是否有人知道在cgo信号发生时运行清除代码的另一种方式。 似乎根本无法捕获并处理这些致命错误,这是极其糟糕的设计。</ p>
</ div>

展开原文

原文

Our applications are using the odbc driver to access an Impala database. We've discovered that in certain difficult-to-replicate situations, the driver will trigger a segfault within its cgo code, which manifests as a fatal error once it propagates back up through the driver and to our code. Since we want some cleanup and alerting to happen in these situations, I implemented a deferred panic catcher, hoping this might catch them.

However, it isn't working. The fatal error continues straight past the deferred function containing the recover() call (so apparently it's not a panic, despite the print output looking similar), though it does catch other panics. A github issue suggests that cgo signals cannot be caught, and that applications should gracelessly and immediately crash if one occurs. This is an unacceptable crash case for our production applications, so I'm wondering if that's changed in the last 6 years, or if anyone knows of another way of running some cleanup code in the event of a cgo signal. It seems like extremely poor design to have no way at all catch and handle these fatal errors.

cgo
dongxifu5009
dongxifu5009 那甚至有能力赶上SIGSEGV吗?老实说,我从未尝试过。
2 年多之前 回复
doujia1939
doujia1939 您还没有尝试过os.signal.Notify的机会
2 年多之前 回复
dro7152
dro7152 我可以邀请您在Go邮件列表中提出您的问题吗?尽管此SO标签由相当多的专业人员监控,但Go开发人员不会阅读。我还要指出,如果/当您决定在此处发布时,请在其中包含Go版本和您使用的操作系统-这对于正确处理问题可能至关重要。
2 年多之前 回复
doucheng9634
doucheng9634 是的,我想。我只是讨厌生产代码中有如此严重的崩溃漏洞,而替代方案却令人讨厌。谢谢您的帮助。
2 年多之前 回复
doulian1852
doulian1852 除了Go确实具有无法捕获的致命错误的概念外,您已经看到了。段错误或内存损坏(通过不正确使用不安全或竞争条件),OOM,并发写入映射等都可能导致致命错误。Go固有的内存安全性比C语言更难实现。
2 年多之前 回复
doutang6600
doutang6600 我已经好几年没有用C编码了,所以不知道,TBH。我喜欢Go的一个重要原因是它实际上并没有可捕捉的致命错误的概念。如果只是扁平状而无法捕获,我想我可能不得不看我是否无法调试cgo代码(ugh),或者查找/编写替代驱动程序。
2 年多之前 回复
duanshan1856
duanshan1856 “似乎根本无法捕获并处理这些致命错误,这似乎是非常糟糕的设计。”–通常如何在普通C代码中捕获SIGSEGV信号(未用Go运行时包装)?
2 年多之前 回复
douji8017
douji8017 不,致命错误是程序立即崩溃。cgo代码在相同的地址空间中运行,因此从技术上讲,Go内存空间也可能处于同样的状态。为了赶上它,您将不得不在另一个过程中运行它。
2 年多之前 回复
duanci6484
duanci6484 是的,您是对的,它显示为致命错误,只是与紧急情况具有相同的堆栈跟踪格式。有什么办法可以捕捉到这样的致命错误?我的意思是,我意识到致命错误肯定意味着我们无法继续执行cgo代码中的任何内容,因为它处于未定义状态,但是我至少希望能够在go代码中进行一些清除/更改只是优雅地崩溃。不得不进行心跳检查或诸如此类的事情似乎太多了。
2 年多之前 回复
duanfen2349
duanfen2349 您确定这是“紧急情况”,而不是运行时致命错误吗?
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐