C++/CLI: Access violation when debugging/stepping into code in 32-bit (VS-2015) - debugging

I got this strange issue when stepping into code when debugging a 32-bit mixed mode assembly. The stripped down version of the code looks like this:
public ref class FooClass {
public:
FooClass();
};
FooClass::FooClass(){
// Note: doesn't matter what code is in here, as long as it is native
char test[10];
memset((void*)test, 0, sizeof(test));
}
This class is then instantiated in another class:
FooClass^ BarClass::Test() {
FooClass^ addr = gcnew FooClass();
return addr;
}
..which again is instantiated in a C# console app:
class Program
{
static void Main(string[] args)
{
BarClass bar = new BarClass();
FooClass foo = bar.Test();
}
}
When stepping through the code, and into the FooClass constructor, I get an exception
(note: removed argument info for the sake of less mess):
ntdll.dll!_NtTraceEvent#16() Unknown
ntdll.dll!EtwpEventWriteFull() Unknown
ntdll.dll!_EtwEventWrite#20() Unknown
clrjit.dll!Compiler::lvaInitTypeRef() Line 253 C++
clrjit.dll!Compiler::compCompileHelper(...) Line 3489 C++
clrjit.dll!Compiler::compCompile(...) Line 3092 C++
clrjit.dll!jitNativeCode(...) Line 4063 C++
clrjit.dll!CILJit::compileMethod(...) Line 180 C++
[Managed to Native Transition]
> FooBar.dll!FooBar::BarClass::Test() Line 16 C++
ConsoleApp.exe!ConsoleApp.Program.Main(string[] args) Line 15 C#
However, if I just add breakpoints in the constructors and just run to next breakpoint, the code runs fine.
Also, when removing native code, it runs fine.
This issue does not occur in 64-bit mode. I crosschecked for settings, but can't really see anything special.
There are no 3rd party dll's, all the native code is compiled into the assembly.
This is not my first C++/CLI project, but first time I do it in VS2015.

From the comments in my original question, the following was suggested:
Enter Tools -> Options -> Debugging -> General
Enable the "Use Managed Compatibility Mode" checkbox
This fixed the issue.

