Bug 22218 – Dynamic casts across binary boundaries can easily fail

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-08-16T20:03:33Z
Last change time
2021-08-20T07:49:09Z
Keywords
pull
Assigned to
No Owner
Creator
kinke

Comments

Comment #0 by kinke — 2021-08-16T20:03:33Z
If there are TypeInfo duplicates in multiple binaries of a process, e.g., from templates instantiated in multiple binaries, dynamic casts can fail. E.g., the following code fails with LDC (v1.27) and GDC (v10.3) on Linux, somehow works with DMD on Linux though, and fails on Windows in general: ``` class C() {} version (DLL) { version (Windows) { import core.sys.windows.dll; mixin SimpleDllMain; } pragma(mangle, "foo") export Object foo(Object o) { assert(cast(C!()) o); // <-- fails here return new C!(); } } else { T getFunc(T)(const(char)* sym, string thisExePath) { import core.runtime : Runtime; version (Windows) { import core.sys.windows.winbase : GetProcAddress; return cast(T) Runtime.loadLibrary("dynamiccast.dll") .GetProcAddress(sym); } else version (Posix) { import core.sys.posix.dlfcn : dlsym; import core.stdc.string : strrchr; auto name = thisExePath ~ '\0'; const pathlen = strrchr(name.ptr, '/') - name.ptr + 1; name = name[0 .. pathlen] ~ "dynamiccast.so"; return cast(T) Runtime.loadLibrary(name) .dlsym(sym); } else static assert(0); } void main(string[] args) { auto c = new C!(); auto o = getFunc!(Object function(Object))("foo", args[0])(c); assert(cast(C!()) o); } } ``` To be built and run like this: $ dmd -shared dynamiccast.d -version=DLL -ofdynamiccast.so -fPIC -defaultlib=libphobos2.so $ dmd dynamiccast.d -ofdynamiccast -fPIC -defaultlib=libphobos2.so $ ./dynamiccast Related: https://issues.dlang.org/show_bug.cgi?id=7020
Comment #1 by dlang-bot — 2021-08-16T20:08:54Z
@kinke updated dlang/druntime pull request #3543 "Fix Issue 22218 - Dynamic casts across binary boundaries can easily fail" fixing this issue: - Fix Issue 22218 Actually fixed by the previous commits, just fixing up the rt.cast_ compile errors after the rebase. https://github.com/dlang/druntime/pull/3543
Comment #2 by dlang-bot — 2021-08-20T07:49:09Z
dlang/druntime pull request #3543 "Fix Issue 22218 - Dynamic casts across binary boundaries can easily fail" was merged into master: - 861ab5bb4f5de95499909afb9fb7123c2bb94b91 by Martin Kinkelin: Fix Issue 22218 Actually fixed by the previous commits, just fixing up the rt.cast_ compile errors after the rebase. https://github.com/dlang/druntime/pull/3543