I have a crash that is caught in Sentry.
CWnd::IsWindowVisible
Unhandled
Fatal Error: EXCEPTION_ACCESS_VIOLATION_READ
I downloaded the mini dump file (dmp) and ran through Visual Studio 19. The crash is occurring in the method:
BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
I'm including a screen shot because one of my questions is:
Where exactly is the crash? Is the line (screenshot) really representing the crash?
Using the debugger I can see that the parameter message coming into the method is 275 which is
0113 275 WM_TIMER
See for example: https://wiki.winehq.org/List_Of_Windows_Messages.
My questions:
Where exactly is the crash? I don't see how checking for pResult being NULL and assigning lResult to *pResult could cause a crash of any kind and certainly not EXCEPTION_ACCESS_VIOLATION_READ
In anticipation of somebody stating that the exception is actually elsewhere...
a. How do I get the exact location/problem from the dump
b. Anyone recognize this type of problem with TIMERS? It's not my code, but I'm already imagining such things as multiple stops of timers, doing something to a Window that no longer exists, etc. Based on EXCEPTION_ACCESS_VIOLATION_READ
Any clues/ideas how to proceed?
As always, if better asked in another group, or more clarification needed, please let me know.
And Thanks!
EDIT - ADDITIONAL INFO
Note that Sentry says the program is actually crashing on IsWindowVisible. That certainly isn't present in debugging the dump file (that I can see) and the point of crash as shown by the screen shot doesn't show it, but it might make sense. The OnTimer routine certainly mentions IsWindowVisible().
4. Can IsWindowVisible() crash with EXCEPTION_ACCESS_VIOLATION_READ ?
Related
The Windows API CopyFile function is rather straightforward:
BOOL CopyFileW(
[in] LPCWSTR lpExistingFileName,
[in] LPCWSTR lpNewFileName,
[in] BOOL bFailIfExists
);
...
If the function fails, the return value is zero. To get extended error
information, call GetLastError.
However, I found this gem in our C++ source code, dating back to Oct / 2006:
try { //Exception, if the file already exists and is write protected
bCopyOK = CopyFile(csSourceFile, csDestinationFile, bFailIfExists);
} catch (...) {
bCopyOK = FALSE;
}
I even found the old ticket title (of course without details): "function 'CopyFile' throws Exception if Destination is write protected, catch Exception" :-)
Even today we still compile with /EHa, so this would have caught any SEH exceptions raised.
Now, at this point in time we would've been using Visual Studio 6 on Windows XP, and that one had all kinds of quirks, but still: I have a hard time imagining this function ever raising an exception (apart from invalid/null parameters and such).
Does or DID Win32 CopyFile(W) ever raise a (SEH) exception?
NO.
at first not exist SEH exceptions at all. SEH this is type of exception handler but not type of exception. another type of handlers (not exceptions) is VEH.
exception can be raised or via invoke RaiseException /RtlRaiseException / ZwRaiseException or by CPU. of course CPU exception alwas can be raised (in case lpExistingFileName or lpNewFileName for instanse point to invalid memory ) but CopyFileW never call RaiseException - by fact and by documentation.
//Exception, if the file already exists and is write protected
so in what problem ? create write protected file lpNewFileName and call CopyFile and test result. will be exception or error code returned
// Self answer, with historical perspective.
It is not documented to throw exceptions, as is apparent from the current docs linked above.
Both the other answer and also, e.g. Do DeleteFile() Or CopyFile() throw exceptions? quite definitely assert that there should be no exception being raised.
However, as is mentioned in comments:
Very few API calls are documented to raise SEH exceptions, but that
doesn't mean that they won't, or prevent SEH exceptions raised in
foreign code from passing through.
and in the linked question:
comment: ... Some odds that getting rid of the installed anti-malware product can rescue it, ymmv. ...
A: It was ... corporate info safety system, anti-malware like product.
It is very well possible that the original developer could actually reproduce this behavior on his machine, and swallowing the error "fixed" it well enough back then.
Things have improved since then. Given that no reproduction is possible in current code, and given that this only works with /EHa anyways, the try-catch is a candidate for cleanup.
I found strange Visual Studio 2010 behavior while debugging project. Variable string s was initialized with "", but debugger shows garbage. Debug point is in the second line of s initialization.
if I do cout<<s, it prints normal value - not garbage.
One more immage to be shure where is breakpoint
In other project places debugger works fine. Procedure where I have garbage is win message handler.
Message was transmitted from same project other thread.
LRESULT CMainWindow::OnMessageAuthorise(WPARAM wParam, LPARAM lParam)
{
string s= "";
...
}
What is wron?
UPD:
Problem is in profile Debug/Release selection. If I choose Release I have these garbage on variables. Why it is so?
Short answer: unless you're willing to inspect disassembly, you can't set watches in release builds. That's what debug builds are for.
Longer answer: In release builds many optimizations can make the mapping of a variable name to a memory address much harder. The simplest case - the variable might have no memory address: it can be saved only in registers. Traditional generation of PDB files (the files that hold - among others - this mapping info) didn't even try to cope with the difficulties emanating from optimizations, but since VS2012 a new switch takes a substantial step in that direction.
I'm playing around with SetWindowsHookEx, specifically I would like be able to find out about any window (on my desktop) thats been activated, via mouse or keyboard.
Reading through MSDN docs for SetWindowsHookEx it would appear that a WH_CBT type would do the job. I've created a dll and put all the code in there, which I control from a gui app (which also handles the unhook).
BUT I only appear to be getting the activation code when I activate my gui app though, any other app I activate is ignored.
In my dll I have the setup code and the CBTProc like so:
LRESULT WINAPI CBTProc(int Code, WPARAM W, LPARAM L) {
if(Code<0) CallN....
if (Code == HCBT_ACTIVATE) { // never get unless I activate my app
HWND a = reinterpret_cast<HWND>(W);
TRACE("this window was activated %d\n", a);
}
CallNext....
}
EXPORTED HHOOK WINAPI Setup(HWND MyWind) {
...
// gDllUInstance set in dllmain
return SetWindowsHookEx(WH_CBT, CBTProc, gDllUInstance, 0);
}
All pretty simple stuff, i've tried moving the setup out of the dll but I still get the same effect.
It would appear that the dll is getting loaded into other processes, I'm counting the number of DLL_PROCESS_ATTACHs I'm getting and can see its going up (not very scientific i know.
NOTE that this is 32 bit code running on 32bit OS - win2k3.
Are my expectations of the hooking mechanism wrong? should I only be getting the activation of my app or do I need a different type of hook?
EDIT: the trace function writes to a file telling me whats sending me activations
TIA.
Turns out its working ok, as Hans points out, i'm just not seeing the output from the debugger from the other processes, if I put in some extra tracing code - one trace file per attached process - I can see can see that things are working after all.
Many thanks for the replies.
i'm trying to figure out where Windows Error Reports are saved; i hit Send on some earlier today, but i forgot that i want to "view the details" so i can examine the memory minidumps.
But i cannot find where they are stored (and google doesn't know).
So i want to write a dummy application that will crash, show the WER dialog, let me click "view the details" so i can get to the folder where the dumps are saved.
How can i crash on Windows?
Edit: The reason i ask is because i've tried overflowing the stack, and floating point dividing by zero. Stack Overflow makes the app vanish, but no WER dialog popped up. Floating point division by zero results in +INF, but no exception, and no crash.
You guys are all so verbose! :-)
Here's a compact way to do it:
*((int*)0)=0;
Should be a good start:
int main(int argc, char* argv[])
{
char *pointer = NULL;
printf("crash please %s", *pointer);
return 0;
}
You are assuming the memory dumps are still around. Once they are sent, AFAIK the dumps are deleted from the machine.
The dumps themselves should be located in %TEMP% somewhere.
As far as crashing, that's not difficult, just do something that causes a segfault.
void crash(void)
{
char* a = 0;
*a = 0;
}
Not sure if this will trigger the Error Reporting dialog, but you could try division by zero.
The officially-supported ways to trigger a crash on purpose can be found here:
http://msdn.microsoft.com/en-us/library/ff545484(v=VS.85).aspx
Basically:
With USB keyboards, you must enable
the keyboard-initiated crash in the
registry. In the registry key
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\kbdhid\Parameters,
create a value named
CrashOnCtrlScroll, and set it equal to
a REG_DWORD value of 0x01.
Then:
You must restart the system for these
settings to take effect.
After this is completed, the keyboard
crash can be initiated by using the
following hotkey sequence: Hold down
the rightmost CTRL key, and press the
SCROLL LOCK key twice.
No programming necessary ;) No wheel reinvention here :)
Interesting to know how to crash Windows. But why not have a look at
%allusersprofile%\Application Data\Microsoft\Dr Watson\
first? Look out for application specific crashdata folders as well, I found e.g.
...\FirefoxPortable\Data\profile\minidumps\
and
...\OpenOfficePortable\Data\settings\user\crashdata\.
I have customer that uses older, custom built ERP application for which they don't have source code and company that developed it does not exist any more. Application is developed in 2000 and it's built with Delphi. Since last executable is from 2003, it could be D6 or D7.
On one important form there are some fields where customer would like to display additional data from other databases and asked me if it's possible to "duct tape" data over existing form.
First idea I got is to build application that will:
browse list of windows target application creates and find controls on form
attach "some" event when to get notified when target form is displayed
attach "some" event when to get notified when field on target form is changed
display additional information in small window overlaying target form
Are there any examples on how to do something like this. I searched google with variations of this question title, but without success.
Note - rewriting of ERP application is not planned.
About language - I can do it with C# or Delphi.
I'm going to answer this from a purely C & Win32 point of view, because I don't know Delphi or its libraries. Converting this to C# can be accomplished via p/invoke, but some parts may/will need to be unmanaged.
First off, no guarantees. If the target application is doing windows-less controls (if there isn't an HWND under every on-screen control) you're pretty much out of luck. This isn't all that uncommon, so yeah...
Step 1, register a window hook listening for new windows created by the target process*:
//dllHMod is an HMODULE that refers to the DLL containing ShellHookProc
HHOOK hook = SetWindowsHookEx(WH_SHELL, ShellHookProc, dllHMod, 0);
// error handling, stashing hook away for unregistering later, etc...
LRESULT CALLBACK ShellHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode < 0) return CallNextHookEx(NULL, nCode, wParam, lParam);
if(nCode == HSHELL_WINDOWCREATED)
{
WindowCreate((HWND)wParam);
}
return 0;
}
WindowCreated(HWND) should stash the HWND away if the correct process (determined via GetWindowThreadProcessId) owns it. At this point, you'll be able to get every top-level window owned by the target process. Note that registering a global hook carries a notable performance penalty, not that it really matters in your case but you should expect it.
Now for the fun part. There's no reliable way to tell when a window is fully constructed, or when its done rendering (there are ways to tell when it STARTS rendering, but that doesn't really help). My advice, guess. Just throw some arbitrary wait in there and then try and enumerate all the child windows.
To enumerate child windows (if you know enough about the target window, there are better ways to do this; but I'm assuming a search is easiest):
//targetHWND is an HWND of one of the top-level windows you've found
EnumChildWindows(targetHWND, ChildWindowCallback, NULL);
//more code...
BOOL ChildWindowCallback(HWND window, LPARAM ignored)
{
if(IsTargetWindow(window)) { /* Do something */ }
return TRUE;
}
Implementing IsTargetWindow is another tricky part. Hopefully you'll find some reliable test for doing so (like checking the class name, window name, style, something; look at GetWindowInfo).
Once you have the window you want to monitor, you can use SetWindowLongPtr and GWLP_WNDPROC to watch all messages it receives. This will require code injection (and thus unmanaged code) and is awfully low level. I'd advise against it if you could possibly avoid it, but lacking the source...
I think this answers is a decent starting point, but once again this is going to be incredibly painful if its even possible at all. Good luck.
*Alternatively, if you know that the target app doesn't create windows except at startup (or at detectable/predictable points in time) you can use EnumWindows.