In my case the issue was an exception in an internal managed component, that apparently did not propagate well to the native layer that invoked it - and manifested as exactly this impossible ETW stack.
To debug I had to attach as managed-only. The exception was staring me right in the face (missing DLL, but that's irrelevant).
Hope this helps someone out there.

Related

When running a Unity HoloLens program from Visual Studio, when an exception is thrown how do I get the line numbers in the stack trace?

Currently when an exception is thrown from within my Unity script while using my HoloLens the Debug Output in Visual Studio shows the stack trace without the line numbers.
How do I get the line numbers along with the stack trace? I'd be fine with it being logged somewhere else other than the Debug Output.
Here's some example output in Visual Studio:
Exception thrown: 'System.NullReferenceException' in Assembly-CSharp.dll
NullReferenceException: Object reference not set to an instance of an object.
at NewBehaviourScript.Update()
at NewBehaviourScript.$Invoke6Update(Int64 instance, Int64* args)
at UnityEngine.Internal.$MethodUtility.InvokeMethod(Int64 instance, Int64* args, IntPtr method)
(Filename: <Unknown> Line: 0)
And the corresponding Unity script (I made a Cube and attached a NewBehaviourScript component):
public class NewBehaviourScript : MonoBehaviour {
// Update is called once per frame
void Update ()
{
object a = null;
a.GetType();
}
}
I tried changing the build from Release to Debug doesn't give the line numbers.
I tried googling, and it looks like it's not showing the line numbers for others, as well: http://answers.unity3d.com/questions/1315985/null-reference-in-line-0.html
I tried asking on Microsoft's forums, but didn't receive any useful replies.
I don't think you would get the line number since it does not exist anymore. You get it in Unity editor because you are not running a full build of the application so Unity still has access to the non-compiled code. When you run on the device, it sends debug commands to the VS console about the printing and the errors but all the code is binary at that point, so there is no reason nor possibility to provide a line number.
Actually this is not specific to Hololens, but you would get the same in Android or iOS. Once build, the code is no longer the same, it does not even match one to one as the compiler performs optimizations.
What you can do is placed Debug commands to see where it happens.
public class NewBehaviourScript : MonoBehaviour {
// Update is called once per frame
void Update ()
{
object a = null;
#if DEBUG
if(a == null)
{
Debug.Log("[NewBehaviourScript] Running update with null a object");
}
#endif
a.GetType();
Debug.Log("[NewBeahviourScript] if this line prints, method did not crash");
}
}
In this example, you can use the DEBUG macros if you would have code running only for debug purpose. This way you can easily exclude it on export. The second call for Debug is not required in the macro since the build process will discard it when you set the build to Release or Master.

DirectX Windows 8.1 fstream won't load file

I'm building a Windows 8.1 DirectX app and trying to load in an external to store level data.
The relevant code currently is (this method is called in the AssetHandler constructor):
void AssetHandler::LoadLevelsData()
{
unsigned int i = 0;
std::string lineData;
this->currentFile.open("Assets/reg.txt");
//Below statement here purely to check if the blasted thing is opening
if (this->currentFile.is_open())
{
i++;
}
while (std::getline(this->currentFile, lineData))
{
levels[i] = lineData;
i++;
}
currentFile.close();
}
The problem that i'm having is that the file does not appear to be opening. I have tried:
Using a full path
Opening the file in the initialisation list
A breakpoint shows that it is jumping over the if and while
I found some information saying that DirectX has constraints on working with external files but it did not specify exactly what these were.
The Item Type was set to 'Does not participate in build'. Setting this value to 'Text' solved the problem.

Pointer object Creates a windows error in Visual C++ 6.0

I will paste a code snippet and explain the problem I am facing,
void materialPropertiesDlg::OnNext() {
contiBeam *continousBeamPtr;
contiBeam contiBeamObj;
UpdateData(TRUE);
switch (m_steel_grade) {
// Do Something
}
continousBeamPtr->setMaterial(m_conc_grade, m_steel_grade);
OnOK();
}
As you see, in line 2 a pointer object is created and in the next line an object is created. So, then I call the member function setMaterials() of the class contiBeam. I can easily do that with the object contiBeamObj, but when I call the function using contiBeamPointer, the windows throws an error which reads
Application Has Stopped working.
I am able to do the needful, I just want to know what could be the possible reason for this?
You are using your pointer contiBeam *continousBeamPtr; without having allocated it.
That is Undefined Behaviour and will make your application crash.
You should allocate (reserve memory for) your pointer by using new, like so:
contiBeam *continousBeamPtr = new contiBeam;
However, the ultimate question is, why are you using a pointer in the first place? Do you need one? Doesn't look like it from the code you posted.

Including DirectShow library into Qt for video thumbnail

I'm trying to implement http://msdn.microsoft.com/en-us/library/dd377634%28v=VS.85%29.aspx on Qt, to generate a poster frame/thumbnail for video files.
I have installed both Windows Vista and Windows 7 SDK. I put:
#include "qedit.h"
in my code (noting there is also one in C:\Qt\2010.04\mingw\include), I add:
win32:INCLUDEPATH += $$quote(C:/WindowsSDK/v6.0/Include)
to my *.pro file. I compile and get " error: sal.h: No such file or directory". Finding this in VC++ I add
win32:INCLUDEPATH += $$quote(C:/Program Files/Microsoft Visual Studio 10.0/VC/include)
And now have 1400 compile errors. So, I abandon that and just add:
win32:LIBS += C:/WindowsSDK/v7.1/Lib/strmiids.lib
to my *.pro file and try to run (without including any headers):
IMediaDet mediadet;
But then I get "error: IMediaDet: No such file or directory".
#include "qedit.h"
gives me the same error (it looks like it's pointing to the Qt version) and
#include "C:/WindowsSDK/v6.0/Include/qedit.h"
goes back to generating 1000's of compile errors.
Sigh, so much trouble for what should be 10 lines of code...
Thanks for your comments and help
Since you say you are "a C++/Qt newbie" then I suspect that the real issue may be that you are attempting to load the library yourself rather than simply linking your application to it?
To link an external library into your application with Qt all you need to do is modify the appropriate .pro file. For example if the library is called libfoo.dll you just add
LIBS += -L/path/to/lib -lfoo
You can find more information about this in the relevant section of the qmake manual. Note that qmake commonly employs Unix-like notation and transparently does the right thing on Windows.
Having done this you can include the library's headers and use whatever classes and functions it provides. Note that you can also modify the project file to append an include path to help pick up the headers eg.
INCLUDEPATH += /path/to/headers
Again, more information in the relevant section of the qmake manual.
Note that both these project variables work with relative paths and will happily work with .. to mean "go up a directory" on all platforms.
Note that qedit.h requires dxtrans.h, which is part of DirectX9 SDK.
You can find dxtrans.h in DirectX SDK from August 2006. Note that dxtrans.h is removed from newer DirectX SDKs.
Do you have access to the source of the external library? The following assumes that you do.
What I do when I need to extract a class from a library with only functions resolved, is to use a factory function in the library.
// Library.h
class SomeClass {
public:
SomeClass(std::string name);
// ... class declaration goes here
};
In the cpp file, I use a proxy function outside the extern "C" when my constructor requires C++ parameters (e.g. types such as std::string), which I pass as a pointer to prevent the compiler from messing up the signature between C and C++. You can avoid the extra step if your constructor doesn't require parameters, and call new SomeClass() directly from the exported function.
// Library.cpp
#include "Library.h"
SomeClass::SomeClass(std::string name)
{
// implementation details
}
// Proxy function to handle C++ types
SomeClass *ImplCreateClass(std::string* name) { return new SomeClass(*name); }
extern "C"
{
// Notice the pass-by-pointer for C++ types
SomeClass *CreateClass(std::string* name) { return ImplCreateClass(name); }
}
Then, in the application that uses the library :
// Application.cpp
#include "Library.h"
typedef SomeClass* (*FactoryFunction)(std::string*);
// ...
QLibrary library(QString("MyLibrary"));
FactoryFunction factory = reinterpret_cast(library.resolve("CreateClass"));
std::string name("foobar");
SomeClass *myInstance = factory(&name);
You now hold an instance of the class declared in the library.

Break when a value changes using the Visual Studio debugger

Is there a way to place a watch on variable and only have Visual Studio break when that value changes?
It would make it so much easier to find tricky state issues.
Can this be done?
Breakpoint conditions still need a breakpoint set, and I'd rather set a watch and let Visual Studio set the breakpoints at state changes.
In the Visual Studio 2005 menu:
Debug -> New Breakpoint -> New Data Breakpoint
Enter:
&myVariable
You can also choose to break explicitly in code:
// Assuming C#
if (condition)
{
System.Diagnostics.Debugger.Break();
}
From MSDN:
Debugger.Break:
If no debugger is attached, users are
asked if they want to attach a
debugger. If yes, the debugger is
started. If a debugger is attached,
the debugger is signaled with a user
breakpoint event, and the debugger
suspends execution of the process just
as if a debugger breakpoint had been
hit.
This is only a fallback, though. Setting a conditional breakpoint in Visual Studio, as described in other comments, is a better choice.
In Visual Studio 2015, you can place a breakpoint on the set accessor of an Auto-Implemented Property and the debugger will break when the property is updated
public bool IsUpdated
{
get;
set; //set breakpoint on this line
}
Update
Alternatively; #AbdulRaufMujahid has pointed out in the comments that if the auto implemented property is on a single line, you can position your cursor at the get; or set; and hit F9 and a breakpoint will be placed accordingly. Nice!
public bool IsUpdated { get; set; }
Imagine you have a class called A with the following declaration.
class A
{
public:
A();
private:
int m_value;
};
You want the program to stop when someone modifies the value of "m_value".
Go to the class definition and put a breakpoint in the constructor of A.
A::A()
{
... // set breakpoint here
}
Once we stopped the program:
Debug -> New Breakpoint -> New Data Breakpoint ...
Address: &(this->m_value)
Byte Count: 4 (Because int has 4 bytes)
Now, we can resume the program. The debugger will stop when the value is changed.
You can do the same with inherited classes or compound classes.
class B
{
private:
A m_a;
};
Address: &(this->m_a.m_value)
If you don't know the number of bytes of the variable you want to inspect, you can use the sizeof operator.
For example:
// to know the size of the word processor,
// if you want to inspect a pointer.
int wordTam = sizeof (void* );
If you look at the "Call stack" you can see the function that changed the value of the variable.
Change the variable into a property and add a breakpoint in the set method. Example:
private bool m_Var = false;
protected bool var
{
get {
return m_var;
}
set {
m_var = value;
}
}
Update in 2019:
This is now officially supported in Visual Studio 2019 Preview 2 for .Net Core 3.0 or higher. Of course, you may have to put some thoughts in potential risks of using a Preview version of IDE. I imagine in the near future this will be included in the official Visual Studio.
https://blogs.msdn.microsoft.com/visualstudio/2019/02/12/break-when-value-changes-data-breakpoints-for-net-core-in-visual-studio-2019/
Fortunately, data breakpoints are no longer a C++ exclusive because they are now available for .NET Core (3.0 or higher) in Visual Studio 2019 Preview 2!
If you are using WPF, there is an awesome tool : WPF Inspector.
It attaches itself to a WPF app and display the full tree of controls with the all properties, an it allows you (amongst other things) to break on any property change.
But sadly I didn't find any tool that would allow you to do the same with ANY property or variable.
I remember the way you described it using Visual Basic 6.0. In Visual Studio, the only way I have found so far is by specifying a breakpoint condition.
Right click on the breakpoint works fine for me (though mostly I am using it for conditional breakpoints on specific variable values. Even breaking on expressions involving a thread name works which is very useful if you're trying to spot threading issues).
As Peter Mortensen wrote:
In the Visual Studio 2005 menu:
Debug -> New Breakpoint -> New Data Breakpoint
Enter: &myVariable
Additional information:
Obviously, the system must know which address in memory to watch.
So
- set a normal breakpoint to the initialisation of myVariable (or myClass.m_Variable)
- run the system and wait till it stops at that breakpoint.
- Now the Menu entry is enabled, and you can watch the variable by entering &myVariable,
or the instance by entering &myClass.m_Variable. Now the addresses are well defined.
Sorry when I did things wrong by explaining an already given solution. But I could not add a comment, and there has been some comments regarding this.
You can use a memory watchpoint in unmanaged code. Not sure if these are available in managed code though.
You can probably make a clever use of the DebugBreak() function.
You can optionally overload the = operator for the variable and can put the breakpoint inside the overloaded function on specific condition.

Resources