Skip to content

[Linux] WinAdapter: IUnknown vtable includes destructors resulting in ABI mismatch #3783

@MarijnS95

Description

@MarijnS95

The vtable for IUnknown from WinAdapter.h contains five instead of three function pointers, shifting vtable entries for every subclass. Two pointers following the three virutal functions in IUnknown are reserved for a complete object and deleting destructor:

vtable for 'DxcLibrary' @ 0x7ffff7cbc5f8 (subobject @ 0x5555556bb9e0):
[0]: 0x7ffff6a56d40 <DxcLibrary::QueryInterface(_GUID const&, void**)>
[1]: 0x7ffff6a56d20 <DxcLibrary::AddRef()>
[2]: 0x7ffff6a56d30 <DxcLibrary::Release()>
[3]: 0x7ffff6b36bc0 <IUnknown::~IUnknown()> // Complete object destructor
[4]: 0x7ffff6a57130 <DxcLibrary::~DxcLibrary()> // Deleting destructor
[5]: 0x7ffff6a56d50 <DxcLibrary::SetMalloc(IMalloc*)>
[6]: 0x7ffff6a56d60 <DxcLibrary::CreateBlobFromBlob(IDxcBlob*, unsigned int, unsigned int, IDxcBlob**)>
[7]: 0x7ffff6a56d70 <DxcLibrary::CreateBlobFromFile(wchar_t const*, unsigned int*, IDxcBlobEncoding**)>
[8]: 0x7ffff6a56d80 <DxcLibrary::CreateBlobWithEncodingFromPinned(void const*, unsigned int, unsigned int, IDxcBlobEncoding**)>
[9]: 0x7ffff6a56d90 <DxcLibrary::CreateBlobWithEncodingOnHeapCopy(void const*, unsigned int, unsigned int, IDxcBlobEncoding**)>
[10]: 0x7ffff6a56da0 <DxcLibrary::CreateBlobWithEncodingOnMalloc(void const*, IMalloc*, unsigned int, unsigned int, IDxcBlobEncoding**)>
[11]: 0x7ffff6a56db0 <DxcLibrary::CreateIncludeHandler(IDxcIncludeHandler**)>
[12]: 0x7ffff6a56dc0 <DxcLibrary::CreateStreamFromBlobReadOnly(IDxcBlob*, IStream**)>
[13]: 0x7ffff6a56dd0 <DxcLibrary::GetBlobAsUtf8(IDxcBlob*, IDxcBlobEncoding**)>
[14]: 0x7ffff6a56e90 <DxcLibrary::GetBlobAsUtf16(IDxcBlob*, IDxcBlobEncoding**)>

This makes it annoying or impossible to interact with the interfaces from Linux and Windows in a generic way.

Simply removing it results in compiler warnings from both Clang and GCC:

../include/dxc/Support/WinAdapter.h:628:8: warning: 'IUnknown' has virtual functions but non-virtual destructor [-Wnon-virtual-dtor]
struct IUnknown {
       ^

No idea if ignoring them locally (#pragma clang/GCC diagnostic ignored "-Wnon-virtual-dtor") or globally is the right way forward though. Members owned by subclasses of IUnknown should be cleaned up through the Release() function anyway otherwise this would leak memory and other resources on Windows where no virtual destructors are used.

I recall reading something about operator delete (called as delete this in IUnknown::Release) requiring object size to call the appropriate memory deallocation function which could be facilitated through this destructor. The deleting destructor could possibly pass a size to one of the operator delete variants.

@pow2clk Hope you have some suggestions since you've been working on Linux compatibility - apart this issue everything runs flawlessly on Linux on-par with our Windows builds and that's simply awesome!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions