Visual Studio's Memory window: Inspecting a reference instead of the referenced value? - visual-studio

When I inspect a string variable text using Visual Studio's Memory window, I get to see its value:
Out of curiosity, is there a way to inspect (also in the Memory window) the location where that value gets referenced?
(Of course I can already see the memory location's address. I am asking this because I am curious how the CLR represents, and works with, class-type instances. Based on what the CLI specification states, I am assuming that the CLR represents them at least as a combination of a pointer, a type token, and a value. I am seeing the latter two above, but would like to see the pointer, and what else might be stored along with it.)

In general there's not just one location, especially since this is an interned string. But you do have one since you know that the text variable points to the string. So use the address-of operator to get the address of the reference, type &text in the Address box.
You'll probably want to make it a bit more recognizable, right-click the Memory window and select "8-byte integer". You'd see 000000000256D08. The area of memory you are looking at is the stack of the main thread.
Do beware that this is all a bit academic. This works because you are using the debugger and the jitter optimizer was disabled. In an optimized program, that pointer value is going to be stored in a cpu register. And in the specific case of your test method there would be nothing to look at because the assignment statement will be optimized away.
You can see the "real" code with the Release build and Tools + Options, Debugging, General, untick the "Suppress JIT optimization" option. Beware that it makes the debugger stupid, it no longer knows much about local variables. The most important debugging windows then are Debug + Windows + Disassembly to see the code and Debug + Windows + Registers to see the CPU registers. Right-click the latter window and tick SSE2 so you can see the XMM registers, the x64 jitter likes to use them.

Related

How do I change memory bytes in Visual Studio 2017?

I am trying to change bytes in memory, in a memory window, when debugging a C++ project in my Visual Studio 2017. The memory window is pointing at memory holding code, as I am trying to patch a piece of code quickly (just need to change parameter value) without needing to stop and re-compile.
I also noticed that you cannot change values in the memory window even for data memory.
Is there some hidden configuration setting to let you do that. It was possible to do this in VS6.
I found a kind of work-around, that works even for modifying executable code memory.
Here are the steps:
Define a spare global pointer in your code (you can actually use any memory pointer in your code as long as you do not care that you will change its value):
char* memptr;
Set the pointer in a watch window.
Set the pointer value to the memory address that you want to modify.
Expend the content (BTW you can use "memptr,100" in your watch window to access more than one byte).
Type the updated value in the expended byte value cells.
This works even if you set the pointer to executable machine code memory, so you can use it to patch code.
It can be an int pointer or any other type, or you can use a cast in the watch window if you desire to edit any other kinds of objects.
Be careful this can be dangerous, modifying of memory has to be done with the greatest of care.
How do I change memory bytes in Visual Studio 2017?
As far as I know, Microsoft does not support changing the memory bytes directly in the latest Visual Studio including VS2017 and there is no such hidden option to realize it.
In general, during debugging, the Memory window shows the memory space your app is using. And the Memory window isn't limited to displaying data. It displays everything in the memory space, including data, code, and random bits of garbage in unassigned memory.
Besides, memory bytes changes with the values of variables in debugger windows such as Watch, Autos, Local Variables, and QuickWatch dialogs. Then analyze its changes in memory usage to improve the program. Because of it, we cannot change it directly.
In addition, more info about Memory Window, you can check this official document.

How do symbols solve walking the stack with FPO in x86 debugging?

In this answer: https://stackoverflow.com/a/8646611/192359 , it is explained that when debugging x86 code, symbols allow the debugger to display the callstack even when FPO (Frame Pointer Omission) is used.
The given explanation is:
On the x86 PDBs contain FPO information, which allows the debugger to reliably unwind a call stack.
My question is what's this information? As far as I understand, just knowing whether a function has FPO or not does not help you finding the original value of the stack pointer, since that depends on runtime information.
What am I missing here?
Fundamentally, it is always possible to walk the stack with enough information1, except in cases where the stack or execution context has been irrecoverably corrupted.
For example, even if rbp isn't used as the frame pointer, the return address is still on the stack somewhere, and you just need to know where. For a function that doesn't modify rsp (indirectly or directly) in the body of the function it would be at a simple fixed offset from rsp. For functions that modify rsp in the body of the function (i.e., that have a variable stack size), the offset from rsp might depend on the exact location in the function.
The PDB file simply contains this "side band" information which allows someone to determine the return address for any instruction in the function. Hans linked a relevant in-memory structure above - you can see that since it knows the size of the local variables and so on it can calculate the offset between rsp and the base of the frame, and hence get at the return address. It also knows how many instruction bytes are part of the "prolog" which is important because if the IP is still in that region, different rules apply (i.e., the stack hasn't been adjusted to reflect the locals in this function yet).
In 64-bit Windows, the exact function call ABI has been made a bit more concrete, and all functions generally have to provide unwind information: not in a .pdb but directly in a section included in the binary. So even without .pdb files you should be able to unwind a properly structured 64-bit Windows program. It allows any register to be used as the frame pointer, and still allows frame-pointer omission (with some restrictions). For details, start here.
1 If this weren't true, ask yourself how the currently running function could ever return? Now, technically you could design a program which clobbers or forgets the stack in a way that it cannot return, and either never exits or uses a method like exit() or abort() to terminate. This is highly unusual and not possibly outside of assembly.

WinDbg not showing register values

Basically, this is the same question that was asked here.
When performing kernel debugging of a machine running Windows 7 or older, with WinDbg version 6.2 and up, the debugger doesn't show anything in the registers window. Pressing the Customize... button results in a message box that reads Registers are not yet known.
At the same time, issuing the r command results in perfectly valid register values being printed out.
What is the reason for this behaviour, and can it be fixed?
TL;DR: I wrote an extension DLL that fixes the bug. Available here.
The Problem
To understand the problem, we first need to understand that WinDbg is basically just a frontend to Microsoft's Windows Symbolic Debugger Engine, implemented inside dbgeng.dll. Other frontends include the command-line kd.exe (kernel debugger) and cdb.exe (user-mode debugger).
The engine implements everything we expect from a debugger: working with symbol files, read and writing memory and registers, setting breakpoitns, etc. The engine then exposes all of this functionality through COM-like interfaces (they implement IUnknown but are not registered components). This allows us, for instance, to write our own debugger (like this person did).
Armed with this knowledge, we can now make an educated guess as to how WinDbg obtains the values of the registers on the target machine.
The engine exposes the IDebugRegisters interface for manipulating registers. This interface declares the GetValues method for retrieving the values of multiple registers in one go. But how does WinDbg know how many registers are there? That why we have the GetNumberRegisters method.
So, to retrieve the values of all registers on the target, we'll have to do something like this:
Call IDebugRegisters::GetNumberRegisters to get the total number of registers.
Call IDebugRegisters::GetValues with the Count parameter set to the total number of registers, the Indices parameter set to NULL, and the Start parameter set to 0.
One tiny problem, though: the second call fails with E_INVALIDARG.
Ehm, excuse me? How can it fail? Especially puzzling is the documentation for this return value:
The value of the index of one of the registers is greater than the number of registers on the target machine.
But I just asked you how many registers there are, so how can that value be out of range? Okay, let's continue reading the docs anyway, maybe something will become clear:
If the return value is not S_OK, some of the registers still might have been read. If the target was not accessible, the return type is E_UNEXPECTED and Values is unchanged; otherwise, Values will contain partial results and the registers that could not be read will have type DEBUG_VALUE_INVALID.
(Emphasis mine.)
Aha! So maybe the engine just couldn't read one of the registers! But which one? Turns out that the engine chokes on the xcr0 register. From the Intel 64 and IA-32 Architectures Software Developer’s Manual:
Extended control register XCR0 contains a state-component bitmap that specifies the user state components that software has enabled the XSAVE feature set to manage. If the bit corresponding to a state component is clear in XCR0, instructions in the XSAVE feature set will not operate on that state component, regardless of the value of the instruction mask.
Okay, so the register controls the operation of the XSAVE instruction, which saves the state of the CPU's extended features (like XMM and AVX). According to the last comment on this page, this instruction requires some support from the operating system. Although the comment states that Windows 7 (that's what the VM I was testing on was running) does support this instruction, it seems that the issue at hand is related to the OS anyway, as when the target is Windows 8 everything works fine.
Really, it's unclear whether the bug is within the debugger engine, which reports more registers than it can retrieve values for, or within WinDbg, which refuses to show any values at all if the engine fails to produce all of them.
The Solution
We could, of course, bite the bullet and just use an older version of WinDbg for debugging older Windows versions. But where's the challenge in that?
Instead, I present to you a debugger extension that solves this problem. It does so by hooking (with the help of this library) the relevant debugger engine methods and returning S_OK if the only register that failed was xcr0. Otherwise, it propagates the failure. The extension supports runtime unload, so if you experience problems you can always disable the hooks.
That's it, have fun!

WinDbg shows some variables but not others, shows some variables in same location

I'm trying to use WinDbg 6.2.9200.16384 x64 over a serial cable to debug a driver I'm writing. WinDbg connects to the target machine (Windows 8) just fine, and I see all the dbgprints as the system boots and loads everything. I can load the symbols for my driver just fine and can set breakpoints, and when my driver hits those breakpoints, the system halts as expected. This is where things get weird: when I hit a breakpoint, I can only see some of the local variables in my function in both the locals window and when using the 'dv' command. I created a variable to test with:
int myInt = 8;
When I use a dbgprint to show the value of myInt, it works fine and I see it as 8. However, the variable doesn't even appear at all in the locals window or with the 'dv' command. Other variables do, such as
ULONG rcb = 0;
and I can see its value just fine in the locals window. These variables are literally declared one after the other.
Another symptom of this strange problem is this. I have a function
ULONG someFunction(UINT16 offset) {
ULONG rcb, tempAddr, temp, temp1;
ULONG writeAddr, readAddr;
UINT16 dev;
dev = 15;
...
}
I call this function like so:
someFunction(0x777);
When I set a breakpoint in this function and inspect the variable values with WinDbg, nothing makes any sense. First, it only sees 4 of my 8 variables, just offset, rcb, writeAddr, and readAddr. It tells me the value of offset is not 0x777 as I would expect, but 0xE061 (this changes each time I run the code). When I look closer at the locals window (same information is shown via 'dv' and '? varname' commands) I notice that the location of offset and the location of rcb are the exact same address. Likewise, writeAddr and readAddr are stored at the same address as well. None of the other variables are detected by the debugger.
I am convinced that I've loaded the symbols properly, the source and symbols paths are set correctly, I've run '.reload /f' a million times with no errors loading my driver's symbols. I'm still able to break and step through other lines of code, but the locals just don't make any sense. When I dbgprint, the correct values are shown so it seems like this is a problem with the debugger itself, not with my driver. Any ideas?
<>
Nowadays Compiler has been enhanced a lot to get better optimized binary with optimized performance and other metrics. Hence compiler store few variables as locals(visible via 'dv /v' command) and store other variables in their registers. That's the reason you didn't see variable int myInt in dv command. We can get to know which registers are being used for the variables, by disassembling the function using 'uf binary!functionname' or by viewing disassembled code in Windbg View-> Disassembly.
Note that the driver may behave little differently with and without optimization of the compiler in the aspects of performance, memory usage, etc. So its always recommended to debug the one generated from the default optimized compiler, as this is the one used in realtime user scenario.
I fixed the problem. To anyone else who runs into this same thing: I was working with a free build of the driver, so the compiler had optimized out a lot of my variables. To fix it, either compile a checked version of the driver, or add the line
MSC_OPTIMIZATION=/Od /Oi
to your sources file to disable optimizations for the free build. Hope this helps anyone with the same problem.

Some Windows API calls fail unless the string arguments are in the system memory rather than local stack

We have an older massive C++ application and we have been converting it to support Unicode as well as 64-bits. The following strange thing has been happening:
Calls to registry functions and windows creation functions, like the following, have been failing:
hWnd = CreateSysWindowExW( ExStyle, ClassNameW.StringW(), Label2.StringW(), Style,
Posn.X(), Posn.Y(),
Size.X(), Size.Y(),
hParentWnd, (HMENU)Id,
AppInstance(), NULL);
ClassNameW and Label2 are instances of our own Text class which essentially uses malloc to allocate the memory used to store the string.
Anyway, when the functions fail, and I call GetLastError it returns the error code for "invalid memory access" (though I can inspect and see the string arguments fine in the debugger). Yet if I change the code as follows then it works perfectly fine:
BSTR Label2S = SysAllocString(Label2.StringW());
BSTR ClassNameWS = SysAllocString(ClassNameW.StringW());
hWnd = CreateSysWindowExW( ExStyle, ClassNameWS, Label2S, Style,
Posn.X(), Posn.Y(),
Size.X(), Size.Y(),
hParentWnd, (HMENU)Id,
AppInstance(), NULL);
SysFreeString(ClassNameWS); ClassNameWS = 0;
SysFreeString(Label2S); Label2S = 0;
So what gives? Why would the original functions work fine with the arguments in local memory, but when used with Unicode, the registry function require SysAllocString, and when used in 64-bit, the Windows creation functions also require SysAllocString'd string arguments? Our Windows procedure functions have all been converted to be Unicode, always, and yes we use SetWindowLogW call the correct default Unicode DefWindowProcW etc. That all seems to work fine and handles and draws Unicode properly etc.
The documentation at http://msdn.microsoft.com/en-us/library/ms632679%28v=vs.85%29.aspx does not say anything about this. While our application is massive we do use debug heaps and tools like Purify to check for and clean up any memory corruption. Also at the time of this failure, there is still only one main system thread. So it is not a thread issue.
So what is going on? I have read that if string arguments are marshalled anywhere or passed across process boundaries, then you have to use SysAllocString/BSTR, yet we call lots of API functions and there is lots of code out there which calls these functions just using plain local strings?
What am I missing? I have tried Googling this, as someone else must have run into this, but with little luck.
Edit 1: Our StringW function does not create any temporary objects which might go out of scope before the actual API call. The function is as follows:
Class Text {
const wchar_t* StringW () const
{
return TextStartW;
}
wchar_t* TextStartW; // pointer to current start of text in DataArea
I have been running our application with the debug heap and memory checking and other diagnostic tools, and found no source of memory corruption, and looking at the assembly, there is no sign of temporary objects or invalid memory access.
BUT I finally figured it out:
We compile our code /Zp1, which means byte aligned memory allocations. SysAllocString (in 64-bits) always return a pointer that is aligned on a 8 byte boundary. Presumably a 32-bit ANSI C++ application goes through an API layer to the underlying Unicode windows DLLs, which would also align the pointer for you.
But if you use Unicode, you do not get that incidental pointer alignment that the conversion mapping layer gives you, and if you use 64-bits, of course the situation will get even worse.
I added a method to our Text class which shifts the string pointer so that it is aligned on an eight byte boundary, and viola, everything runs fine!!!
Of course the Microsoft people say it must be memory corruption and I am jumping the wrong conclusion, but there is evidence it is not the case.
Also, if you use /Zp1 and include windows.h in a 64-bit application, the debugger will tell you sizeof(BITMAP)==28, but calling GetObject on a bitmap will fail and tell you it needs a 32-byte structure. So I suspect that some of Microsoft's API is inherently dependent on aligned pointers, and I also know that some optimized assembly (I have seen some from Fortran compilers) takes advantage of that and crashes badly if you ever give it unaligned pointers.
So the moral of all of this is, dont use "funky" compiler arguments like /Zp1. In our case we have to for historical reasons, but the number of times this has bitten us...
Someone please give me a "this is useful" tick on my answer please?
Using a bit of psychic debugging, I'm going to guess that the strings in your application are pooled in a read-only section.
It's possible that the CreateSysWindowsEx is attempting to write to the memory passed in for the window class or title. That would explain why the calls work when allocated on the heap (SysAllocString) but not when used as constants.
The easiest way to investigate this is to use a low level debugger like windbg - it should break into the debugger at the point where the access violation occurs which should help figure out the problem. Don't use Visual Studio, it has a nasty habit of being helpful and hiding first chance exceptions.
Another thing to try is to enable appverifier on your application - it's possible that it may show something.
Calling a Windows API function does not cross the process boundary, since the various Windows DLLs are loaded into your process.
It sounds like whatever pointer that StringW() is returning isn't valid when Windows is trying to access it. I would look there - is it possible that the pointer returned it out of scope and deleted shortly after it is called?
If you share some more details about your string class, that could help diagnose the problem here.

Resources