I try to show an exception (or error code) in C++ with visual studio 2017 when a crash occurs.
For example, the following codes does not show any dialog(message box).
int* p = 0;
*p = 10;
or
throw std::exception("some error");
Thus, I cannot attach it with just in time debugger.
In fact, the second code shows a dialog but it is not what I want.
UPDATE
Windows 10 does not support the WER dialog any more. - link
(link is provided by Hans Passant)
Undefined.
You should also note:
If the given example is complete (no further use of p), an exception might occur, but in release mode the code may be optimized. In this case, there would be no message at all.
Related
I have a cross-platform build. On a *nix platform using GCC, I use the __attribute__((warn_unused_result)) to notify the consumer of my API if a return value is not checked. I assumed that _Check_return does the same thing on MSVC, but it doesn't appear to be working the way I expect.
The following code does not produce a warning as I expect. Warnings are set to /Wall.
_Check_return_ _Must_inspect_result_ int foo()
{
return 100;
}
int main()
{
foo();
return 0;
}
Code compiles without warnings. What am I doing wrong (or what should I be using to generate warnings for unchecked return codes)?
SAL annotations like _Check_return_ and _Must_inspect_result_ are only checked during code analysis builds (either by starting a code analysis build in the IDE or by building with the /analyze flag on the command line).
See "Understanding SAL" on MSDN for more information.
I trigger an c# application by an custom action:
On failing condition, my application tells Install Shield to abort the installation process using an exit code:
static void Main(string[] args)
{
if(false)
{
Environment.ExitCode = 1;
}
}
Using this approach, Install shield´s setup displays an error message like expected:
How can I overwrite that error message by a custom text?
Reading between the lines here, it appears your custom action launches an EXE. If that is so, there is no way to do what you ask. You could show a message from your EXE before returning a non-zero exit code, but then Windows Installer would still show the Error 1722 message.
If you can instead run a function from a DLL, you have more options. Instead of returning errors, you'd be able to set properties (assuming this is an immediate mode action), and could use those properties to do further things, such as show another dialog, or exit the installation without the Error 1722 message. I don't think all the necessary configuration options are available in the limited edition - you certainly cannot edit dialogs in LE - so to do all of that, you would have to change to a more capable tool (including the Professional edition, or options from other vendors).
I'm trying to create a new Visual Studio project type following the tutorial:
http://msdn.microsoft.com/en-us/library/vstudio/cc512961.aspx
Unfortunately I'm getting a strange exception stating that "Guid should contain 32 digits and 4 dashes".
The error appears somewhere along the lines:
// Launch the aggregate creation process (we should be called back on our
IVsAggregatableProjectFactoryCorrected implementation)
IVsCreateAggregateProject aggregateProjectFactory =IVsCreateAggregateProject)this.Site.GetService(typeof(SVsCreateAggregateProject));
int hr = aggregateProjectFactory.CreateAggregateProject(guidsList, fileName, location, name, flags, ref projectGuid, out project);
if(hr == VSConstants.E_ABORT)
canceled = 1;
ErrorHandler.ThrowOnFailure(hr);
I 've got no idea what I'm doing wrong and how to debug this. ErrorHandler just throws exception.
I've created very simple Visual Studio Add-in, ala this article by JP Booodhoo.
http://codebetter.com/jpboodhoo/2007/09/04/macro-to-aid-bdd-test-naming-style/
The addin works in debug, so if I F5 in the add in solution, and open a solution then the addin shows in the tools. However, it doesn't show when not debugging. i.e. after I've deployed the addin, closed and re-opened my solution.
Am I missing something?
In terms of deployment, I followed the deployment steps in this article and deployed it to C:\Users[your user name]\Documents\Visual Studio 2012\Addins
Alternative to macros in Visual Studio 2012
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
handled = false;
if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if(commandName == "KinghamExtensions.Connect.KinghamExtensions")
{
var selection = (TextSelection)(_applicationObject.ActiveDocument.Selection);
selection.SelectLine();
if (selection.Text == "") return;
var prefix = "public void ";
var index = selection.Text.IndexOf(prefix);
prefix = selection.Text.Substring(0, index) + prefix;
var description = selection.Text.Replace(prefix, String.Empty);
selection.Text = prefix + description.Replace(" ", "_").Replace("'", "_");
selection.LineDown();
selection.EndOfLine();
handled = true;
}
}
}
As I say, the code works when running the addin from vs in debug, but doesn't show in the tools menu.
Also, it doesn't show up in the keyboard options like the Git Extensions addin does meaning I can't assign a key binding.
Any thoughts?
It is hard to answer by the information you given, but at first you should check the followings:
Your AddIn should appear in the Tools>Add-in Managger...
If you set the first check box before it, than it should be loaded.
If it isn't and you get an error message, click to no, else the Studio will rename the deployed .AddIn file.
You should check if your release assembly is at the place referenced by the Assembly element like this: <Assembly>C:\Users[your user name]\Documents\Visual Studio 2012\Projects\MyAddin1\MyAddin1\bin\MyAddin1.dll</Assembly>
in the .AddIn file deployed by Visual Studio to the AddIn folder you mentioned in your question.
If it is, and the error pesrists, you should add some log to your Add-In (a Windows MessageBox will do)
and place it to the OnConnection method. The error can appear either OnConnection throws an Exception while the IDE trying to load it, or the FullClassName element in the AddIn file refers to an other name than your Connection class has.
If you get no errors and your OnConnection runs properly, then it could be an exception thrown while your code is adding your command, - if you do the same way as it is in a generated Add-In template in a try/catch block- and you need to resolve it.
Visual C++ 6.0 is not supported on Windows 8, but we have a couple of legacy apps that still needs to be compiled with Visual C++ 6.0. :-(
It is possible to install Visual C++ 6.0 on Windows 8 by unchecking Data Access -> Change Options -> ADO, RDS and OLE DB Providers. See this SU-question and this thread. You also need to install SP6 afterwards.
Visual C++ 6.0 works perfectly on one computer, but two others cannot use the debugger. The same hardware, same version of Windows, same person doing the installation, same project. There must be some difference...
On the computers with the problem you can set a break point and the debugger will break into the IDE, but when you try do step, step into or run the code will crash with Unhandled exception in EXENAME.EXE (OLE32.DLL): 0xC0000005: Access Violation.
Walter Oney reports the exact same problem on MSDN forums, but they have no solution as VC++ 6.0 is unsupported.
As we have Visual C++ 6.0 working on one Win8 computer there is apparently way to do it. Any ideas on what the difference could be?
Turning off OLE RPC debugging (Tools / Options / Debug) works for me (Windows 8 Pro 64 bit, Visual C++ 6.0 with SP6). This solution was suggested (later) within the above-mentioned MSDN forum thread.
I was eventually able to get VS 6 working on Win 8 and Win 10. The basic steps were these:
Create a dummy file named msjava.dll in \Windows. (E.g., "echo >msjava.dll") Without this step, the VS 6 installer can't get very far.
Install VS 6 and SP 6.
Rename MSDEV.EXE to something else, such as MSDEVQ.EXE.
Create a compatibility database for MSDEVQ that excludes the fault-tolerant heap shim. Without this step, debugging a program that makes heavy use of HeapAlloc, etc., is excruciatingly slow.
For debugging, ensure that a breakpoint is tripped before any calls to OLE32 can occur. I include the following header early in the main program or (for an MFC app) the InitInstance function:
X64DebugHack.h:
#ifdef _DEBUG
// In order to be able to debug this application on x64, we need to single
// step across at least one statement before ole32.dll gets loaded. So
// always leave this breakpoint in place.
requiredbreakpoint:
int junkola = 42;
// Check to see that there was a breakpoint...
PUCHAR pjunk;
_asm lea eax, requiredbreakpoint
_asm mov pjunk, eax
if (*pjunk != 0xCC)
AfxMessageBox("Required breakpoint was not set prior to loading OLE32.DLL -- single stepping will not be possible during this debugging session.", MB_OK | MB_ICONHAND, 0);
LoadLibrary("OLE32");
#endif
Write an extension DLL that provides a "Stop Debugging" button. The extension has to search and destroy debug handles, which have a different handle type in Win64 than in Win32. The mechanics of writing the extension are beyond the scope of this forum, but the code that does the actual work is here:
CCommands::HelpAssistantKill:
typedef LONG NTSTATUS;
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
enum SYSTEM_INFORMATION_CLASS {
SystemHandleInformation = 16,
};
typedef NTSTATUS(NTAPI *PNTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef struct _SYSTEM_HANDLE_INFORMATION_DATA {
ULONG HandleCount;
SYSTEM_HANDLE_INFORMATION HandleInformation[1];
} SYSTEM_HANDLE_INFORMATION_DATA, *PSYSTEM_HANDLE_INFORMATION_DATA;
#define HANDLE_TYPE_DEBUG_OBJECT 11 // correct value for Win8 x64
STDMETHODIMP CCommands::HelpAssistantKill()
{ // CCommands::HelpAssistantKill
AFX_MANAGE_STATE(AfxGetStaticModuleState());
BOOL didit = FALSE;
HMODULE hDll = NULL;
PSYSTEM_HANDLE_INFORMATION_DATA phi = NULL;
do { // do once
HRESULT hr;
// Locate NtQuerySystemInformation within NTDLL.DLL
hDll = LoadLibrary("NTDLL");
if (!hDll)
break;
PNTQUERYSYSTEMINFORMATION NtQuerySystemInformation = (PNTQUERYSYSTEMINFORMATION) GetProcAddress(hDll, "NtQuerySystemInformation");
if (!NtQuerySystemInformation)
break;
// Do an initial query to get the number of handles presently open in the system.
// This is a large number. The returned length value is meaningless for this query.
SYSTEM_HANDLE_INFORMATION_DATA hid;
DWORD junk;
NTSTATUS status = (*NtQuerySystemInformation)(SystemHandleInformation, &hid, sizeof(hid), &junk);
if (!NT_SUCCESS(status) && status != STATUS_INFO_LENGTH_MISMATCH)
break;
ULONG length = sizeof(SYSTEM_HANDLE_INFORMATION_DATA) + (hid.HandleCount - 1) * sizeof(SYSTEM_HANDLE_INFORMATION);
phi = (PSYSTEM_HANDLE_INFORMATION_DATA) new UCHAR[length];
if (!phi)
break;
// Get a list of all handles open in the system
status = (*NtQuerySystemInformation)(SystemHandleInformation, phi, length, &junk);
if (!NT_SUCCESS(status))
break;
// Find and close any debug objects that are open in this instance of Visual Studio.
DWORD pid = GetCurrentProcessId();
ULONG ihandle;
for (ihandle = 0; ihandle < hid.HandleCount; ++ihandle)
{ // for each open handle
PSYSTEM_HANDLE_INFORMATION p = phi->HandleInformation + ihandle;
if (p->ProcessId != pid || p->ObjectTypeNumber != HANDLE_TYPE_DEBUG_OBJECT)
continue;
if (CloseHandle((HANDLE) p->Handle))
didit = TRUE;
} // for each open handle
// Instruct DevStudio to stop
BSTR bsStopDebugging = SysAllocString(L"DebugStopDebugging");
if (!bsStopDebugging)
break;
hr = m_pApplication->ExecuteCommand(bsStopDebugging);
SysFreeString(bsStopDebugging);
if (hr != 0)
break;
} // do once
while (FALSE);
if (phi)
delete[] phi;
if (hDll)
FreeLibrary(hDll);
if (!didit)
{ // didn't do anything
MessageBox(NULL, "Unable to find and close any debug object handles", "HelpAssistant", MB_OK | MB_ICONINFORMATION);
} // didn't do anything
return S_OK;
} // CCommands::HelpAssistantKill
This felt like a pretty heroic effort, but I had about a million lines of code built on VS 6 that I had to keep working. Now that I've built myself a workable macro processor for VS 2015, I may undertake a conversion of this application.
One wrinkle -- I had the very same same issue with the Visual C++ 6.0 debugger on Windows 8.1 . But I could not find the RPC debug option under the Tools/Options/ Debug option described in the answer above. Instead I had to go into the registry editor and delete the RPC Debug key that is mentioned in the same MSDN thread referenced above (maybe it was there because I had already installed later versions of Microsoft Visual Studio before I had installed 6.0) . The debugger works great now, and thanks to previous posters!
The issue is due to incompatible “ADO, RDS and OLE DB Providers” comes along with the Visual C++ 6.0.
Please follow the below mentioned steps to disable ADO, RDS and OLE DB Providers and install the Visual C++ 6.0 –
1) Start the installation as usual.
2) Click on Custom installation when installer will ask for type of installation.
3) Click on Data Access from available items and then click on ‘Change Option’.
4) In new window de-select “ADO, RDS and OLE DB Providers” and click OK (ignore the warning).
5) Click on continue to proceed with the installation.
6) Installer will not freeze during ‘Updating components’ and will install successfully.
7) Now install the service pack ‘Vs6sp6’ and it will also install successfully.
Non of above answers work for me.
Solution from this site fix my problem.
Re-register ole32.dll file and check if it helps.
Click Start, type cmd in the Start search.
Right click on cmd and click on Run as administrator.
In the Command prompt, type the following commands and hit ENTER
after each command.
takeown /f ole32.dll
regsvr32 ole32.dll
Close the Command prompt after running the above two commands.
Try to run the application and check is the issue persists.