calling IDirect3D9::CreateDevice() from DllMain hangs - directx

What can be a reason?
From DllMain() on DLL_PROCESS_ATTACH I'm calling IDirect3D9::CreateDevice() and it hangs
code is straightforward, just like:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if (ul_reason_for_call = DLL_PROCESS_ATTACH) {
IDirect3D9* d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS pp = {};
pp.BackBufferWidth = 1;
pp.BackBufferHeight = 1;
pp.BackBufferFormat = D3DFMT_X8R8G8B8;
pp.BackBufferCount = 1;
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
pp.Windowed = TRUE;
IDirect3DDevice9* device = NULL;
HRESULT hr = d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
GetDesktopWindow(),
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&pp,
&device);
device->Release();
d3d->Release();
}
return TRUE;
}
GetDesktopWindow() is used for simplicity, I tried to create own window and use it, the same result

You cannot do these kind of things in DllMain. Specifically, you cannot call functions from other DLLs. You can only do this from an exported function, when it is called by the main application.
Quoting the docs on MSDN:
Threads in DllMain hold the loader lock so no additional DLLs can be dynamically loaded or initialized.
Calling functions that require DLLs other than Kernel32.dll may result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions load other system components.

Related

nvwgf2umx.dll CComPtr Crash Sometimes

