[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