标签: stack-unwinding

在didSelectRowAtIndexPath中使用展开segue?

我有一个根视图控制器A,它将segue推送到表视图控制器B.当在B中选择一行时,我想使用展开segue返回到A并将行中的文本传递回根视图A.然后我使用准备segue方法将stint发送回如下:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
     ViewControllerA *vca = (ViewControllerA *)segue.destinationViewController;
    vca.textString = [[_objects objectAtIndex:indexPath.row] objectForKey:@"title"];
}
Run Code Online (Sandbox Code Playgroud)

但是我不知道该怎么做,就是在didSelectRowAtIndexPath方法中调用unwind segue.

我在这里先向您的帮助表示感谢.

objective-c stack-unwinding didselectrowatindexpath ios

5
推荐指数
1
解决办法
3363
查看次数

调试时无法设置下一个语句

我在VS2015中调试我的项目,并在我的代码中抛出异常.当我尝试设置下一个语句时,我收到下面显示的错误消息.当我在VS2013中调试相同的解决方案时,我能够设置下一个语句没有任何问题.这种行为似乎发生在多种异常中.

Microsoft Visual Studio错误窗口:

我可以重现问题的示例代码如下所示.当在最后一行抛出异常时,TestMethod1我可以很容易地回到VS2013中的第一个语句,但不能回到VS2015中.

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        object o = new object();
        o = null;
        var e = o.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

c# stack-unwinding .net-4.5 visual-studio-2013 visual-studio-2015

5
推荐指数
1
解决办法
7132
查看次数

在Linux/GCC下将NULL指针访问转换为C++异常

有没有办法将NULL指针访问转换为Linux下的C++异常?类似于Java中的NullPointerException.我希望以下程序能够成功返回,而不是崩溃(假设编译器在编译期间无法找出此NULL指针访问):

class NullPointerException {};

void accessNullPointer(char* ptr) {
    *ptr = 0;
}

