[Issue 22218] New: Dynamic casts across binary boundaries can easily fail
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Mon Aug 16 20:03:33 UTC 2021
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 at puremagic.com
Reporter: kinke at 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
--
More information about the Digitalmars-d-bugs
mailing list