August 16, 2021 [Issue 22218] New: Dynamic casts across binary boundaries can easily fail | ||||
|---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=22218 Issue ID: 22218 Summary: Dynamic casts across binary boundaries can easily fail Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: major Priority: P1 Component: druntime Assignee: nobody@puremagic.com Reporter: kinke@gmx.net 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 -- | ||||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply