-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scalar deleting destructor link error #13
Comments
This should already be linked to by way of the Is it possible to provide an example as to how you're using ➜ git diff
diff --git a/stltest/memory_tests.cpp b/stltest/memory_tests.cpp
index 97ffcdc..7892139 100644
--- a/stltest/memory_tests.cpp
+++ b/stltest/memory_tests.cpp
@@ -7,9 +7,22 @@
#include "tests_common.hpp"
#include <jxy/memory.hpp>
+#include <jxy/string.hpp>
+
namespace jxy::Tests
{
+struct TestObject
+{
+ ~TestObject() = default;
+
+ TestObject(_In_ const wchar_t* n) : Name(n)
+ {
+ }
+
+ const jxy::wstring<NonPagedPoolNx, '0GAT'> Name;
+};
+
void MemoryTests()
{
{
@@ -70,6 +83,10 @@ void MemoryTests()
auto ptr = jxy::make_shared<int, NonPagedPoolNx, '0GAT'>(1);
UT_ASSERT(*ptr == 1);
}
+ {
+ auto ptr = jxy::make_shared<TestObject, NonPagedPoolNx, '0GAT'>(L"Testing");
+ UT_ASSERT(ptr->Name == L"Testing");
+ }
} That said, there is still a problem with storing an object that requires virtual destruction in a jxy::unique_ptr<IInterface, PagedPool, '0GAT'> ptr(new (PagedPool, '0GAT') Implementation()); In this scenario we will store an offset pointer, destruct through the scalar deleting destructor, then free the virtual pointer - when in reality we should have freed the implementation pointer. That said, there is a property of how MSVC implements the scalar deleting destructor where (despite there technically not being a return value (e.g. Regardless, what you're explaining should work for the time being since the implementation mentioned previously for I will investigate the problem explained previously when I have time. But, I expect it isn't what you're encountering, based on what you've described. |
Thank you for your quick response and explanation. Because you mentioned about vcrtl dependency, I immediately realized that I am working on a fork (https://github.com/lucianpin/stlkrn/tree/main-no-exceptions) where I deliberately switched off exceptions and removed the vcrtl dependency. All I wanted was the STL in kernel even with no exception handling and your repository is the winner. Now all seems clear, I really overlooked the https://github.com/avakar/vcrtl/blob/master/src/runtime.cpp. So there is no need for further investigation. I must provide that code on my own. Thanks again and your work and info is really appreciated. |
The issue occurred as soon as some struct allocated through
jxy::make_unique
contained some members of other class types that required a constructor and destructor.The error:
LNK2019: unresolved external symbol "void __cdecl operator delete(void *,unsigned __int64)" (??3@YAXPEAX_K@Z) referenced in function "public: void * __cdecl SomeClass::'scalar deleting destructor'(unsigned int)"
Background: So what is
'scalar deleting destructor'(unsigned int)
? According to this article: https://ofekshilon.com/2014/06/09/on-vector-deleting-destructors-and-some-newdelete-internals/The
unsigned int
parameter is a flag telling if the function should perform a vector deleting destructor or a scalar deleting destructor and whether to deallocate memory, which is optional.Raymond Chen spelled out pseudo code for it:
The actual issue:
When the default deleter calls
Pointer->~T()
, the compiler is using the hidden wrapper functionSomeClass::'scalar deleting destructor'
, but with flag set not to perform deallocation because obviously the intention was only to call de destructor ofSomeClass
.It can be seen that flag is tested and if not set, after calling the destructor, it would jump at the end without calling the
operator delete
.However, the code calling
operator delete
is there so the compiler needs the definition for it. But Jxy library is not providing any code for such signature:void __cdecl operator delete(void *,unsigned __int64)
because no code path should presumably call it. In kernel-mode we would eventually usevoid __cdecl operator delete(void* Memory, POOL_TYPE PoolType, ULONG PoolTag)
. So that explains the link error.Solution would be to define
void __cdecl operator delete(void* Memory, size_t Size)
and maybe alsovoid __cdecl operator delete(void* Memory) noexcept
, but to issue a bug check if these operators would ever be called - that should not happen. All this just because the compiler is using the multi-purpose wrapper and the code inside needs to link also to not used delete operator in kernel.Any other ideas or thoughts?
The text was updated successfully, but these errors were encountered: