10

There is this code:

char text[] = "zim";
int x = 777;

If I look on stack where x and text are placed there output is:

09 03 00 00 7a 69 6d 00

Where:

  • 09 03 00 00 = 0x309 = 777 <- int x = 777
  • 7a 69 6d 00 = char text[] = "zim" (ASCII code)

There is now code with try..catch:

char text[] = "zim";
try{
  int x = 777;
}
catch(int){
}

Stack:

09 03 00 00 **97 85 04 08** 7a 69 6d 00

Now between text and x is placed new 4 byte value. If I add another catch, then there will be something like:

09 03 00 00 **97 85 04 08** **xx xx xx xx** 7a 69 6d 00

and so on. I think that this is some value connected with exception handling and it is used during stack unwinding to find appropriate catch when exception is thrown in try block. However question is, what is exactly this 4-byte value (maybe some address to excception handler structure or some id)?

I use g++ 4.6 on 32 bit Linux machine.

Charles
  • 50,943
  • 13
  • 104
  • 142
scdmb
  • 15,091
  • 21
  • 85
  • 128
  • See [C++ try/throw/catch => machine code](http://stackoverflow.com/questions/1331220/c-try-throw-catch-machine-code), which points to http://www.codeproject.com/Articles/2126/How-a-C-compiler-implements-exception-handling – Adam Liss Feb 12 '12 at 17:08
  • 3
    Why do you want to know. Even if we gave you an answer it would be specific to the compiler and that specific version of the compiler. So technically it is not a C++ question. It is a question about g++ and how it works. Which unless you are really into writing extensions for g++ is completely useless knowledge. – Martin York Feb 12 '12 at 17:17
  • 4
    @LokiAstari: g++ and other C++ compilers for *nix use the [Itanium ABI](http://sourcery.mentor.com/public/cxx-abi/abi-eh.html) on most plaforms (with some modifications depending on the platform), so it's not *that* platform/compiler specific. And still, it's interesting to know how the exception handling machinery can be implemented. – Matteo Italia Feb 12 '12 at 17:23
  • 1
    @MatteoItalia: Its the bit `modifications depending on the platform` that worries me (and making the firs assumption is a bad idea). As a compiler writer I find exception implementation very interesting. And even I don't care what 4 bytes on the stack represent (I bet it is a pointer at a structure). This knowledge is only useful in a much broader context that requires a lot more specialized knowledge before the information becomes even slightly meaningful. But as a normal C++ coder or a beginner the knowledge is useless. – Martin York Feb 12 '12 at 17:29
  • @LokiAstari: probably you are right - and actually if I were curious about exception handling implementation like him I'd just have a look at the related Itanium ABI section, without going into excruciating detail of the single pointers going around. – Matteo Italia Feb 12 '12 at 17:35
  • I actually couldn't reproduce. I used a 32bit Fedora VM with GCC 4.5.1. It seems adding a try-catch clause does not affect `gcc -g`. Also, @AdamLiss - the link you gave is relevant to VC++, which is working differently to G++ (http://stackoverflow.com/questions/490773/how-is-the-c-exception-handling-runtime-implemented) – user1071136 Feb 12 '12 at 19:40

2 Answers2

5

AFAICT, that's a pointer to an "unwind table". Per the the Itanium ABI implementation suggestions, the process "[uses] an unwind table, [to] find information on how to handle exceptions that occur at that PC, and in particular, get the address of the personality routine for that address range. "

The idea behind unwind tables is that the data needed for stack unwinding is rarely used. Therefore, it's more efficient to put a pointer on the stack, and store the reast of the data in another page. In the best cases, that page can remain on disk and doesn't even need to be loaded in RAM. In comparison, C style error handling often ends up in the L1 cache because it's all inline.

MSalters
  • 173,980
  • 10
  • 155
  • 350
0

Needless to say all this is platform-dependent and etc.

This may be an address. It may point to either a code section (some handler address), or data section (pointer to a build-time-generated structure with frame info), or the stack of the same thread (pointer to a run-time-generated table of frame info). Or it may also be a garbage, left due to an alignment requirement, which EH may demand.

For instance on Win32/x86 there's no such a gap. For every function that uses exception handling (has either try/catch or __try/__except/__finally or objects with d'tors) - the compiler generates an EXCEPTION_RECORD structure that is allocated on the stack (by the function prolog code). Then, whenever something changes within the function (object is created/destroyed, try/catch block entered/exited) - the compiler adds an instruction that modifies this structure (more correctly - modifies its extension). But nothing more is allocated on the stack.

valdo
  • 12,632
  • 2
  • 37
  • 67