Unhandled Exception??

Feb 20, 2020 at 6:50pm
Heyo, i have been following a tutorial on graphics in C++, i keep getting an error that is : 'An unhandled exception was encountered during a user callback'. i checked all the code and it is identical to the dudes. i tried finding a solution online, figuring out what the hell it is, but so far unsuccesful.

Was wondering if anyone could explain what it is so i can fix it.
The code:

(error is on 'm_vs->Release')

#include "VertexShader.h"
#include "GraphicsEngine.h"

VertexShader::VertexShader()
{
}

void VertexShader::release()
{
m_vs->Release();
delete this;

}


bool VertexShader::init(const void* shader_byte_code, size_t byte_code_size)
{
if (!SUCCEEDED(GraphicsEngine::get()->m_d3d_device->CreateVertexShader(shader_byte_code, byte_code_size, nullptr, &m_vs)))
return false;
return true;
}

VertexShader::~VertexShader()
{
}

Thanks :)
Feb 20, 2020 at 7:05pm
1. Where/how is m_vs initialized?
2. What type is m_vs?
3. What is inside Release()?
4.
delete this;
I'm not sure if you want to be doing this. How are you creating your VertexShader object?
Last edited on Feb 20, 2020 at 7:09pm
Feb 20, 2020 at 7:12pm
m_vs is part of :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
{
#include "AppWindow.h"

struct vec3
{
	float x, y, z;
};

struct vertex
{
	vec3 position;
	vec3 color;
};

AppWindow::AppWindow()
{
}

AppWindow::~AppWindow()
{
}

void AppWindow::onCreate()
{

	Window::onCreate();
	GraphicsEngine::get()->init();
	m_swap_chain  = GraphicsEngine::get()->createSwapChain();

	RECT rc = this->getClientWindowRect();
	m_swap_chain->init(this->m_hwnd, rc.right - rc.left, rc.bottom - rc.top);

	vertex list[] =
	{
		// X - Y - Z //
		{-0.5f, -0.5f, 0.0f,  1,0,0 }, // POS 1 //
		{-0.5f,  0.5f, 0.0f,  0,1,0 }, // POS 2 //
		{ 0.5f, -0.5f, 0.0f,  0,0,1 }, // POS 2 //
	    { 0.5f, -0.5f, 0.0f,  1,1,0 }
	};

	m_vb = GraphicsEngine::get()->createVertexBuffer();
	UINT size_list = ARRAYSIZE(list);


	void* shader_byte_code = nullptr;
	size_t size_shader = 0;

	GraphicsEngine::get()->compileVertexShader(L"VertexShader.hlsl", "vsmain", &shader_byte_code, &size_shader);

	m_vs = GraphicsEngine::get()->createVertexShader(shader_byte_code, size_shader);
	m_vb->load(list, sizeof(vertex), size_list, shader_byte_code, size_shader);

	GraphicsEngine::get()->releaseCompiledShader();


	GraphicsEngine::get()->compilePixelShader(L"VPixelShader.hlsl", "psmain", &shader_byte_code, &size_shader);

	m_ps = GraphicsEngine::get()->createPixelShader(shader_byte_code, size_shader);

	GraphicsEngine::get()->releaseCompiledShader();

}

void AppWindow::onUpdate()
{
	Window::onUpdate();
	// CLEAR THE RENDER TARGET //
	GraphicsEngine::get()->getImmediateDeviceContext()->clearRenderTargetColor(this->m_swap_chain,
		0, 0.3f, 0.4f, 1);
	// SET VIEWPORT OF RENDER TARGET IN WHICH E HAVE TO DRAW //
	RECT rc = this->getClientWindowRect();
	GraphicsEngine::get()->getImmediateDeviceContext()->setViewportSize(rc.right - rc.left, rc.bottom - rc.top);
	// SET DEFAULT SHADER IN THE GRAPHICS PIPELINE TO BE ABLE TO DRAW //

	GraphicsEngine::get()->getImmediateDeviceContext()->setVertexShader(m_vs);
	GraphicsEngine::get()->getImmediateDeviceContext()->setPixelShader(m_ps);

	// SET THE VERTICES OF THE TRAINGLETO DRAW //
	GraphicsEngine::get()->getImmediateDeviceContext()->setVertexBuffer(m_vb);


	// FINALLY DRAW THE TRIANGLE //
	GraphicsEngine::get()->getImmediateDeviceContext()->drawTriangleList(m_vb->getSizeVertexList(), 0);
	m_swap_chain->present(true);
}

void AppWindow::onDestroy()
{

	Window::onDestroy();
	m_vb->release();
	m_swap_chain->release();
	m_vs->release();
	m_ps->release();
	GraphicsEngine::get()->release();

}

}


