避免 libgmp 中的中止
我有一些使用 libgmp 的代码。在某些时候,用户可能会请求一个非常大的数字的阶乘。不幸的是,这会导致 libgmp 发出中止信号。
例如下面的代码:
#include <cmath>
#include <gmp.h>
#include <iostream>
int main() {
mpz_t result;
mpz_init(result);
mpz_fac_ui(result, 20922789888000);
std::cout << mpz_get_si(result) << std::endl;
}
结果:
$ ./test
gmp: overflow in mpz type
Aborted
显然,产生的数字非常大。无论如何,有没有比中止更优雅地处理错误的方法。这是一个基于 GUI 的应用程序,它的中止几乎是处理此类问题的最不理想的方式。
I have some code that uses libgmp. At some point the user may request a factorial of a very large number. Unfortunately, this results in libgmp raising an abort signal.
For example the following code:
#include <cmath>
#include <gmp.h>
#include <iostream>
int main() {
mpz_t result;
mpz_init(result);
mpz_fac_ui(result, 20922789888000);
std::cout << mpz_get_si(result) << std::endl;
}
Results in:
$ ./test
gmp: overflow in mpz type
Aborted
Apparently, the number produced is REALLY big. Is there anyway to handle the error more gracefully than an abort. This is a GUI based application and it aborting is pretty much the least desirable way to handle this sort of issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
根据 mpz/realloc.c 和 mpz/realloc2 .c。如果请求了太多内存,它只会执行以下操作:
It would appear that you are out of luck, based on the code in mpz/realloc.c and mpz/realloc2.c. If too much memory was requested, it just does this:
在应用程序中优雅地处理这些错误的最佳方法可能是分叉一个辅助进程来执行 GMP 计算。如果帮助程序进程被
SIGABRT
终止,您的父进程可以检测到并向用户报告错误。(下面是我的原始答案,根据 GMP 文档,它具有“未定义的结果” - 为了完整起见,将其留在这里)。
如果您为
安装信号处理程序,则可以捕获该错误使用
:longjmp()
的 SIGABRTThe best way to handle these errors gracefully in your application is probably to fork off a helper process to perform the GMP calculations. If the helper process is killed by
SIGABRT
, your parent process can detect that and report an error to the user.(The below is my original answer, which has "undefined results" according to the GMP documentation - it is left here for completeness).
You can catch the error if you install a signal handler for
SIGABRT
that useslongjmp()
:用
LD_PRELOAD
覆盖abort()
。LD_PRELOAD 技巧是什么?
编辑:为了使答案更加独立,我在此处复制该答案的文本:
感谢 JesperE。
Overwrite
abort()
withLD_PRELOAD
.What is the LD_PRELOAD trick?
Edit: To make the answer more self-contained, I copy the text of that answer here:
Credits to JesperE.