Permalink
Browse files

[AMD64] Fix bug when getting a signal while throwing exception.

This is a very rarely occurring bug that's also still present on x86
and possibly other architectures, as well.
  • Loading branch information...
1 parent 2f76311 commit 8828fafe297e758858468c2e96054ae101ea7227 @schani schani committed Oct 2, 2013
Showing with 11 additions and 10 deletions.
  1. +11 −10 mono/mini/exceptions-amd64.c
@@ -225,16 +225,17 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
amd64_mov_reg_membase (code, AMD64_R15, AMD64_R11, G_STRUCT_OFFSET (MonoContext, r15), 8);
#endif
- if (mono_running_on_valgrind ()) {
- /* Prevent 'Address 0x... is just below the stack ptr.' errors */
- amd64_mov_reg_membase (code, AMD64_R8, AMD64_R11, G_STRUCT_OFFSET (MonoContext, rsp), 8);
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, G_STRUCT_OFFSET (MonoContext, rip), 8);
- amd64_mov_reg_reg (code, AMD64_RSP, AMD64_R8, 8);
- } else {
- amd64_mov_reg_membase (code, AMD64_RSP, AMD64_R11, G_STRUCT_OFFSET (MonoContext, rsp), 8);
- /* get return address */
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, G_STRUCT_OFFSET (MonoContext, rip), 8);
- }
+ /*
+ * The context resides on the stack, in the stack frame of the
+ * caller of this function. The stack pointer that we need to
+ * restore is potentially many stack frames higher up, so the
+ * distance between them can easily be more than the red zone
+ * size. Hence the stack pointer can be restored only after
+ * we have finished loading everything from the context.
+ */
+ amd64_mov_reg_membase (code, AMD64_R8, AMD64_R11, G_STRUCT_OFFSET (MonoContext, rsp), 8);
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, G_STRUCT_OFFSET (MonoContext, rip), 8);
+ amd64_mov_reg_reg (code, AMD64_RSP, AMD64_R8, 8);
/* jump to the saved IP */
amd64_jump_reg (code, AMD64_R11);

0 comments on commit 8828faf

Please sign in to comment.