I am receiving a very strange bug right now. I'm currently writing a small project in DirectX 11 and making use of ATL CComPtr's for the COM components. In one instance, I'm wrapping an ID3D11Buffer in a CComPtr. In most of my application, this has been fine and seen no crashes, however, for some reason in this very particular instance, I'm crashing occasionally.
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.ByteWidth = sizeof(MiscCBuffer);
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
hr = device->CreateBuffer(&bd, nullptr, &_gcVoxelBuffer);
if (FAILED(hr)) {
throw std::exception("[E] Creating constant buffer in TerrainComponent onAwake.");
}
This is the code I'm using to create the constant buffer. The CPU buffer's values are set like this
float dimX = _instanceDimensions.x;
float dimY = _instanceDimensions.y;
float dimZ = _instanceDimensions.z;
_cVoxelBuffer.misc.x = dimX;
_cVoxelBuffer.misc.y = dimY;
_cVoxelBuffer.misc.z = dimZ;
_cVoxelBuffer.misc.w = 0;
The MiscCBuffer struct only holds a XMFLOAT4. Finally, to update the constant buffer on the GPU with the CPU data, I use this code.
updateD11Buffer(_gcVoxelBuffer, _cVoxelBuffer, context);
template <class T>
updateD11Buffer(const CComPtr<ID3D11Buffer>& gcBuffer, const T& cbuffer, const CComPtr<ID3D11DeviceContext>& ctx){
D3D11_MAPPED_SUBRESOURCE mappedResource;
ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE));
ctx->Map(gcBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
memcpy(mappedResource.pData, &cbuffer, sizeof(cbuffer));
ctx->Unmap(gcBuffer, 0);
}
As for the error itself, it sometimes happens when the program first launches. It could successfully launch 10 times in a row, and then fail the next 3 times.
Exception thrown at 0x00007FFB003B273B (nvwgf2umx.dll) in ECS_Simulation.exe: 0xC0000005: Access violation reading location 0x000001BE69F9F000.
I have tried reading online but a lot of posts regarding nvwgf2umx.dll crashing with an access violation come from shipped game titles, other posts regarding access violations are usually caused by NULL pointers. In my case, I have checked the _gcVoxelBuffer and _gcVoxelBuffer.p, both of which are valid pointers.
In addition, the D3D Context object is pointing to a valid location, and the CPU side buffer object is also valid to the best of my knowledge.
I'm not sure if this is really the problem, but it's a problem.
Instead try:
template <class T>
updateD11Buffer(const CComPtr<ID3D11Buffer>& gcBuffer, const T& cbuffer, const CComPtr<ID3D11DeviceContext>& ctx)
{
D3D11_MAPPED_SUBRESOURCE mappedResource = {};
if (SUCCEEDED(ctx->Map(gcBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource))
{
memcpy(mappedResource.pData, &cbuffer, sizeof(cbuffer));
ctx->Unmap(gcBuffer, 0);
}
}
ZeroMemory is ancient Win32 pattern. With C++11 or later compilers, uniform initialization is much easier to use.
Note that a more flexible design would be:
template <class T>
updateD11Buffer(ID3D11Buffer* gcBuffer, const T& cbuffer, ID3D11DeviceContext* ctx)
{
...
}
// call using updateD11Buffer(_gcVoxelBuffer.Get(), _cVoxelBuffer, context.Get());
This version doesn't force the use of a particular smart-pointer, and is less of a "thick syntax forest".
PS: ATL's CComPtr is a bit dated and has a few quirks to it. For example, &_gcVoxelBuffer assumes that _gcVoxelBuffer is always null so you can easily get resource leaks.
You should take a look at WRL's ComPtr which is "ATL 2.0". See this article.

How to detect if Windows 10 is in tablet mode with Delphi?

How would someone detect when a user enters tablet mode on a Windows 10 device with Delphi code?
Can someone show a code example for this?
I don't want to detect if the user has a tablet or not. I simply want to see whether they're in tablet mode or not. What would be the best way to do this?
You can use UIViewSettings.UserInteractionMode API. Please refer to #Raymond blog: "How can I detect whether my PC is in tablet mode?", there are UWP and desktop ways in C++ you can refer to.
More detailed information you can check this thread.
But you need find out how to do in Delphi. There are some related issues hope they are helpful for you:
delphi - call external WinAPI function
Can we call Native Windows API from Delphi?
I deleted the previous variant (based on [SO]: How can I detect when Windows 10 enters tablet mode in a Windows Forms application? (#CheeseLover's answer) (pointed out by #Remko's comment)) because it's a totally different scenario (doesn't have anything to do with Win running on desktop).
I spent some time on [MS.DevBlogs]: Raymond - How can I detect whether my PC is in tablet mode? (pointed out in #RitaHan-MSFT's answer (+1)), and clearly, that's the way to go.
I don't know how to "translate" the code into Delphi, as many years passed since I wrote significant amounts of code in it (but I'm sure it's possible), so I did the next best thing: wrote a C++ .dll (containing a modified / improved version of Raymond's code) that is called from Delphi.
Note: VStudio is required to build the .dll, I used 2015 Community Edition, which is free and can be downloaded from [VStudio]: Visual Studio 2015 and other Products (you need an MS account though).
dll.cpp:
#include <wrl/client.h>
#include <windows.ui.viewmanagement.h>
#include <UIViewSettingsInterop.h>
#include <wrl/wrappers/corewrappers.h>
namespace WRL = Microsoft::WRL;
namespace VM = ABI::Windows::UI::ViewManagement;
class Backend {
public:
static Backend &instance() {
static Backend m_instance;
return m_instance;
}
WRL::ComPtr<IUIViewSettingsInterop> interop() { return m_interop; }
private:
Backend() {
HRESULT res = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
m_comInit = (res == S_OK) || (res == S_FALSE);
if (m_comInit || (res == RPC_E_CHANGED_MODE)) {
res = Windows::Foundation::GetActivationFactory(WRL::Wrappers::HStringReference(
RuntimeClass_Windows_UI_ViewManagement_UIViewSettings).Get(), &m_interop);
}
}
Backend(const Backend &other) = delete;
Backend &operator =(const Backend &other) = delete;
~Backend() {
if (m_interop) { m_interop.Reset(); }
if (m_comInit) { CoUninitialize(); }
}
bool m_comInit = false;
WRL::ComPtr<IUIViewSettingsInterop> m_interop = nullptr;
};
/*!
Gets Tablet mode value.
\param hwnd Window handle to get the mode for
\returns:
1 - Tablet mode ON
0 - Tablet mode OFF
-X - Error
*/
extern "C" __declspec(dllexport) int GetTabletMode(HWND hwnd) {
WRL::ComPtr<IUIViewSettingsInterop> interop = Backend::instance().interop();
if (!interop) { return -3; }
WRL::ComPtr<VM::IUIViewSettings> viewSettings;
HRESULT res = interop->GetForWindow(hwnd != NULL ? hwnd : GetConsoleWindow(), IID_PPV_ARGS(&viewSettings));
if (!viewSettings) { return -2; }
VM::UserInteractionMode currentMode;
res = viewSettings->get_UserInteractionMode(&currentMode);
int ret = -1;
switch (currentMode) {
case VM::UserInteractionMode_Mouse: ret = 0; break;
case VM::UserInteractionMode_Touch: ret = 1; break;
default: ret = -1;
}
viewSettings.Reset();
return ret;
}
Below is the Delphi relevant code (only the unit, as the rest can easily be manufactured, and there's no point placing it all here).
Unit0.pas:
unit Unit0;
interface
uses
Forms, Dialogs, Controls, StdCtrls, Classes;
type
TForm0 = class(TForm)
CheckButton: TButton;
procedure CheckButtonClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form0: TForm0;
function GetTabletMode(hwnd: THandle): Integer cdecl; external 'TabletUtils.dll';
implementation
{$R *.dfm}
procedure TForm0.CheckButtonClick(Sender: TObject);
var
TabletModeStr: String;
begin
case GetTabletMode(Self.Handle) of
0 : TabletModeStr := 'OFF';
1 : TabletModeStr := 'ON';
else TabletModeStr := 'ERROR';
end;
MessageDlg('Tablet Mode: ' + TabletModeStr, mtInformation, [mbOK], 0);
end;
end.
Output:
[cfati#CFATI-5510-0:e:\Work\Dev\StackOverflow\q056321591]> sopr.bat
*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***
[prompt]> "c:\Install\x86\Microsoft\Visual Studio Community\2015\vc\vcvarsall.bat" x86
[prompt]> dir /b
App0.cfg
App0.dof
App0.dpr
App0.exe
App0.res
dll.cpp
other
Unit0.dcu
Unit0.ddp
Unit0.dfm
Unit0.pas
[prompt]> cl /nologo /DDLL /DNDEBUG /DUSRDLL /D_WINDOWS /MT dll.cpp /link /NOLOGO /DLL /OUT:TabletUtils.dll ole32.lib runtimeobject.lib
dll.cpp
Creating library TabletUtils.lib and object TabletUtils.exp
[prompt]> dir /b
App0.cfg
App0.dof
App0.dpr
App0.exe
App0.res
dll.cpp
dll.obj
other
TabletUtils.dll
TabletUtils.exp
TabletUtils.lib
Unit0.dcu
Unit0.ddp
Unit0.dfm
Unit0.pas
[prompt]> App0.exe
[prompt]>
In the screenshot below, I ran the application:
On my laptop (Win 10) with Desktop mode (right side)
On a Win 10 VM with Tablet mode (left side). Note that I had to copy:
App0.exe
TabletUtils.dll

MemFault in GC when calling back a closure from C

I working with Keil, MDK-ARM Pro 4.71 for a Cortex-M3 target(STM32F107).
I have compiled the Lua interpreter and a Lua "timer" module that interfaces the chip's timers. I'd like to call a lua function when the timer is elapsed.
Here is a sample use :
t = timer.open()
t.event = function() print("Bing !") end
t:start()
Until here, everything works fine :-) ! I see the "Bing !" message being printed each time the timer elapses.
Now if I use a closure :
t = timer.open()
i = 0
t.event = function() i = i + 1; print(i); end
t:start()
I'm having a bad memory access in the GC after some amount of timer's updates. Since it's an embedded context with very few memory, I may be running out of memory quite fast if there is a leak.
Here is the "t.event" setter (ELIB_TIMER is a C structure representing my timer) :
static int ElibTimerSetEvent(lua_State* L)
{
ELIB_TIMER* pTimer_X = ElibCheckTimer(L, 1, TRUE);
if (pTimer_X->LuaFuncKey_i != LUA_REFNIL)
{
luaL_unref(L, LUA_REGISTRYINDEX, pTimer_X->LuaFuncKey_i);
pTimer_X->LuaFuncKey_i = LUA_REFNIL;
}
if (!lua_isnil(L, 2))
{
pTimer_X->LuaFuncKey_i = luaL_ref(L, LUA_REGISTRYINDEX);
}
return 0;
}
And here is the native callback implementation :
static void ElibTimerEventHandler(SYSEVT_HANDLE Event_H)
{
ELIB_TIMER* pTimer_X = (ELIB_TIMER*)SWLIB_SYSEVT_GetSideData(Event_H);
lua_State* L = pTimer_X->L;
int i = lua_gettop(L);
if (pTimer_X->LuaFuncKey_i != LUA_REFNIL)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, pTimer_X->LuaFuncKey_i);
lua_call(L, 0, 0);
lua_settop(L, i);
}
}
This is synchronized externally, so this isn't a synchronization issue.
Am I doing something wrong ?
EDIT
Here is the callstack (with a lua_pcall instead of lua_call, but it is the same). The first line is my hard fault handler.
I have found the problem ! I ran out of stack (native stack, not Lua) space :p.
I guess this specific script was causing a particularly long call stack. After increasing the allocated memory for my native stack, the problem is gone. On the opposite, if I reduce it, I can't even initialize the interpreter.
Many thanks to those who tried to help here.
Found a bug in your C code. You broke the lua stack in static int ElibTimerSetEvent(lua_State* L)
luaL_ref will pop the value on the top of Lua stack: http://www.lua.org/manual/5.2/manual.html#luaL_ref
So you need to copy the value to be refed, before the call to luaL_ref:
lua_pushvalue(L, 2); // push the callback to stack top, and then it will be consumed by luaL_ref()
Please fix this and try again.

a call to GetMessage causes a thread to stop

I am writing a multi-threaded application using Borland C++ (Delphi Forms). I have recently learned that I can use Windows' Messaging Service within these classes when I call the PostThreadMessage() function:
System = new STSystem(SystemName,1000,1,NULL);
while (PostThreadMessage(System->ThreadID,ST_MSG_SYSTEM_INIT,0,0) == 0)
{
Sleep(0);
};
The above seems to work just fine. The issue lies on the retrieval end of this process inside of the Thread Execution function:
void __fastcall STSystem::Execute()
{
ST_Message STMSG;
while(FStatus != Destroyed)
{
FHeartBeat++;
if(GetMessage(MSG,NULL,ST_MSG_SYSTEM_START,ST_MSG_SYSTEM_END))
{
STMSG.Value = MSG->wParam;
if((STMSG.dSYS + (8*STMSG.dSEC) + (64*STMSG.dDEP)) == FSystemID)
{
RXMessages[RxQueueIn++] = STMSG.MSG; // Message
RXMessages[RxQueueIn++] = MSG->lParam; // Data
}
}
if(TaskList->Count>0)
ProcessTask();
if(RxQueueIn!=RxQueueOut)
ProcessRxMessage();
if(TxQueueIn!=TxQueueOut)
ProcessTxMessage();
Sleep(0);
};
}
The above works for about two thread cycles and then stops; the thread stops, not the program. I have tried using the PeekMessage() function instead of the GetMessage() function in the IF clause following the FHeartbeat++ counter. This prevents the thread from stopping however, the INIT message sent in the first block of code is still not found.
I hope this example is not too specific. I have tried to leave in anything that was pertinent. Basically, this is a message pump for a class that has no window.
GetMessage() blocks the calling thread when there are no messages to retrieve. Like Luis said, you need to make sure the thread has a message queue before you start posting messages to it, and you need to check the return value of PostThreadMessage() for failures. A message queue is not created in a thread until any user32.dll function is called within the thread for the first time. For example:
System = new STSystem(SystemName,1000,1,NULL);
while (!System->Ready)
Sleep(100);
if (!PostThreadMessage(System->ThreadID,ST_MSG_SYSTEM_INIT,0,0))
{
DWORD err = GetLastError();
//...
}
void __fastcall STSystem::Execute()
{
// create a message queue
PeekMessage(MSG, NULL, 0, 0, PM_NOREMOVE);
Ready = true;
ST_Message STMSG;
while(FStatus != Destroyed)
{
FHeartBeat++;
if(GetMessage(MSG,NULL,ST_MSG_SYSTEM_START,ST_MSG_SYSTEM_END)) // or PeekMessage()
{
STMSG.Value = MSG->wParam;
if((STMSG.dSYS + (8*STMSG.dSEC) + (64*STMSG.dDEP)) == FSystemID)
{
RXMessages[RxQueueIn++] = STMSG.MSG; // Message
RXMessages[RxQueueIn++] = MSG->lParam; // Data
}
}
if(TaskList->Count>0)
ProcessTask();
if(RxQueueIn!=RxQueueOut)
ProcessRxMessage();
if(TxQueueIn!=TxQueueOut)
ProcessTxMessage();
Sleep(0);
};
}
To send messages to a tread it must have a message queue, in the remarks section of this link:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644946(v=vs.85).aspx
you can fine the steps reqired to create a message queue for a thread.
By the way, if PostThreadMessage returns 0 (FALSE), there is an error and you must check the value returned by GetLastError.

Bad file descriptor on pthread_detach

My pthread_detach calls fail with a "Bad file descriptor" error. The calls are in the destructor for my class and look like this -
if(pthread_detach(get_sensors) != 0)
printf("\ndetach on get_sensors failed with error %m", errno);
if(pthread_detach(get_real_velocity) != 0)
printf("\ndetach on get_real_velocity failed with error %m", errno);
I have only ever dealt with this error when using sockets. What could be causing this to happen in a pthread_detach call that I should look for? Or is it likely something in the thread callback that could be causing it? Just in case, the callbacks look like this -
void* Robot::get_real_velocity_thread(void* threadid) {
Robot* r = (Robot*)threadid;
r->get_real_velocity_thread_i();
}
inline void Robot::get_real_velocity_thread_i() {
while(1) {
usleep(14500);
sensor_packet temp = get_sensor_value(REQUESTED_VELOCITY);
real_velocity = temp.values[0];
if(temp.values[1] != -1)
real_velocity += temp.values[1];
} //end while
}
/*Callback for get sensors thread*/
void* Robot::get_sensors_thread(void* threadid) {
Robot* r = (Robot*)threadid;
r->get_sensors_thread_i();
} //END GETSENSORS_THREAD
inline void Robot::get_sensors_thread_i() {
while(1) {
usleep(14500);
if(sensorsstreaming) {
unsigned char receive;
int read = 0;
read = connection.PollComport(port, &receive, sizeof(unsigned char));
if((int)receive == 19) {
read = connection.PollComport(port, &receive, sizeof(unsigned char));
unsigned char rest[54];
read = connection.PollComport(port, rest, 54);
/* ***SET SENSOR VALUES*** */
//bump + wheel drop
sensor_values[0] = (int)rest[1];
sensor_values[1] = -1;
//wall
sensor_values[2] = (int)rest[2];
sensor_values[3] = -1;
...
...
lots more setting just like the two above
} //end if header == 19
} //end if sensors streaming
} //end while
} //END GET_SENSORS_THREAD_I
Thank you for any help.
The pthread_* functions return an error code; they do not set errno. (Well, they may of course, but not in any way that is documented.)
Your code should print the value returned by pthread_detach and print that.
Single Unix Spec documents two return values for this function: ESRCH (no thread by that ID was found) and EINVAL (the thread is not joinable).
Detaching threads in the destructor of an object seems silly. Firstly, if they are going to be detached eventually, why not just create them that way?
If there is any risk that the threads can use the object that is being destroyed, they need to be stopped, not detached. I.e. you somehow indicate to the threads that they should shut down, and then wait for them to reach some safe place after which they will not touch the object any more. pthread_join is useful for this.
Also, it is a little late to be doing that from the destructor. A destructor should only be run when the thread executing it is the only thread with a reference to that object. If threads are still using the object, then you're destroying it from under them.

Resources