So far my program is working pretty well. Unfortunately when I press ctrl + alt + del it throws an error. Now I have read this question:
E_ACCESSDENED when using ctrl alt del
In which it is mentioned that the computer switches to a different screen (in which you don't have any writing permissions). It's just that I have no idea how to trace if I have writing permission in the current screen.
My code looks like:
void D3D::StartFrame() {
HRESULT result;
result = pDevice->Clear( 0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(FRAME_BG_R,FRAME_BG_G,FRAME_BG_B),0.0f,0 );
assert( !FAILED( result ) );
result = pBackBuffer->LockRect( &backRect,NULL,NULL );
assert( !FAILED( result ) );
}
void D3D::EndFrame() {
HRESULT result;
result = pBackBuffer->UnlockRect();
assert( !FAILED( result ) );
result = pDevice->Present( NULL,NULL,NULL,NULL );
assert( !FAILED( result ) );
}
Currently I am running the "StartFrame()" function each frame followed by some actions that should be done during the frame. At the end it will call the "EndFrame()" function that will unlock the drawing rectangle.
Now the error that occurs comes from the last assert (the StartFrame() assert doesn't fail?). Should I change these functions to return booleans telling the program if it should continue or not? Should I make it stop the entire program (which feels a bit odd)? Perhaps I am handling the rectangle locking the wrong way (should it work with asserts)?
Error: Assertion failed! - !FAILED(result)
Any help/advice would be appriciated !
First of all, whenever you get an error, before doing somethig, and before even thinking about what happened, you must check what exactly error message said.
In case of DirectX 9, you must not only check if HRESULT variable FAILED but get detailed info from it. You can get details from it using DXGetErrorString() and/or DXGetErrorDescription() functions (dxerr.h + dxerr.lib). For example, you can handle you errors by writing a small helper function, that accepts HRESULT and shows MessageBox() with details if it FAILED. Also, there is a good DXTrace() macro as a quick solution. Or, as a quickest lazy solution, you can just set a breakpoint right after function fail, and inspect value of HRESULT variable in debug watcher.
In your case, because we don't have error description in your post, we can only guess what happened (that's what guys from SO doesn't like the most). And I suspect here Device Lost state. That state sometimes happens when your app looses focus (Alt+tab, Ctrl+Alt+Del, etc.). To prevent crashes you must handle such exceptional states as described on MSDN or this short tutorial.
Of course, my guess can be wrong here, because I dont't know, what exactly happened. Please add proper error handling and provide additional information to get concrete help.
Happy coding!
Related
Good afternoon to all! I am writing a game engine using OpenGL + Win32 / GLFW. Therefore, I will say the project is large, but I have a problem that has led me to a dead end and I can't understand what the problem is. The problem is that I have a shared_ptr<Context> in the 'windows' class (it is platform-based) that is responsible for the context (GL, D3D). And everything works fine when I launch the application, everything is drawn normally, but when I start entering the cursor into the window, a crash occurs when any function calls from context, in my case is:
context->swapBuffers();
Here a crash:
std::shared_ptr<Context>::operator-><Context,0>(...)->**** was 0xFFFFFFFFFFFFFFE7.
Then I got into the callstack and saw that the context-> itself is non-zero, so the function should be called.
Then I searched for a long time for the problem and found that when I remove the Win32 message processing code, and when I remove it, errors do not occur when calling a function from context->. I removed everything unnecessary from the loop and left only the basic functions and tried to run it like this, because I thought that some other functions inside were causing this problem, but no.
while (PeekMessageW(&msg, NULL, NULL, NULL, PM_REMOVE) > 0) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
That is, when I delete TranslateMessage() and DispatchMessage(), the error goes away. And then I finally got confused i.e I don't understand what is happening. And then I thought that maybe somehow the operating system itself affects that pointer, prohibits reading or something like that.
And then I paid attention to __vtptr in the call stack, and noticed that it is nullptr, and moreover it has the void** type. And also the strangest thing is that in the error I have ->**** was 0xffffffffffffffc7 as many as four consecutive pointers. What is it?
I understand I practically didn't throw off the code, because I have a big project and I think it doesn't make sense to throw everything, so I tried to explain the problem by roughly showing what is happening in my code. I will be grateful to everyone who will help :)
The point was to make this little multiplayer game in the terminal, applying some basic graphics concepts to get a grasp on how it works and the maths behind it.
Note I wish to do this for fun and I am fully aware there are way better alternatives out there to using a terminal.
I'd need a console I could write to, so the point was to remove scroll bars and have the whole buffer printed to the screen.
But because of the carriage return when characters get written to the end of the previous line:
this would look overall ugly:
After trying for about 3 hours to get this working through SetConsoleMode, I asked about it in a discord.
The answer I got was this:
void main( )
{
auto h = GetStdHandle( STD_OUTPUT_HANDLE );
DWORD mode = 0;
GetConsoleMode( h, &mode );
mode |= DISABLE_NEWLINE_AUTO_RETURN | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
puts( SetConsoleMode( h, mode ) ? "Win" : "Loss" );
char * buf = new char[ 200*2 ];
memset( buf, 0, 200*2 );
memset( buf, 'A', 120*2 );
std::cout << ( buf );
getchar( );
}
with this result:
At first I tried adapting it to my project, which failed.
Then I got frustrated and ended up creating a new project into which I just copy pasted the working code.
And you guessed it, it doesn't work.
Now I've tried quite a bit of stuff, I've changed my program from unicode to ansi and back, and done mode = DISABLE_NEWLINE_AUTO_RETURN | ENABLE_VIRTUAL_TERMINAL_PROCESSING, mode |= DISABLE_NEWLINE_AUTO_RETURN | ENABLE_VIRTUAL_TERMINAL_PROCESSING, and each individually with and without |with no success.
Given it's error 87 which means bad parameter, I even tried putting the exact value from GetConsoleMode to see if it was the handle, but since it worked we can assume it's not the handle's problem.
Basically code that works on another machine doesn't work on mine.
The other machine was windows 10 mine's 8.1 both 64.
On both machines the value gotten off GetConsoleMode the first time is 3, which means ENABLE_PROCESSED_OUTPUT and ENABLE_WRAP_AT_EOL_OUTPUT.
The windows SDK version on my project is 10.0.15063.0, with a platform toolset of Visual Studio 2017 (v141).
I've been at this all day with no success. Now it wouldn't be the first time I read over some important detail, but I've been going through documentation and nothing mentions the failiure of SetConsoleMode using ENABLE_VIRTUAL_TERMINAL_PROCESSING.
As far as I can tell I'm doing it correctly based on the Docs
What should I be doing that I am not?
Sorry for any spelling/grammar mistakes that might have gone noticed and thank you for your time.
Virtual terminal mode is available in the console starting with Windows 10.0.10586. It's not supported by the OS if setting the mode fails with ERROR_INVALID_PARAMETER (87). Also, it's only implemented in the new console. With the legacy console selected in Windows 10, enabling VT mode may succeed, but it won't actually enable VT support.
The failure case is mistakenly documented as "SetConsoleMode returning with STATUS_INVALID_PARAMETER" (0xC000000D) in the Enabling Virtual Terminal Processing example. It seems the writer overlooked that the kernel status code that's returned by the NtDeviceIoControlFile system call (in Windows 8+) gets translated to failing the SetConsoleMode call and translating the status code to a Windows API error code.
I am using the method:
ACE_Task::putq (ACE_Message_Block *mb, ACE_Time_Value *tv)
Here is the line where I call it:
ret = putq(mb, const_cast(&ACE_Time_Value::zero));
What I am basically trying is that I need to get regular errors
EWOULDBLOCK and ESHUTDOWN from
int lastErr = ACE_OS::last_error();
in order to debug it right away...
So my question is, it there a simple way how to force such errors ?
I've already tried this:
while ( ret >= 0 )
ret = putq(mb, const_cast(&ACE_Time_Value::max_time));
but my thread gets stuck after few calls and never returns from putq...
Many thanx in advance for hints !
Peter
I think for the first part (EWOULDBLOCK) i can just use:
ACE_Svc_Handler::msg_queue()->high_water_mark(MAX_BUF_SIZE_BYTES);
ACE_Svc_Handler::msg_queue()->low_water_mark(MIN_BUF_SIZE_BYTES);
I assume these fit my needs and what I observe is exactly what I need.
The envoking of ESHUTDOWN error is another problem, and you can simulate it by putting appropriately putting slow down sleep methods.
I am working with HANDLES, the first one, nextColorFrameEvent is an event handler and the second one is a stream handler. They are being initialized in the following piece of code:
nextColorFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
hr = nui->NuiImageStreamOpen(
NUI_IMAGE_TYPE_COLOR,
NUI_IMAGE_RESOLUTION_640x480,
0,
2,
nextColorFrameEvent,
&videoStreamHandle);
I want to properly deal with them on destruction, while not creating errors at the same time. Sometimes the initializer wont be called, so both HANDLEs are still NULL when the software comes to an end. Thats why I want to check first if the HANDLEs are properly initialized etc. and if they are, I want to close them. I got my hands on the following piece of code for this:
if (nextColorFrameEvent && nextColorFrameEvent != INVALID_HANDLE_VALUE)CloseHandle(nextColorFrameEvent);
#ifdef QT_DEBUG
DWORD error = GetLastError();
qDebug()<< error;
#endif
if (videoStreamHandle && videoStreamHandle != INVALID_HANDLE_VALUE)CloseHandle(videoStreamHandle);
#ifdef QT_DEBUG
error = GetLastError();
qDebug()<< error;
#endif
But this is apperently incorrect: if I do not run the initializer and then close the software this piece of code runs and gives me a 6:
Starting C:\...\Qt\build-simpleKinectController-Desktop_Qt_5_0_2_MSVC2012_64bit-Debug\debug\simpleKinectController...
6
6
C:\...\Qt\build-simpleKinectController-Desktop_Qt_5_0_2_MSVC2012_64bit-Debug\debug\simpleKinectController exited with code 0
which means:
ERROR_INVALID_HANDLE 6 (0x6) The handle is invalid.
Which means that closeHandle ran anyway despite the tests. What tests should I do to prevent closing when the handle is not a valid HANDLE?
Bonus question: if I run the initializer this error will no longer appear when only closing colorFrameEvent, but will still appear when closing videoStreamHandle:
Starting C:\...\Qt\build-simpleKinectController-Desktop_Qt_5_0_2_MSVC2012_64bit-Debug\debug\simpleKinectController...
0
6
C:\...\Qt\build-simpleKinectController-Desktop_Qt_5_0_2_MSVC2012_64bit-Debug\debug\simpleKinectController exited with code 0
Do I need a diffent function to close a stream handler?
nui->NuiImageStreamOpen(...) does not create a valid Windows handle for the stream but instead it creates an internal handle inside the driver side.
So you can not use windows API to release/close stream handle !!!
To do that just call nui->NuiShutdown(). I have not yet used the callback event but I think its a valid windows handle and should be closed normally.
if you need just to change settings you can always call nui->NuiImageStreamOpen(...) with new settings. No need to shutdown ...
I would also welcome function nui->NuiImageStreamClose(...); because current state of API complicates things for long term running aps with changing sensor configurations.
CreateEvent (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx) returns NULL if an event was not created.
You are checking against INVALID_HANDLE_VALID which is not NULL.
You are probably trying to double-close a handle. That is likely to generate ERROR_INVALID_HANDLE 6. You can't detect this with your test, because the first CloseHandle(nextColorFrameEvent); did not change nextColorFrameEvent.
The solution is to use C++ techniques, in particular RAII. There are plenty of examples around how to use shared_ptr with HANDLE. shared_ptr is the standard solution to run cleanup code at most once, after everyone is done, and only if anybody actually allocated a resource.
there is a good way of debugging that I'm particularly fond of, despite being all writen in macros, which are nasty, but in this case they work wonders.
Zed's Awesome Debug Macros
there are a couple of things I like to change though. They make extensive use of goto, which I tend to avoid, specially in c++ projects, because otherwise you wouldn't be able to declare variables mid-code. This is why I use exit(-1) instead, or, in some projects, I mod the code to try, throw, catch c++. Since you are working with Handles, a good thing would be setting a variable and telling the program to close itself.
here is what I mean. Take this piece of code from the macros (i assume you would read the exercise and familiarize with the macros):
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
i'd change
goto error;
to something like
error = true;
the syntax inside the program would be something like, and I took it from a multithread program I'm writing myself:
pRSemaphore = CreateSemaphore(NULL, 0, MAX_TAM_ARQ, (LPCWSTR) "p_read_semaphore");
check(pRSemaphore, "Impossible to create semaphore: %d\n", GetLastError());
As you can see, GetLastError is only called when pRSemaphore is set to null. There are somewhat fancy mechanisms behind the macro (at least they are fancy for me), but they are hidden inside the "check" mask, so you needn't worry about them.
next step is to treat the error with something like:
inline void ExitWithError(bool &err) {
//close all handles
//tell other related process to do the same if necessary
exit(-1);
}
or you could just call it inside the macro like
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; ExitWithError(); }
hope I could be of any help
I'm trying to read the install path for an application, and I'm baffled at the behaviour I'm getting. First, here's the code that didn't work (formatted it a little so it doesn't take up a huge line):
LONG status = RegQueryValueEx(
hkRegistry,
"InstallPath",
0,
®Type, (LPBYTE)installPath,
®Size );
if (status == ERROR_SUCCESS) {
// Handle success.
}
I realized that it was failing on the call to RegQueryValueEx, so I decided to probe the return value by throwing it within an exception by adding:
else {
throw Exception( status );
}
But then... the code started to work and the call to RegQueryValueEx succeeded. I've been able to repeat this behaviour as long as I throw something within the else. If I comment out the body of the else, the error returns.
Edit: Okay, I tried calling MessageBox instead of an exception and I get the same behaviour. If I comment it out, it stops working again.
Is there a rational explanation for this?
It's possible that the buffer for installPath is too small compared to the value contained in regSize (which must be initialized to the size of the buffer).
If installPath is a stack-allocated value I suspect that it is overflown, causing the value of status to get overwritten.