[llvm-dev] RuntimeDyLdCOFF and RTTI on Windows

Stefan Gränitz via llvm-dev llvm-dev at lists.llvm.org
Tue Oct 25 06:19:40 PDT 2016


>> LLVM ERROR: Program used external function '??_7type_info@@6B@' which
>> could not be resolved!
>>
>> Have you done anything to get past this kind of problem?
>
> It's the external "const type_info::`vftable'" and it seems correctly
> resolved by linking to msvcrt.lib/msvcrtd.lib. I think this is correct
> because building the repro with Visual Studio and
> /NODEFAULTLIB:"msvcrt.lib" brings up the same unresolved symbol.

Quoting VC\crt\src\vcruntime\std_type_info_static.cpp, line 6:
Definition of the std::type_info destructor. This symbol is needed in
the import library. Any class with virtual member functions compiled
with /GR will depend on the type_info::`vftable` symbol. This definition
of the destructor ensures that this symbol will be found, even if no
user source file includes <typeinfo>.

So IIUC it's meant to be a fallback. Anyway, this looks promising
VC\crt\src\vcruntime\vcstartup_internal.h, line 218:

void __CRTDECL __scrt_initialize_type_info();
void __CRTDECL __scrt_uninitialize_type_info();

Am 25.10.2016 um 14:34 schrieb Stefan Gränitz:
> Hi Reid, thanks for looking into that.
> 
>> but I get this:
>> LLVM ERROR: Program used external function '??_7type_info@@6B@' which
>> could not be resolved!
> 
> That's right, sorry I accidentally used our own adjusted version and it
> silently skips unresolved symbols in release builds [1]. On head of
> release39 I get this too.
> 
>> Have you done anything to get past this kind of problem?
> 
> It's the external "const type_info::`vftable'" and it seems correctly
> resolved by linking to msvcrt.lib/msvcrtd.lib. I think this is correct
> because building the repro with Visual Studio and
> /NODEFAULTLIB:"msvcrt.lib" brings up the same unresolved symbol.
> 
> Anyway, lli will report the next problem:
> 
> $ lli -extra-archive="C:\Program Files (x86)\Microsoft Visual Studio
> 14.0\VC\lib\amd64\msvcrt.lib" repro_input.bc
> LLVM ERROR: Program used external function '??_Etype_info@@UEAAPEAXI at Z'
> which could not be resolved!
> 
> This is a WeakExternal symbol referring to:
> public: virtual void * __cdecl type_info::`vector deleting
> destructor'(unsigned int))
> 
> In our production system we're currently just ignoring it, as I didn't
> figure this one. I cannot reproduce it with Visual Studio and reading
> about it a bit more let us assume it's probably not urgently relevant
> yet [2].
> 
> However, this may well be related to the problem with RTTI!
> 
> Best
> Stefan
> 
> [1]
> https://github.com/weliveindetail/pj-llvm/commit/58e09372c29d6c60cd982cd1b560a692fcf85de8
> 
> [2] "6) Deleting Destructors" in
> http://www.openrce.org/articles/full_view/23
> 
> Am 25.10.2016 um 01:49 schrieb Reid Kleckner:
>> I have a similar build tree to what you describe on Windows, but I get this:
>>
>> $ clang -c -emit-llvm repro_input.cpp -std=c++11 -o t.bc
>> $ lli t.bc
>> LLVM ERROR: Program used external function '??_7type_info@@6B@' which
>> could not be resolved!
>>
>> It looks like people have already reported similar issues. Have you done
>> anything to get past this kind of problem?
>>
>> On Sat, Oct 22, 2016 at 7:18 AM, Stefan Gränitz via llvm-dev
>> <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote:
>>
>>     Hi Lang, hi dev-list (as it may be interesting for others too)
>>
>>     With the cpp file attached, the repro is actually as simple as this:
>>     $ clang -std=c++11 -emit-llvm repro_input.cpp -c -o repro_input.bc
>>     $ lli repro_input.bc
>>
>>     On Mac this prints:
>>     dynamic_cast worked! dummy is 1
>>
>>     On Windows this prints:
>>     dynamic_cast failed
>>
>>     As the issue is reproducible with lli, it's probably unrelated to
>>     the COFF implementation as originally stated.
>>     I built LLVM and Clang from release39 HEAD and used both, clang and
>>     lli from this build. OS versions and CMake flags are:
>>
>>     * OSX 10.10.6 with -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_EH=ON
>>     -DLLVM_TARGETS_TO_BUILD=X86
>>     * Windows 10 64bit OS Build 14393.222 with -DLLVM_ENABLE_RTTI=ON
>>     -DLLVM_ENABLE_EH=ON -DLLVM_TARGETS_TO_BUILD=X86
>>     -DLLVM_USE_CRT_DEBUG=MDd -DLLVM_USE_CRT_RELEASE=MD
>>
>>     Hope this helps nailing down the issue. Maybe I can help fixing it,
>>     if you can provide a few pointers where to start :) If you need any
>>     more info please let me know.
>>
>>     Cheers
>>     Stefan
>>
>>     Am 19.10.16 um 12:10 schrieb Stefan Gränitz:
>>>     Hi Lang, thanks for getting back to this.
>>>
>>>>     Did you get a chance to run this on a debug build? Did it trigger
>>>>     an assertions/unreachables? Or did the cast just fail?
>>>     Yes, I use debug builds of Clang and LLVM (both 3.9.1). We have a
>>>     pretty special setup in the Projucer, but with "95% certainty":
>>>     Clang output is correct. Loading the binary objects with
>>>     RuntimeDyLd produces the problem. I spent quite some time
>>>     debugging this and the fact that data is incomplete though it's in
>>>     the right place feels similar to what I experienced with
>>>     exceptions on Win64 (which turned out to be missing registration
>>>     calls https://llvm.org/bugs/show_bug.cgi?id=24233
>>>     <https://llvm.org/bugs/show_bug.cgi?id=24233>).
>>>
>>>>     Will you be at the dev meeting? We could take a look at this in
>>>>     one of the labs.
>>>     Sooner or later I will make it to a Bay Area dev meeting, promise!
>>>     Unfortunately not in November as I will be at ADC in London.
>>>     However, I will try to reproduce the issue in a minimal example
>>>     during our Berlin Hackday on Saturday, that's a good challenge! If
>>>     successful I will put it on GitHub and let you know! Maybe you
>>>     guys then find a solution or make a plan at the dev meeting.
>>>
>>>     Thanks
>>>     Stefan
>>>
>>>     Am 18.10.16 um 21:35 schrieb Lang Hames:
>>>>     Hi Stefan,
>>>>
>>>>     Did you get a chance to run this on a debug build? Did it trigger
>>>>     an assertions/unreachables? Or did the cast just fail?
>>>>
>>>>     Will you be at the dev meeting? We could take a look at this in
>>>>     one of the labs.
>>>>
>>>>     Cheers,
>>>>     Lang.
>>>>
>>>>
>>>>     On Tue, Oct 11, 2016 at 1:52 AM, Stefan Gränitz
>>>>     <stefan.graenitz at gmail.com <mailto:stefan.graenitz at gmail.com>> wrote:
>>>>
>>>>         Thanks Lang for forwarding this to the list
>>>>         The symptom in a nutshell: I cannot get dynamic_cast to work
>>>>         in JITed code on Windows
>>>>
>>>>         Reid, do you have an idea whether: it's a bug / it's just not
>>>>         implemented yet / I am missing something?
>>>>>         Just to rule out one other possibility, Reid: does Windows
>>>>>         require any special calls to register C++ RTTI?
>>>>
>>>>         There's some more details in the original mail.
>>>>
>>>>         Thanks
>>>>         Stefan
>>>>
>>>>         Am 07.10.16 um 02:29 schrieb Lang Hames via llvm-dev:
>>>>>         HI Stefan,
>>>>>
>>>>>         CC'ing Reid Kleckner, who might have some insight here, and
>>>>>         llvm-dev as this may be of interest to other windows JIT users.
>>>>>
>>>>>             I am facing the issue that C++ dynamic_cast doesn't work
>>>>>             for types
>>>>>             loaded from object files with RuntimeDyLd.
>>>>>
>>>>>          
>>>>>         <snip>
>>>>>
>>>>>             Do you think it is possible that RuntimeDyLd misses type
>>>>>             info data in
>>>>>             the COFF file or doesn't wire it up correctly?
>>>>>             I set ProcessAllSections = true, but I didn't recognize
>>>>>             any change. I
>>>>>             found that RuntimeDyLdCOFF does not override
>>>>>             finalizeLoad like the ELF
>>>>>             and MachO versions. The function call's comment reads
>>>>>             "Give the
>>>>>             subclasses a chance to tie-up any loose ends" --
>>>>>             possibly missing
>>>>>             functionality?
>>>>>
>>>>>
>>>>>         Unfortunately I don't have a windows machine to test on, so
>>>>>         it's difficult to know for sure. From a quick look at the
>>>>>         IR, it seems like the Window's C++ ABI implementation of
>>>>>         dynamic_cast works similarly to Darwin's: The type info
>>>>>         pointers for the reference type and cast type are passed in
>>>>>         to the function, so as long as memory has been allocated for
>>>>>         the type info I would have expected this to "just work". My
>>>>>         best guess for why it wouldn't is that RuntimeDyldCOFF is a
>>>>>         missing relocation somewhere. What happens when you run this
>>>>>         code on a debug build? Do you hit the llvm_unreachable at
>>>>>         the bottom of the resolveRelocation switch?
>>>>>
>>>>>         Just to rule out one other possibility, Reid: does Windows
>>>>>         require any special calls to register C++ RTTI?
>>>>>
>>>>>         Finally, regarding the ProcessAllSections flag: it tells
>>>>>         RuntimeDyld to call the memory manager interface for every
>>>>>         section, not just the sections that RuntimeDyld thinks are
>>>>>         necessary for execution. This was a hack to make debug info
>>>>>         sections visible to clients who are interested in them. It
>>>>>         can be important if your object file contains metadata
>>>>>         sections that are required, but not referenced in the file.
>>>>>         I don't think it should affect this case though.
>>>>>
>>>>>         - Lang.
>>>>>
>>>>>
>>>>>         On Thu, Oct 6, 2016 at 4:37 AM, Stefan Gränitz
>>>>>         <stefan.granitz at roli.com <mailto:stefan.granitz at roli.com>>
>>>>>         wrote:
>>>>>
>>>>>             Hi Lang
>>>>>
>>>>>             You are not only the maintainer for ORC but also for
>>>>>             RuntimeDyLd right?
>>>>>             May I ask if you know about problems reading RTTI data
>>>>>             from COFF object
>>>>>             files on Windows?
>>>>>
>>>>>             I am facing the issue that C++ dynamic_cast doesn't work
>>>>>             for types
>>>>>             loaded from object files with RuntimeDyLd. I inspected
>>>>>             my object files
>>>>>             compiled with Clang-3.9 (pure, not cl2) and they seem to
>>>>>             include all the
>>>>>             necessary info. When I link (with MS link) and run the
>>>>>             static build I
>>>>>             get the expected behavior. Correspondingly I'd consider
>>>>>             the RTTI
>>>>>             emission in Clang to work correctly.
>>>>>
>>>>>             When I load the object files with RuntimeDyLd at
>>>>>             runtime, I face the
>>>>>             following troubles in vcruntime140.dll:
>>>>>             * invoking dynamic_cast: the RTTI Complete Object
>>>>>             Locator queried in
>>>>>             __RTDynamicCast (rtti.cpp) has incomplete data, which
>>>>>             tricks the runtime
>>>>>             to always belief the number of base classes is zero,
>>>>>             that's why
>>>>>             dynamic_cast never succeeds
>>>>>             * invoking typeid(variable).name(): the runtime's
>>>>>             __std_type_info_name
>>>>>             (std_type_info.cpp) receives a corrupt type data
>>>>>             pointer, which causes
>>>>>             an access violation when reading from one of its members
>>>>>
>>>>>             Do you think it is possible that RuntimeDyLd misses type
>>>>>             info data in
>>>>>             the COFF file or doesn't wire it up correctly?
>>>>>             I set ProcessAllSections = true, but I didn't recognize
>>>>>             any change. I
>>>>>             found that RuntimeDyLdCOFF does not override
>>>>>             finalizeLoad like the ELF
>>>>>             and MachO versions. The function call's comment reads
>>>>>             "Give the
>>>>>             subclasses a chance to tie-up any loose ends" --
>>>>>             possibly missing
>>>>>             functionality?
>>>>>
>>>>>             It would help a lot if you let me know your feeling on
>>>>>             this issue and/or
>>>>>             give me a few pointers what I could check next.
>>>>>
>>>>>             I can reproduce the above symptoms reliably within our
>>>>>             project on
>>>>>             different Windows systems. I think I can also prepare a
>>>>>             self-contained
>>>>>             repro, if you happen to have a Windows machine/VM at
>>>>>             hand and you are
>>>>>             interested in clearing up this issue.
>>>>>
>>>>>             Thanks.
>>>>>             Stefan
>>>>>
>>>>>         _______________________________________________
>>>>>         LLVM Developers mailing list
>>>>>         llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
>>>>>         http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>>         <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev>
>>>>
>>>>         -- 
>>>>         https://about.me/stefan.graenitz
>>>>         <https://about.me/stefan.graenitz>
>>>>
>>>     -- 
>>>     https://about.me/stefan.graenitz <https://about.me/stefan.graenitz>
>>
>>     -- 
>>     https://about.me/stefan.graenitz <https://about.me/stefan.graenitz>
>>
>>
>>     _______________________________________________
>>     LLVM Developers mailing list
>>     llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
>>     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>     <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev>
>>
>>



More information about the llvm-dev mailing list