i think..
and m_vs is a nullptr
and release is mentioned in the header files classes, as in, void release()
and VertexShader is a class, in a header file



Last edited on Feb 20, 2020 at 9:08pm
Feb 20, 2020 at 8:01pm
Please use code format tags. Edit your post and type [code] {your code here} [/code].

I still don't see what type m_vs is. But regardless, I don't ever see VertexShader::init being called anywhere. It looks like VertexShader::init is what is modifying m_vs to put it in a valid state. If that isn't happening, then the worst case is that m_vs is a junk pointer (not necessarily a null pointer).

and release is mentioned in the header files classes, as in, void release()
It's two different functions by the looks of it. You have your VertexShader::release() function, but then you also call m_vs->Release();.
Notice the difference in capitalization.

______________________________________

So, in other words, you need to debug your code to figure out if your VertexShader::init() function is ever being hit, and also I would make sure the return value of VertexShader::init is true.

It also couldn't hurt to explicitly set m_vs as a nullptr in the VertexShader constructor.
Last edited on Feb 20, 2020 at 8:03pm
Feb 20, 2020 at 9:49pm
alright well,

VertexShader init function is mentioned in graphicsEngine.cpp:


1
2
3
4
5
6
7
8
9
10
11
12
13
{
VertexShader* GraphicsEngine::createVertexShader(const void* shader_byte_code, size_t byte_code_size)
{
	VertexShader* vs = new VertexShader();

	if (!vs->init(shader_byte_code, byte_code_size))
	{
		vs->release();
		return nullptr;
	}
	return vs;
}
}


and init() does return true within a condition:

1
2
3
4
5
6
7
8
{
bool VertexShader::init(const void* shader_byte_code, size_t byte_code_size)
{
	if (!SUCCEEDED(GraphicsEngine::get()->m_d3d_device->CreateVertexShader(shader_byte_code, byte_code_size, nullptr, &m_vs)))
		return false;
	return true;
}
}


maybe it is a junk pointer?

Feb 20, 2020 at 10:02pm
This is very confusing to discuss, because you have multiple functions that only differ by capitalization.

You're saying that when you debug, the call to the function bool VertexShader::init(const void* shader_byte_code, size_t byte_code_size) is returning true?

Well, hypothetically, let's say this branch is being entered:
1
2
3
4
5
	if (!vs->init(shader_byte_code, byte_code_size))
	{
		vs->release();
		return nullptr;
	}


Your new'd VertexShader is created. This is calling your constructor:
1
2
3
VertexShader::VertexShader()
{
}

Nothing is initialized inside your constructor, so m_vs, which is presumably a member variable inside your VertexShader class, is going to contain junk.

Afterwards, vs->release(); is called. This attempts to call m_vs->Release();, which is illegal to do if m_vs is null or a junk pointer.

Not sure if this is really a "fix"; rather it's putting a band-aid over the design of your code, but something like:
1
2
3
4
5
6
7
8
9
10
VertexShader::VertexShader()
: m_vs(nullptr)
{
}

void VertexShader::release()
{
    if (m_vs) m_vs->Release();
    delete this;
}

will at least prevent the junk dereference.
Last edited on Feb 20, 2020 at 10:05pm
Feb 20, 2020 at 10:43pm
it helped!
but, it throws a similar error in deviceContext.cpp:

1
2
3
4
5
6
7
8
{
void DeviceContext::setVertexShader(VertexShader* vertex_shader)
{

	m_device_context->VSSetShader(vertex_shader->m_vs, nullptr, 0);

}
}


error being: Unhandled exception thrown: read access violation.
vertex_shader was nullptr.

its linked to the previous error, right?

why does it come up with this error, if vertex_shader->m_vs can be nothing else but a NULL?

Feb 20, 2020 at 10:51pm
vertex_shader was nullptr.
why does it come up with this error, if vertex_shader->m_vs can be nothing else but a NULL?

"vertex_shader->m_vs" is not what is null. "vertex_shader->m_vs" does not 'exist' in this case.
vertex_shader itself is what is null, and you're attempting to dereference this.

Whatever is happening, it's not creating your vertex shader correctly. Your createVertexShader() call is presumably returning null. This should be checked for to prevent null dereferences.

You need to figure out why m_d3d_device->CreateVertexShader(...) is generating an error. That's the source of your troubles.

Direct3D return codes are more than just pass/fail, they can give hints as to what is going wrong.
I'm not sure how much information it will give, but it might help.
See: https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d11-graphics-reference-returnvalues
Last edited on Feb 20, 2020 at 10:56pm
Topic archived. No new replies allowed.