4

On Windows x64, suppose there is a call chain of three functions:

function A, written in C++
function B, generated by a JIT compiler
function C, written in C++

A calls B which calls C, then C throws an exception caught by A. B is just straight-line code; it never throws or catches any exception, nor does it contain any destructors.

http://msdn.microsoft.com/en-us/library/ms235286(v=vs.80).aspx says B has to keep the stack aligned to 16 bytes, which is fine. It also says B has to be supplied with unwinding data, but isn't clear about what this data should consist of or how to supply it.

In this case where B does not actually have to do any unwinding, does it still have to have an empty unwinding data block, or can you just ignore that and have the exception silently pass over B?

rwallace
  • 31,405
  • 40
  • 123
  • 242

2 Answers2

5

You do need unwind data as this article explains:

even if you just have a tiny little function that only calls another function, you still need unwind data, or when an exception occurs, your process will simply be terminated.

The format of the unwind data is documented but it is rather terse.

arx
  • 16,686
  • 2
  • 44
  • 61
2

The Microsoft C++ compiler emits exception handling code that's unified with Windows SEH. So it is an excellent tool to see how it should be done. Start with a dummy project that contains some test code:

void foo() { throw 1; }

void testNoTry() { foo(); }

void testTry() {
    try { foo(); }
    catch (int& err) {}
}

Project + Properties, C/C++, Output Files, ASM List Location = /FAcs. That generates a .cod file with the assembly for this code. C/C++, Code Generation, Basic Runtime Checks = Default. That cuts down on the noise. Build.

Open the .cod file with your text editor. You'll see it writing exception data to the xdata$x segment. With explicitly named parts for the unwind table, __unwindtable$ symbols. Painful, isn't it.

But otherwise very good news: there is no unwind data at all for testNoTry(). Congratulations. Build up your confidence about it by making it less trivial, moving foo() into another .cpp file for example and trying /EHsa.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536