VS debugger skips ctors in base class - visual-studio

It seems that Visual Studio debugger (I've checked VS 2015 and VS 2017) skips constructors and assignment operators in the base class. If I create a new C++ Win32 console application project with the following code
#include <iostream>
struct B
{
B() { std::cout << "ctor"; }
};
struct S : B { };
int main()
{
S s1;
return 0;
}
I cannot step into B::B(), "ctor" is printed and the debugger goes to the "return 0;" line. In the disassembly the "call S::S (01713D4h)" is followed by a piece of code that is not attributed to any source ("Source not available"):
00E51DF0 push ebp
00E51DF1 mov ebp,esp
00E51DF3 sub esp,0CCh
00E51DF9 push ebx
00E51DFA push esi
00E51DFB push edi
00E51DFC push ecx
00E51DFD lea edi,[ebp-0CCh]
00E51E03 mov ecx,33h
00E51E08 mov eax,0CCCCCCCCh
00E51E0D rep stos dword ptr es:[edi]
00E51E0F pop ecx
00E51E10 mov dword ptr [this],ecx
00E51E13 mov ecx,dword ptr [this]
00E51E16 call B::B (0E51389h)
How can I step into B::B() (without using a breakpoint)?

I got the same issue as yours, not find the VS settings which could impact the debugger tool, so I help you report this issue to the product team here:
https://developercommunity.visualstudio.com/content/problem/77978/vs-debugger-skips-ctors-in-base-class.html.
If possible, you could also add your comment and vote that report directly. If I got any update from the product team, I will share it here.

Related

Assembly in visual studio Print the value in registry

I have created a program in visual studio to move values in the registry but i have no way of knowing whether the program actually worked since i cannot see the registr in visual studio 2017
I am running on visual studio 2017. I have a C++ Project that looks like this
extern "C" void doit();
void main()
{
doit();
}
and thsi is what my assembly file looks like
.586
.model flat ,c
.stack 100h
.data
.code
doit proc
mov eax, 8
mov ebx, 4
mov ecx, 6
mov edx, 12
add eax, ebx
add eax, edx
sub eax, ecx
doit endp
end
I would now please like to print or message box the values in these registrys so that i can know if the program works. Thx for the help

VariantClear releases VT_DISPATCH -vs- MSDN documentation

VS2015 C++ / Windows7 SP1
Considering the following code:
CComPtr<IFontDisp> m_pFont;
::OleCreateFontIndirect(&fdesc,IID_IFontDisp,(void**)&m_pFont);
VARIANT var = m_pFont; // PSEUDO CODE
after this,
var.vt = 9; //VT_DISPATCH
var.DISPATCH = "oleaut32.dll/IFontDisp"
So all looks fine.
Now I call
::VariantClear(var);
And I debug into (ASM), I found this:
74CB2EA6 nop
CFont::Release:
--> 74CB2EA7 sub dword ptr [esp+4],4
74CB2EAC jmp CFont::Release (74CB2E79h)
74CB2EAE nop
74CB2EAF nop
74CB2EB0 nop
Following the code:
CFont::Release:
--> 74CB2E79 mov edi,edi
74CB2E7B push ebp
74CB2E7C mov ebp,esp
74CB2E7E push esi
74CB2E7F mov esi,dword ptr [ebp+8]
74CB2E82 push edi
74CB2E83 lea eax,[esi+0A8h]
74CB2E89 push eax
74CB2E8A call dword ptr [__imp__InterlockedDecrement#4 (74C91298h)]
74CB2E90 mov edi,eax
74CB2E92 test edi,edi
74CB2E94 je CFont::Release+261h (74CB30DAh)
74CB2E9A mov eax,edi
74CB2E9C pop edi
74CB2E9D pop esi
74CB2E9E pop ebp
74CB2E9F ret 4
So as I see, it releases the COM interface.
But if I see MSDN doc about VariantClear:
if the variant to be cleared is a COM object that is passed by
reference, the vtfield of the pvargparameter is VT_DISPATCH | VT_BYREF
or VT_UNKNOWN | VT_BYREF. In this case, VariantClear does not release
the object. Because the variant being cleared is a pointer to a
reference to an object, VariantClear has no way to determine if it is
necessary to release the object. It is therefore the responsibility of
the caller to release the object or not, as appropriate.
According to this, it should not call release on the IFontDisp.
Can anybody explain what is going on here?
Thanks.

Cannot access stack elements from another method - Assembly [duplicate]

My questions pertain to the actions that seem to happen between the line when context is changed especially concerning RSP and RBP.
Given this very simple program:
Reading symbols from ./function_call...done.
(gdb) disass main
Dump of assembler code for function main:
0x00000000004004d6 <+0>: push rbp
0x00000000004004d7 <+1>: mov rbp,rsp
0x00000000004004da <+4>: mov esi,0x2
0x00000000004004df <+9>: mov edi,0x1
0x00000000004004e4 <+14>: call 0x4004b6 <add_and_7>
0x00000000004004e9 <+19>: mov eax,0x0
0x00000000004004ee <+24>: pop rbp
0x00000000004004ef <+25>: ret
End of assembler dump.
(gdb) disass add_and_7
Dump of assembler code for function add_and_7:
0x00000000004004b6 <+0>: push rbp
0x00000000004004b7 <+1>: mov rbp,rsp
0x00000000004004ba <+4>: mov DWORD PTR [rbp-0x14],edi
0x00000000004004bd <+7>: mov DWORD PTR [rbp-0x18],esi
0x00000000004004c0 <+10>: mov DWORD PTR [rbp-0x4],0x7
0x00000000004004c7 <+17>: mov edx,DWORD PTR [rbp-0x14]
0x00000000004004ca <+20>: mov eax,DWORD PTR [rbp-0x18]
0x00000000004004cd <+23>: add edx,eax
0x00000000004004cf <+25>: mov eax,DWORD PTR [rbp-0x4]
0x00000000004004d2 <+28>: add eax,edx
0x00000000004004d4 <+30>: pop rbp
0x00000000004004d5 <+31>: ret
End of assembler dump.
(gdb) list
1 int add_and_7( int num1, int num2 ) {
2 int seven = 7;
3 return num1 + num2 + seven;
4 }
5
6 int main() {
7 add_and_7( 1, 2 );
8 return 0;
9 }
All functions start off with push rbp which I as I understand it is preserving the parent context onto the stack. How does the parent function know how to rebuild itself? Are the necessary steps built into call and ret?
Then the rsp is always moved to rbp. As I have read this sets the new stack base to be in the context of the current function. What I can't seem to figure out is when or how stack pointer was set to that point in the first place. My best guess is the assembly function call does this, is that whats happening?
Lastly when a method returns it seems like eax is the register that is used for the parent function to utilize the return of its child function. Is eax explicitly used for this or is this just a convention with my compiler and architecture?
How does the parent function know how to rebuild itself ? Are the necessary steps built into call and ret?
Before calling a function, current status of registers are saved, as well as the return address. call instruction jumps to particular address, where the called function begins. The return address is pushed onto stack. When called function returns, ret instruction pops previously pushed return address and goes to that location.
Then the rsp is always moved to rbp
rbp is previously pushed onto stack to be able to restore rbp's value from caller's function. Then, rsp is moved to rbp to create a new stack frame for callee function. The new base pointer has been set up. So currently, rbp and rsp points to the same addresses. If there are other push instructions, esp is automatically adjusted. When function is done, the pop ebp instruction restores previously pushed stack base pointer address.
Push and Pop modify the stack pointer - SP.
Call pushes FLAGS - status register as well as the RA - return address.
Ret pops the FLAGS pops and jumps to the return address.
As rkhb said, the need to keep certain registers as they are comes from the calling conventions.

C++Builder - implement entire function in assembly

I am trying to implement this inline assembly trick to obtain the value of EIP in C++Builder. The following code works in Release mode:
unsigned long get_eip()
{
asm { mov eax, [esp] }
}
however it doesn't work in Debug mode. In Debug mode the code has to be changed to this:
unsigned long get_eip()
{
asm { mov eax, [esp+4] }
}
By inspecting the generated assembly; the difference is that in Debug mode the code generated for the get_eip() function (first version) is:
push ebp
mov ebp,esp
mov eax,[esp]
pop ebp
ret
however in Release mode the code is:
mov eax,[esp]
ret
Of course I could use #ifdef NDEBUG to work around the problem ; however is there any syntax I can use to specify that the whole function is in assembly and the compiler should not insert the push ebp stuff? (or otherwise solve this problem).
Have you tried __declspec(naked)?
__declspec(naked) unsigned long get_eip()
{
asm { mov eax, [esp] }
}

Why is a stack overflow exception occuring immediately in my Visual Studio Debug Session?

I am attempting to debug a program (.exe) written in C++. The program is a console application, and is mathematical-oriented simulation, no GUI or interface code. I am attempting to start a debug session on this program compiled in Visual Studio 2008 on Win 7 (64 bit), by right-clicking the executable from VS's solution explorer and selection "step into new instance". However, before the very first line of code is executed, Visual Studio reports "Unhandled exception at 0x00000001401b3937 in sim.exe: 0xC00000FD: Stack overflow." Here's a snippet of the first couple lines of code
int_T main(int_T argc, const char_T *argv[])
{
SimData thisSim;
int InputFlag = 0;
The debugger arrow is pointing at the first angle bracket.
Here's a snapshot of the dissabembly view:
int_T main(int_T argc, const char_T *argv[])
{
0000000140141930 mov qword ptr [rsp+10h],rdx
0000000140141935 mov dword ptr [rsp+8],ecx
0000000140141939 push rsi
000000014014193A push rdi
000000014014193B mov eax,1120C8h
0000000140141940 call __chkstk (1401B3900h)
0000000140141945 sub rsp,rax <------DEBUGGER IS STOPPED HERE
0000000140141948 mov rax,qword ptr [__security_cookie (1401F7050h)]
000000014014194F xor rax,rsp
0000000140141952 mov qword ptr [rsp+1120B0h],rax
///////////////////////////////////////////////////////////////////////////
/* Initialize Instance of SimData */
SimData thisSim;
int InputFlag = 0;
000000014014195A mov dword ptr [rsp+20h],0
I'm not a Visual Studio expert, but I have used it a fair amount to do debugging in the past, and I've never seen this behavior.
Any thoughts on how to proceed?

Resources