[llvm-dev] Windows "0xC00001A5: An invalid exception handler routine has been detected" with LLVM win32 (i386) SEH code

636 views
Skip to first unread message

Carlo Kok via llvm-dev

unread,
Aug 20, 2018, 10:00:39 AM8/20/18
to llvm-dev
Hi,

I'm getting:

Unhandled exception at 0x00C211F0 in ConsoleApplication830.exe: 0xC00001A5: An invalid exception handler routine has been detected (parameters: 0x00000001).

With some fairly simple SEH enabled routine:

define i32 @__elements_entry_point_main(%._gt2a_RemObjects_d_Elements_d_System_d_Array_t_1s*) #0 personality i8* bitcast (i32 ()* @_elements_exception_handler to i8*) !dbg !61 {
BasicBlock0:
%1 = alloca %._gt2a_RemObjects_d_Elements_d_System_d_Array_t_1s*
store %._gt2a_RemObjects_d_Elements_d_System_d_Array_t_1s* %0, %._gt2a_RemObjects_d_Elements_d_System_d_Array_t_1s** %1
call void @llvm.dbg.declare(metadata %._gt2a_RemObjects_d_Elements_d_System_d_Array_t_1s** %1, metadata !86, metadata !DIExpression()), !dbg !88
%csLoc0 = alloca i32, !dbg !88
store i32 0, i32* %csLoc0, !dbg !88
br label %BasicBlock1, !dbg !88

BasicBlock1: ; preds = %BasicBlock0
call void @llvm.dbg.declare(metadata i32* %csLoc0, metadata !89, metadata !DIExpression()), !dbg !91
store i32 0, i32* %csLoc0, !dbg !91
invoke void @ms_t1d_ConsoleApplication4_d_Program2_m1()
to label %BasicBlock2 unwind label %2, !dbg !92

BasicBlock2: ; preds = %BasicBlock1
br label %BasicBlock3, !dbg !93

; <label>:2: ; preds = %BasicBlock1
%3 = catchswitch within none [label %BasicBlock4] unwind to caller, !dbg !93

BasicBlock3: ; preds = %BasicBlock5, %BasicBlock2
%4 = load i32, i32* %csLoc0, !dbg !94
ret i32 %4, !dbg !94

BasicBlock4: ; preds = %2
%5 = catchpad within %3 [{ i8*, i8* }* @0, i32 0, i8* null], !dbg !93
catchret from %5 to label %BasicBlock5, !dbg !95

BasicBlock5: ; preds = %BasicBlock4
br label %BasicBlock3, !dbg !95

BasicBlock6: ; No predecessors!
unreachable, !dbg !94
}


(_elements_exception_handler is my exception handler routine which I added to the LLVM source, compatible with the standard VC++ one). My question is,

is there something special I need to do to make SEH work (I'm using LLVM LLD to compile it, from 3 months ago, but latest doesn't give a different result)? I can't find anything real about that exception code.

0x00C211F0 DOES point to the generated code used for SEH:

00C211F0 | 57 | push edi |
00C211F1 | 56 | push esi |
00C211F2 | 83EC 10 | sub esp,10 |
00C211F5 | 8B4424 28 | mov eax,dword ptr ss:[esp+28] |
00C211F9 | 8B4C24 24 | mov ecx,dword ptr ss:[esp+24] |
00C211FD | 8B5424 20 | mov edx,dword ptr ss:[esp+20] |
00C21201 | 8B7424 1C | mov esi,dword ptr ss:[esp+1C] |
00C21205 | BF 54DCC800 | mov edi,consoleapplication830.C8DC54 |
00C2120A | 894424 0C | mov dword ptr ss:[esp+C],eax |
00C2120E | 89F8 | mov eax,edi |
00C21210 | 897424 08 | mov dword ptr ss:[esp+8],esi |
00C21214 | 894C24 04 | mov dword ptr ss:[esp+4],ecx |
00C21218 | 891424 | mov dword ptr ss:[esp],edx |
00C2121B | 83C4 10 | add esp,10 |
00C2121E | 5E | pop esi |
00C2121F | 5F | pop edi |
00C21220 | E9 7B270100 | jmp <consoleapplication830.RemObjects.Elements.System.Exte |

Which seems fine.
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Reid Kleckner via llvm-dev

unread,
Aug 20, 2018, 12:47:11 PM8/20/18
to Carlo Kok, llvm-dev
This is 32-bit x86, right? Sounds like the exception handler did not appear in the /safeseh table.

If you emit a standalone .s file, do you see something like `.safeseh  _elements_exception_handler` somewhere in there? If not, that's a problem. I think it would also be a problem if  _elements_exception_handler is imported. If so, try making a thunk for it.

You can also try running `dumpbin /loadconfig` (or equivalently llvm-readobj -coff-load-config) on your binary to confirm that the RVA of _elements_exception_handler appears in the safe seh table.

Carlo Kok via llvm-dev

unread,
Aug 20, 2018, 2:04:30 PM8/20/18
to Reid Kleckner, llvm-dev
Indeed, it's 32bits x86 and there's no .safeseh or anything like it, even readobj -coff-load-config says nothing:

File: ConsoleApplication830.exe
Format: COFF-i386
Arch: i386
AddressSize: 32bit


Now I know what to look for, thanks!

Reid Kleckner via llvm-dev

unread,
Aug 20, 2018, 4:14:14 PM8/20/18
to Carlo Kok, llvm-dev
Oh, apparently we did this:

void WinException::endModule() {
  auto &OS = *Asm->OutStreamer;
  const Module *M = MMI->getModule();
  for (const Function &F : *M)
    if (F.hasFnAttribute("safeseh"))
      OS.EmitCOFFSafeSEH(Asm->getSymbol(&F));
}

And we add the attribute in the state number store insertion pass.  That's not very discoverable. :(

So, I guess just add the "safeseh" string attribute to your personality declaration and you're set.

Carlo Kok via llvm-dev

unread,
Aug 21, 2018, 2:34:16 AM8/21/18
to Reid Kleckner, llvm-dev
Yeah but it seems that's set automatically on the other end, so that's not a real problem.

Turns out that, since I don't use libc I  didn't have:

_load_config_used

which has to be setup to make it all work. Once introduced everything started working again (odd that this used to work without, I think LLD must have started to set a " I need safeseh" bit at some point).

Thanks!
Reply all
Reply to author
Forward
0 new messages