int main() {
    try {
        accessNullPointer(0);
    } catch (NullPointerException&) {
        return 1;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不期望任何标准的方法,因为C++下的NULL指针访问是未定义的 - 行为,只是想知道如何在x86_64 Linux/GCC下完成它.

我做了一些非常原始的研究,有可能:

  1. 当在Linux下访问NULL指针时,将生成SIGSEGV.
  2. 在SIGSEGV处理程序内部,程序的内存和寄存器信息将可用(如果sigaction()用于注册信号处理程序).如果程序被反汇编,也可以使用导致SIGSEGV的指令.
  3. 修改程序的内存和/或注册,并创建/伪造异常实例(可能通过调用低级展开库函数,如_Unwind_RaiseException等)
  4. 最后从信号处理程序返回,希望程序启动一个C++堆栈展开过程就像抛出正常异常一样.

以下是GCC手册页的引用(-fnon-call-exceptions):

生成允许捕获指令以抛出异常的代码.请注意,这需要在任何地方都不存在的特定于平台的运行时支持.此外,它只允许捕获指令抛出异常,即内存引用或浮点指令.它不允许从诸如"SIGALRM"之类的任意信号处理程序抛出异常.

看来这个"特定于平台的运行时"正是我想要的.任何人都知道这样的Linux/x86_64运行时?或者如果没有这样的运行时已经存在,请给我一些关于如何实现这样的运行时的信息?

我希望该解决方案也适用于多线程程序.

c++ linux gcc exception stack-unwinding

5
推荐指数
1
解决办法
417
查看次数

RAII获取破坏期间捕获的错误的方法

在维基百科上的文件I/O的RAII的典型示例中,吞下关闭文件时发生的任何错误:

#include <iostream>
#include <string> 
#include <fstream>
#include <stdexcept>

void write_to_file (const std::string & message) {
    // try to open file
    std::ofstream file("example.txt");
    if (!file.is_open())
        throw std::runtime_error("unable to open file");

    // write message to file
    file << message << std::endl;

    // file will be closed when leaving scope (regardless of exception)
}
Run Code Online (Sandbox Code Playgroud)

似乎没有办法确定file自动关闭时是否发生错误; 显然一个只能调用file.rdstate()file上的范围.

我可以file.close()手动调用然后检查错误,但是我必须在从示波器返回的每个地方都这样做,这违背了RAII的目的.

有些人评论说,在析构函数中只能发生文件系统损坏等不可恢复的错误,但我不相信这是正确的,因为析构函数AFAIK在关闭文件之前会刷新文件,并且在刷新时可能会发生可恢复的错误.

那么是否有一种常见的RAII方法来获取破坏期间发生的错误?我读到从析构函数中抛出异常是危险的,这听起来不像正确的方法.

我能想到的最简单的方法是注册一个回调函数,如果在破坏期间发生任何错误,析构函数将调用该函数.令人惊讶的是,似乎没有一个事件得到支持ios_base::register_callback.这似乎是一个重大的疏忽,除非我误解了一些事情.

但也许回调是在现代课程设计中被破坏时通知错误的最常见方式?

我假设在析构函数中调用任意函数也很危险,但是将调用包装在一个try/catch块中是完全安全的.

c++ error-handling destructor raii stack-unwinding

5
推荐指数
1
解决办法
195
查看次数

If an object is created locally and thrown as an exception in C++, how can a local object be valid outside it's scope .i.e., in catch block?

在try块中,调用了函数“ fun()”。在“ fun”内部创建一个类“ abc”的本地对象,并引发异常。该本地对象被捕获在“ catch”块中,并且已打印了适当的值。由于此对象是在本地创建的,因此不应打印“ 0(默认值)”,因为调用throw时将发生堆栈展开。

#include <iostream>

using namespace std;

class abc
{
    int var;
    public:
    abc():abc(0){}
    abc(int i):var(i){}
    void print()
    {
        cout << "inside abc : " << var << endl;
    }
};

void fun()
{
    cout << "inside fun()" << endl;
    abc obj(10);
    throw obj;
}

int main()
{
    try
    {
        cout << "inside try" << endl;
        fun();
    }catch(abc& ob)
    {
        ob.print();
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:在 abc 内部尝试
在fun()
内部:10

我的期望: 在abc 内部尝试
在fun()
内部:0

c++ exception stack-unwinding c++11

4
推荐指数
1
解决办法
140
查看次数

我应该使用 std::uncaught_exceptions() 来决定是否从我的 dtor 抛出异常吗?

我有一个类,其 ctor 进行驱动程序调用,其 dtor 进行匹配的终止/释放驱动程序调用。这些调用可能会失败。问题自然出在 dtor 身上。

我自然知道避免 dtor 中出现异常的常识,因为如果您在堆栈展开期间抛出异常,您会得到std::terminate. 但是 - 如果可以的话,我宁愿不只是“吞下”此类错误并且不报告它们。那么,编写这样的代码是否合法/惯用:

~MyClass() noexcept(false) {
    auto result = something_which_may_fail_but_wont_throw();
    if (std::uncaught_exceptions() == 0) {
        throw some_exception(result);
    }
}
Run Code Online (Sandbox Code Playgroud)

或者这只是巴洛克风格而不是一个好主意?

注意:此类无法访问标准输出/错误流,也无法访问日志等。

c++ destructor idioms stack-unwinding exception-safety

4
推荐指数
1
解决办法
231
查看次数

异常处理

我听说有人说因为堆栈展开,异常处理有点贵.

我没有得到什么,无论我抛出异常以及是否使用"return",都会发生堆栈展开.那么区别在哪里?

例如,如果我遇到无法处理的内存问题 - 唯一的选择是停止该功能,直到我到达应该处理或通知问题的区域.那么抛出异常的另一个选择是什么?

我可以使用"return"而不是抛出异常,但那时它是一样的.我知道堆栈展开甚至可以返回六个堆栈,但所以检查返回值和"返回"组合.

欢迎解释.

c++ exception stack-unwinding

3
推荐指数
1
解决办法
694
查看次数

停止调试时堆栈是否已解除?

如果我的析构函数被调用,那就好奇了.
(特别是对于Visual Studio,当您点击红色停止按钮时)

c++ standards destructor stack-unwinding visual-studio

3
推荐指数
1
解决办法
549
查看次数

C++从析构函数中抛出异常

这不是一个关于从析构函数中抛出异常是否安全的问题.

http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9声明:

"在堆栈展开期间,所有这些堆栈帧中的所有本地对象都被破坏.如果其中一个析构函数抛出一个异常(比如它抛出一个Bar对象),那么C++运行时系统就处于一个无法获胜的情况:它应该忽略Bar并最终进入} catch(Foo e){它最初的位置?它应该忽略Foo并寻找} catch(Bar e){handler?没有好的答案 - 任何选择都会丢失信息.

IE:如果在堆栈展开期间抛出另一个异常,那么运行时系统处于不赢状态,因为"查找"的catch处理程序是不明确的.

当堆栈展开期间抛出的异常是在try/catch块中时,是否存在上述"异常"?在这种情况下,没有歧义:

#include <iostream>
using namespace std;

class Component
{
public:
    ~Component()
    {
        cout << "In component destructor" << endl;
        try
        {
            throw 1;
        }
        catch (...)
        {
            cout << "Caught exception in component destructor" << endl;
        }
    }

};

class Container
{
public:
    ~Container()
    {
        cout << "In container destructor" << endl;
        Component component;
    }
}
    ;

int main()
{
    try
    {
        Container cont;
        throw 'a';
    }
    catch (...) …
Run Code Online (Sandbox Code Playgroud)

c++ exception-handling stack-unwinding

3
推荐指数
1
解决办法
1509
查看次数

为什么malloc/new会捕获callstack?

我有一个64位应用程序,在Server 2003下作为服务运行.

当我连接VS Profiler或windbg时,我看到很多像下面那样的callstack.我知道在调试器(或分析器)中产生的进程使用调试堆等...但事实并非如此,因为该服务是由OS启动的,我只附加到它.

我不明白它为什么要展开堆栈.分析器显示花费了大量时间.更多信息:

•这些是使用vc9构建的发行版,在Server 2003上运行.

•系统环境变量_NO_DEBUG_HEAP设置为1.

•我正在使用Microsoft符号服务器.

为什么要捕获堆栈跟踪?它似乎正在记录它...但我无法找到它.

我的目标是验证应用程序是否真正展开堆栈,如果确实如此,请尽量避免使用它.

有任何想法吗?


调用堆栈

ntdll!RtlVirtualUnwind
ntdll!RtlpWalkFrameChain
ntdll!RtlCaptureStackBackTrace
ntdll!RtlpCaptureStackTraceForLogging
ntdll!RtlLogStackBackTrace
ntdll!RtlDebugAllocateHeap
ntdll!RtlAllocateHeapSlowly
ntdll!RtlAllocateHeap
MSVCR90!malloc
MSVCR90!operator new
Run Code Online (Sandbox Code Playgroud)

c++ windows callstack heap-memory stack-unwinding

3
推荐指数
1
解决办法
631
查看次数