标签: longjmp

C++:安全使用longjmp和setjmp?

关于以下内容在linux/gcc上使用C++中的longjmp和setjmp是否安全?

  1. 异常处理(我没有使用longjmp/setjmp实现异常处理.我想知道longjmp/setjmp对标准异常处理会产生什么副作用)
  2. *this 指针
  3. 信号
  4. 智能指针(boost的共享和侵入指针)
  5. 你能想到的任何其他东西.

c++ linux gcc exception longjmp

39
推荐指数
2
解决办法
1万
查看次数

OCaml内部:例外

我很想知道如何在OCaml运行时处理异常以使它们如此轻量级.他们使用setjmp/longjmp还是在每个函数中返回一个特殊值,然后传播它?

在我看来,longjmp会给系统带来一点压力,但只有当引发异常时,检查每个函数的返回值才需要在调用函数后检查每个值和每个值,这在我看来会很多检查和跳跃,似乎表现最差.

通过查看OCaml如何与C接口(http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html#toc142),并查看callback.h,似乎通过使用标记异常对象的内存对齐(#define Is_exception_result(v)(((v)&3)== 2)).这似乎表明它的实现不使用longjmp并在每次函数调用后检查每个函数结果.是吗?或者C函数已经尝试捕获任何异常,然后将其转换为这种格式?

谢谢!

compiler-construction ocaml exception internals longjmp

21
推荐指数
1
解决办法
1952
查看次数

使用longjmp/setjmp进行C错误处理有哪些"好"的方法?

我必须将C用于一个项目,我正在考虑使用longjmp/setjmp错误处理,因为我认为在一个中心位置处理错误要比返回代码容易得多.如果有一些关于如何做到这一点的线索,我将不胜感激.

如果发生任何此类错误,我特别关注正确完成资源清理.

另外,我如何处理导致多线程程序使用它们的错误?

更好的是,是否有一些C库已经存在以进行错误/异常处理?

c error-handling longjmp setjmp

20
推荐指数
4
解决办法
9926
查看次数

如何在Rcpp中安全地生成R警告

我们知道Rf_error()在Rcpp中应该避免调用,因为它涉及堆栈上的C++析构函数的longjmp.这就是为什么我们宁愿在Rcpp代码中抛出C++异常(喜欢throw Rcpp::exception("...")或通过stop("...")函数).

但是,R警告也可能导致调用Rf_error()(此行为取决于warn选项).所以,打电话Rf_warning()也是有风险的.

Rcpp::sourceCpp(code = '

   #include <Rcpp.h>
   using namespace Rcpp;

   class Test {
      public:
         Test() { Rcout << "start\\n"; }
         ~Test() { Rcout << "end\\n"; }
   };

   // [[Rcpp::export]]
   void test() {
      Test t;
      Rf_warning("test");
   }
')

options(warn=10)
test()
## start
## Error in test() : (converted from warning) test
Run Code Online (Sandbox Code Playgroud)

我们看到析构函数没有被调用(没有"结束"消息).

如何用C++生成R警告 - 对析构函数友好的方式?

warnings r longjmp rcpp

18
推荐指数
2
解决办法
2480
查看次数

使用setjmp,longjmp进行多任务处理

有没有办法实现多任务使用setjmplongjmp功能

longjmp

17
推荐指数
3
解决办法
6732
查看次数

这些破坏性变量警告有何意义?

我有这样的功能:

#include <setjmp.h>
jmp_buf buf;
void func2(int g);
extern int some_global;
void func(int x)
{
    if (setjmp(buf))
        return;
    if (some_global)
        x += 5;
    func2(x);
}
Run Code Online (Sandbox Code Playgroud)

GCC(gcc(Debian 4.4.5-8)4.4.5)发出警告:

test.c: In function ‘func’:
test.c:5: warning: argument ‘x’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]

为什么????我的意思是,显然我不在乎是否x被破坏,因为它不可能在setjmp返回后使用.即使编译器应该知道一些非常明显的东西,因为它具有某种特殊的知识setjmp.

我的主要兴趣是找到我继承的代码库中的错误,因此,"使用这种编码风格"并不是我正在寻找的建议.然而,这里有许多奇怪的曲折.例如,如果x是局部变量而不是参数,那么GCC不会抱怨.此外,GCC不会在没有if (some_global)线的情况下抱怨.尼斯.有些事情搞砸了GCC的流量分析,或者GCC知道我不知道的事情.

所以,

  • 是否有一种简单的方法来抑制此函数的此警告,就像您可以将未使用的参数转换为(void)

  • 或者我只是在项目范围内禁止警告?

  • 或者我错过了什么?

更新:让我与您分享一个不会产生警告的略有不同的版本:

#include <setjmp.h>
jmp_buf buf;
void func2(int g);
extern int some_global;
void func(int …
Run Code Online (Sandbox Code Playgroud)

c gcc warnings longjmp

17
推荐指数
2
解决办法
6137
查看次数

Longjmp退出信号处理程序?

从问题:

在C中使用setjmp和longjmp是不错的编程习惯?

其中两条评论说:

"你不能在信号处理程序中抛出异常,但你可以安全地做一个longjmp - 只要你知道你在做什么. - Dietrich Epp 8月31日19:57 @Dietrich:+1你的评论.这是一个鲜为人知且完全不被重视的事实.在不使用信号处理程序的longjmp的情况下,有许多问题无法解决(令人讨厌的竞争条件).阻塞系统调用的异步中断是典型的例子."

我的印象是内核在遇到异常情况时调用信号处理程序(例如除以0).此外,如果您专门注册它们,它们只会被调用.

这似乎意味着(对我来说)它们不会通过您的正常代码调用.

继续这个想法...我理解的是setjmp和longjmp用于将堆栈折叠到先前的点和状态.我不明白在调用信号处理程序时如何折叠堆栈,因为它从内核调用作为一次性环境而不是从您自己的代码调用.从信号处理程序到堆栈的下一个东西是什么!?

c unix signals longjmp

16
推荐指数
2
解决办法
6224
查看次数

longjmp解除的C/C++实现?

是否有主要的C/C++实现,其中longjmp函数"展开",即它与自动存储对象的析构函数__attribute__((__cleanup__(...))),POSIX线程取消处理程序等交互,而不仅仅是恢复由setjmp?保存的寄存器上下文?我对使用此属性的POSIX实现的存在(或不存在)特别感兴趣,但C/C++通常也很有趣.

对于赏金,我正在寻找符合POSIX或至少类似POSIX的系统,而不是已经提到过的Windows.

c c++ exception-handling stack-unwinding longjmp

14
推荐指数
1
解决办法
2251
查看次数

如果我用"goto"跳出一个catch块,我保证异常对象是免费的吗?

我有这样的代码如下

try {
  doSomething();
} catch(InterruptException) {
  goto rewind_code;
}

if(0) {
rewind_code:
  longjmp(savepoint, 1);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,当我goto离开catch块时,C++运行时存储的异常对象是免费的吗?或者运行时是否允许缓存它,直到周围的函数存在或类似的东西?我只是想确保如果我多次执行上面的代码,每次采用倒带代码,我都不会泄漏内存(因为longjmp不会执行编译器在函数序列之前或之前发出的清理代码).

c++ exception abi language-lawyer longjmp

13
推荐指数
1
解决办法
679
查看次数

即使存在非本地跳转,也可以稳健地检测递归

我有一个特殊的函数(信号处理程序),我想检测它的递归,即确定函数是否直接或间接调用自身.棘手的一点是,该函数在一个点上调用一些不受其控制的代码,并且该代码可以执行任何操作.

通常,我只会写一些类似的东西

void foo() {
    static int recursed = 0;
    if(recursed) {
        ...
    }
    recursed = 1;
    othercode();
    recursed = 0;
}
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,我担心othercode可能会使用longjmp或类似的突破,导致recursed保持在1.如果我的功能以这种方式跳出来,我想确保它不会看到自己如果稍后调用则递归(事实上它longjmp不会出现问题).

注意:我认为longjmp可能.该othercode是从其他一些在最狂野的代码链接的信号处理程序,并确实存在于如处理器SIGSEGV,其使用longjmp还原环境(例如,作为"故障保护"异常处理程序).请注意,longjmp在同步信号处理程序中使用通常是安全的.在任何情况下,我都不特别在意其他代码是否安全,因为它不是我能控制的.

c recursion longjmp

12
推荐指数
1
解决办法
146
查看次数