I'm trying to track down a "memory leak." However it's doesn't seem like a real memory leak since calling ReportLiveDeviceObjects reports that there are 0 references
D3D11 WARNING: Live ID3D11Texture2D at 0x00000140D3FE44F0, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #425: LIVE_TEXTURE2D]
D3D11 WARNING: Live ID3D11RenderTargetView at 0x00000140D3FCBB60, Refcount: 0, IntRef: 0 [ STATE_CREATION WARNING #428: LIVE_RENDERTARGETVIEW]
D3D11 WARNING: Live ID3D11Texture2D at 0x00000140D3FE5BF0, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #425: LIVE_TEXTURE2D]
D3D11 WARNING: Live ID3D11RenderTargetView at 0x00000140B8EDB000, Refcount: 0, IntRef: 0 [ STATE_CREATION WARNING #428: LIVE_RENDERTARGETVIEW]
As you can see, the ID3D11RenderTargetView objects have both 0 internal and external references. However it's still a live object. What could cause this to happen?
For clarity, I am using this through SharpDX, though that shouldn't affect the debug output from DirectX 11.
Corresponding issue:
https://github.com/sharpdx/SharpDX/issues/903
DirectX 11 uses 'deferred destruction' of resources, so typically if you need to force destruction you need to Flush. For example, in Direct3D game templates, you need to fully unbind and destroy the render targets before resizing:
// Remove any bound render target or depth/stencil buffer
ID3D11RenderTargetView* nullViews [] = { nullptr };
m_d3dContext->OMSetRenderTargets(_countof(nullViews), nullViews, nullptr);
// Destroy the views (which themselves hold the references to the resources)
m_renderTargetView.Reset();
m_depthStencilView.Reset();
// Flush the immediate context to force cleanup
m_d3dContext->Flush();
Related
I'm trying to create VkImageView which will be binded to index 0.
Here is my VkImageView creation code
void Image::createImageView() {
VkImageViewUsageCreateInfo imageViewUsage;
imageViewUsage.sType=VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
imageViewUsage.pNext=nullptr;
imageViewUsage.usage=VK_IMAGE_USAGE_STORAGE_BIT;
VkImageViewCreateInfo viewInfo{};
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.pNext=&imageViewUsage;
viewInfo.image = textureImage;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;
if (vkCreateImageView(device, &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) {
throw std::runtime_error("failed to create texture image view!");
}
}
When I call vkUpdateDescriptorSets I get validation error:
vkCreateImageView: Includes a pNext pointer (pCreateInfo->pNext) to a VkStructureType (VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO), but its parent extension VK_KHR_maintenance2 has not been enabled. The Vulkan spec states: Each pNext member of any structure (including this one) in the pNext chain must be either NULL or a pointer to a valid instance of VkImageViewASTCDecodeModeEXT, VkImageViewUsageCreateInfo, VkSamplerYcbcrConversionInfo, VkVideoProfileKHR, or VkVideoProfilesKHR
Before this I had set viewInfo.pNext=nullptr; for which I was getting validation error:
Write update to VkDescriptorSet 0xf018750000000004[] allocated with VkDescriptorSetLayout 0x683e70000000002[] binding #0 failed with error message: Attempted write update to image descriptor failed due to: ImageView (VkImageView 0xa3c6870000000008[]) with usage mask 0x6 being used for a descriptor update of type VK_DESCRIPTOR_TYPE_STORAGE_IMAGE does not have VK_IMAGE_USAGE_STORAGE_BIT set
Can someone please help me with some hint how exactly I can solve the error?
The error message tells you exactly what to do. If you use VkImageViewUsageCreateInfo, that means you have to enable maintenance2 extension or in turn Vulkan 1.1 to which it was promoted.
Since you seem surprised by the existence of extensions, it feels likely your use of them is just accidental. You might simply want to stop using the VkImageViewUsageCreateInfo extension struct and always set pNext to NULL.
I am trying to load a library via reflective DLL injection, but it crashes on calling ofstream.open(); calling fopen() yields the same result.
For reflective dll injection i basically follow the steps described at https://0x00sec.org/t/reflective-dll-injection/3080:
Load the dll contents in a buffer
Create a file mapping and map view of file, then copying the NT headers and sections there.
Copy the contents of the mapping to a buffer and close the mapping.
Rebuild the import table.
Rebuild relocations.
Allocate memory in a target suspended process and copy the buffer there.
CreateRemoteThread to start the dllMain (while the target process is still suspended).
The code gets loaded and the dllmain is executed.
My dllmain looks like this:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
logFile.open("hookLog.txt", std::ios::out);
logFile << "DLL Attached\n";
HRESULT nResult = InitCoCreateInstanceHook();
logFile << "Hook initialized with result: " << std::to_string(nResult) << "\n";
logFile.flush();
}
And it crashes while opening the log file. I know exeption handling is not set up when I execute the code, could that be the issue? Am I missing something else?
Thanks in advance.
I Was going through the CCL code samples along with the oneapi toolkit.
In the below DPC++(SYCL) code initially sendbuf a buffer is created in the cpu side and is not initialised and in the part where offloading to target device takes place the dev_acc_sbuf[id] variable, which is a variable in the kernel scope is modified. This variable(dev_acc_sbuf) is not hence used in the program neither is its value copied back to sendbuf.Then in the next line the sendbuf variable is used for allreduce. I am not able to understand how changing the dev_acc_sbuf makes change in the sendbuf.
cl::sycl::queue q;
cl::sycl::buffer<int, 1> sendbuf(COUNT);
/* open sendbuf and modify it on the target device side */
q.submit([&](cl::sycl::handler& cgh) {
auto dev_acc_sbuf = sendbuf.get_access<mode::write>(cgh);
cgh.parallel_for<class allreduce_test_sbuf_modify>(range<1>{COUNT}, [=](item<1> id) {
dev_acc_sbuf[id] += 1;
});
});
/* invoke ccl_allreduce on the CPU side */
ccl_allreduce(&sendbuf,
&recvbuf,
COUNT,
ccl_dtype_int,
ccl_reduction_sum,
NULL,
NULL,
stream,
&request);
In the line "auto dev_acc_sbuf = sendbuf.get_access<mode::write>(cgh);" the dev_acc_sbuf is a handle that accesses sendbuf and not a seperate buffer. The changes made in the dev_acc_sbuf handle gets reflected to the original buffer ie the sendbuffer . This is an advantage in SYCL as the changes made in the kernel scope is automatically copied back to the original variable
On most systems, the host and the device do not share physical memory, the CPU might use RAM and the GPU might use its own global memory. SYCL needs to know which data it will be sharing between the host and the devices.
For this purpose, SYCL uses its buffers, the buffer class is generic over the element type and the number of dimensions. When passed a raw pointer, the buffer(T* ptr, range size) constructor takes ownership of the memory it has been passed. This means that we absolutely cannot use that memory ourselves while the buffer exists, which is why we begin a C++ scope. At the end of their scope, the buffers will be destroyed and the memory returned to the user. A size argument is a range object, which has to have the same number of dimensions as the buffer and is initialized with the number of elements in each dimension. Here, we have one dimension with one element.
Buffers are not associated with a particular queue or context, so they are capable of handling data transparently between multiple devices.
Accessors are used to access request control over the device memory from the buffer objects. Their modes will take care of data movement between host and device. So we need not have to explicitly copy back the result from device to host.
Below is the example for more clarification:
#include <bits/stdc++.h>
#include <CL/sycl.hpp>
using namespace std;
class vector_addition;
int main(int, char**) {
//creating host memory
int *a=(int *)malloc(10*sizeof(int));
int *b=(int *)malloc(10*sizeof(int));
int *c=(int *)malloc(10*sizeof(int));
for(int i=0;i<10;i++){
a[i]=i;
b[i]=10-i;
}
cl::sycl::default_selector device_selector;
cl::sycl::queue queue(device_selector);
std::cout << "Running on "<< queue.get_device().get_info<cl::sycl::info::device::name>()<< "\n";
{
//creating buffer from pointer of host memory
cl::sycl::buffer<int, 1> a_sycl{a, cl::sycl::range<1>{10} };
cl::sycl::buffer<int, 1> b_sycl{b, cl::sycl::range<1>{10} };
cl::sycl::buffer<int, 1> c_sycl{c, cl::sycl::range<1>{10} };
queue.submit([&] (cl::sycl::handler& cgh) {
//creating accessor of buffer with proper mode
auto a_acc = a_sycl.get_access<cl::sycl::access::mode::read>(cgh);
auto b_acc = b_sycl.get_access<cl::sycl::access::mode::read>(cgh);
auto c_acc = c_sycl.get_access<cl::sycl::access::mode::write>(cgh);//responsible for copying back to host memory
//kernel for execution
cgh.parallel_for<class vector_addition>(cl::sycl::range<1>{ 10 }, [=](cl::sycl::id<1> idx) {
c_acc[idx] = a_acc[idx] + b_acc[idx];
});
});
}
for(int i=0;i<10;i++){
cout<<c[i]<<" ";
}
cout<<"\n";
return 0;
}
I am writing a DirectX 11 based engine.
Where all of the DirectX Com objects are wrapped in Microsoft::WRL::ComPtr.
But unfortunately when I am calling ID3D11Debug::ReportLiveDeviceObjects on shutdown, it is reporting more the reference count for more than 1 objects are non-zero.
I am confused, which code actually increasing those reference count preventing teh reference to be zero at the end. For an example, I am providing this example usage of ID3D11ShaderResourceView in my code:
The ID3D11ShaderResourceView was declared in my render target class as member,
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_pShaderResourceView
It was initialized in to nullptr in the constructor:
m_pShaderResourceView(wwNULLPTR)
The interface was created as follows:
device->CreateShaderResourceView(m_pDXTexture.Get(), &shaderResourceDesc, m_pShaderResourceView.ReleaseAndGetAddressOf());
The interface was used in GenerateMips function:
deviceContext->GenerateMips(m_pShaderResourceView.Get());
There is a getter function for the interface:
ID3D11ShaderResourceView* GetShaderResourceView()
{
return m_pShaderResourceView.Get();
}
and at last the interface was reset in desctructor:
m_pShaderResourceView.Reset();
At the end I am getting at least 8 reference in live object summary.
My questions are:
Which part of my code is actually increasing the reference count?
Why calling Reset is not making the reference zero?
Probably I am missing something?
Thanks.
ID3D11Debug::ReportLiveDeviceObjects is a very useful debugging tool, but it does have some quirks. Specifically a few objects have lives you don't directly control and are part of the ID3D11Device itself. You can't get rid of the references without closing the device, at which point you can't get a live objects report.
In the DXUT for Direct3D 11 framework, I get it down as much as possible by calling ClearState and then Flush on the immediate context just before calling report live objects.
Even in a 'clean' exit you will still have a few lingering "live" objects:
D3D11 WARNING: Live ID3D11Device at 0x025CA03C, Refcount: 5 [ STATE_CREATION WARNING #441: LIVE_DEVICE]
D3D11 WARNING: Live ID3D11Context at 0x02831030, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #2097226: LIVE_CONTEXT]
D3D11 WARNING: Live ID3DDeviceContextState at 0x02828038, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #3145742: LIVE_DEVICECONTEXTSTATE]
D3D11 WARNING: Live ID3D11BlendState at 0x005B766C, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #435: LIVE_BLENDSTATE]
D3D11 WARNING: Live ID3D11DepthStencilState at 0x0283ECAC, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #436: LIVE_DEPTHSTENCILSTATE]
D3D11 WARNING: Live ID3D11RasterizerState at 0x027006F4, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #437: LIVE_RASTERIZERSTATE]
D3D11 WARNING: Live ID3D11Sampler at 0x0270082C, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #434: LIVE_SAMPLER]
D3D11 WARNING: Live ID3D11Query at 0x005BB904, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #438: LIVE_QUERY]
D3D11 WARNING: Live ID3D11Context : 1 [ STATE_CREATION WARNING #422: LIVE_OBJECT_SUMMARY]
D3D11 WARNING: Live ID3DDeviceContextState : 1 [ STATE_CREATION WARNING #422: LIVE_OBJECT_SUMMARY]
D3D11 WARNING: Live ID3D11BlendState : 1 [ STATE_CREATION WARNING #422: LIVE_OBJECT_SUMMARY]
D3D11 WARNING: Live ID3D11DepthStencilState : 1 [ STATE_CREATION WARNING #422: LIVE_OBJECT_SUMMARY]
D3D11 WARNING: Live ID3D11RasterizerState : 1 [ STATE_CREATION WARNING #422: LIVE_OBJECT_SUMMARY]
D3D11 WARNING: Live ID3D11Sampler : 1 [ STATE_CREATION WARNING #422: LIVE_OBJECT_SUMMARY]
D3D11 WARNING: Live ID3D11Query : 1 [ STATE_CREATION WARNING #422: LIVE_OBJECT_SUMMARY]
These are the 'default' objects used by the runtime itself. Ideally the debug runtime would ignore them when generating this report, but it doesn't.
That said, as you have 8 instead of 5 live objects, you may have something lingering on. First try the ClearState and Flush to make sure you aren't having anything kept alive by the virtue of being bound to the pipeline or due to deferred destruction. If there are still objects left, the next step in finding them is to make use of "Debug Object Naming" so you can figure out what objects you control are still alive. The debug naming can be done using either a macro or a template:
Template
template<UINT TNameLength>
inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const char (&name)[TNameLength])
{
#if defined(_DEBUG)
resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name);
#else
UNREFERENCED_PARAMETER(resource);
UNREFERENCED_PARAMETER(name);
#endif
}
Macro
#ifdef _DEBUG
inline void DXUT_SetDebugName( _In_ ID3D11DeviceChild* pObj,
_In_z_ const CHAR* pstrName )
{
if ( pObj )
pObj->SetPrivateData( WKPDID_D3DDebugObjectName,
(UINT)strlen(pstrName), pstrName );
}
#else
#define DXUT_SetDebugName( pObj, pstrName )
#endif
You need to link to dxguid.lib to get the symbol WKPDID_D3DDebugObjectName. "WKPDID" stands for Well Known Private Data ID. It's ironic since it isn't all that 'well known'.
See Object Naming and Direct3D SDK Debug Layer Tricks
I have troubles with dynamic loading of libraries - my code panics with Kern-Exec 3. The code is as follows:
TFileName dllName = _L("mydll.dll");
TFileName dllPath = _L("c:\\sys\\bin\\");
RLibrary dll;
TInt res = dll.Load(dllName, dllPath); // Kern-Exec 3!
TLibraryFunction f = dll.Lookup(1);
if (f)
f();
I receive panic on TInt res = dll.Load(dllName, dllPath); What can I do to get rid of this panic? mydll.dll is really my dll, which has only 1 exported function (for test purposes). Maybe something wrong with the DLL? Here's what it is:
def file:
EXPORTS
_ZN4Init4InitEv # 1 NONAME
pkg file:
#{"mydll DLL"},(0xED3F400D),1,0,0
;Localised Vendor name
%{"Vendor-EN"}
;Unique Vendor name
:"Vendor"
"$(EPOCROOT)Epoc32\release\$(PLATFORM)\$(TARGET)\mydll.dll"-"!:\sys\bin\mydll.dll"
mmp file:
TARGET mydll.dll
TARGETTYPE dll
UID 0x1000008d 0xED3F400D
USERINCLUDE ..\inc
SYSTEMINCLUDE \epoc32\include
SOURCEPATH ..\src
SOURCE mydllDllMain.cpp
LIBRARY euser.lib
#ifdef ENABLE_ABIV2_MODE
DEBUGGABLE_UDEBONLY
#endif
EPOCALLOWDLLDATA
CAPABILITY CommDD LocalServices Location MultimediaDD NetworkControl NetworkServices PowerMgmt ProtServ ReadDeviceData ReadUserData SurroundingsDD SwEvent TrustedUI UserEnvironment WriteDeviceData WriteUserData
source code:
// Exported Functions
namespace Init
{
EXPORT_C TInt Init()
{
// no implementation required
return 0;
}
}
header file:
#ifndef __MYDLL_H__
#define __MYDLL_H__
// Include Files
namespace Init
{
IMPORT_C TInt Init();
}
#endif // __MYDLL_H__
I have no ideas about this... Any help is greatly appreciated.
P.S. I'm trying to do RLibrary::Load because I have troubles with static linkage. When I do static linkage, my main program doesn't start at all. I decided to check what happens and discovered this issue with RLibrary::Load.
A KERN-EXEC 3 panic is caused by an unhandled exception (CPU fault) generated by trying to invalidly access a region of memory. This invalid memory access can be for both code (for example, bad PC by stack corruption) or data (for example, accessing freed memory). As such these are typically observed when dereferencing a NULL pointer (it is equivalent to a segfault).
Certainly the call to RLibrary::Load should never raise a KERN-EXEC 3 due to programmatic error, it is likely to be an environmental issue. As such I have to speculate on what is happening.
I believe the issue that is observed is due to stack overflow. Your MMP file does not specify the stack or heap size the initial thread should use. As such the default of 4Kb (if I remember correctly) will be used. Equally you are using TFileName - use of these on the stack is generally not recommended to avoid... stack overflow.
You would be better off using the _LIT() macro instead - this will allow you to provide the RLibrary::Load function with a descriptor directly referencing the constant strings as located in the constant data section of the binary.
As a side note, you should check the error value to determine the success of the function call.
_LIT(KMyDllName, "mydll.dll");
_LIT(KMyDllPath, "c:\\sys\\bin\\");
RLibrary dll;
TInt res = dll.Load(KMyDllName, MyDllPath); // Hopefully no Kern-Exec 3!
if(err == KErrNone)
{
TLibraryFunction f = dll.Lookup(1);
if (f)
f();
}
// else handle error
The case that you can't use static linkage should be a strong warning to you. It shows that there is something wrong with your DLL and using dynamic linking won't change anything.
Usually in these cases the problem is in mismatched capabilities. DLL must have at least the same set of capabilities that your main program has. And all those capabilities should be covered by your developer cert.