1

I have some odd code which needs to call a throwing function in an asm block and be able to catch the exception thrown. My code looks something like this:

// Throwing Function
void throwing() __asm__("throwing");
void throwing() {
    throw "abc";
}

// Assembly function which calls throwing()
void asm_call() {
    __asm__ __volatile__ (
        "call throwing\n"
    );
}

// Main calls the assembly function in a try block
int main() {
    try {
        asm_call();
    } catch (...) {
        std::cout << "caught..." << std::endl;
    }

    return 0;
}

I am unable to get the exception to be caught by main; it always simply terminates when it reaches the throw "abc"; line. I saw a similar question here, and I tried the top answer but it did not work for me. Is it possible to catch the exception which is thrown in the asm_call?

I'm using x64 Linux with g++ 6.3.0.

user3250889
  • 191
  • 1
  • 9
  • 1
    Since you are inserting assembler, there is no stack-unwinding information available for that part of the call stack, so the stack-unwinding code just errors out. I have no clue as to what needs to be done to get the stack-unwinding code properly skip over your asm `call`, but I'd strongly suggest that you just wrap the `throwing()` function into a `non_throwing_callthrough()` wrapper, that catches the exception and returns an error code. – cmaster - reinstate monica Nov 24 '17 at 16:53
  • You can't easily use `call` from inline asm in x86-64 Linux [because it clobbers the red-zone](https://stackoverflow.com/questions/34520013/using-base-pointer-register-in-c-inline-asm). The only safe workaround is to `add $-128, %rsp` first. When you compile with optimizations enabled, code like that can and will break when `asm_call` is inlined. – Peter Cordes Nov 25 '17 at 01:49
  • Or maybe this doesn't apply if you call a function that always throws, but then you have a different problem: you've written an `asm()` statement where execution enters but leaves somewhere else, and you didn't use `asm goto` to tell the compiler about it. The compiler might decide to leave something until *after* the `asm volatile`, but then it never happens. (Using a `"memory"` clobber can help prevent that). – Peter Cordes Nov 25 '17 at 01:50

0 Answers0