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

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?

Related

Inline __asm code for getting the address of TIB (fs:[0x18])

I'd like to get the TIB of a process and afterwards get its PEB and so forth. I'm failing to do so because I'm having some issues with the __readfsdword(0x18) function, so I'd like to do it with __asm inline code, if possible.
The program is compiled for x86, so I think it means that the TIB will be located at offset 0x18 from the FS register. On x64 it should be on gs:[0x30].
How would I implement this inline assembly idea?
Edit
NtCurrentTeb() and __readfsdword gave different return addresses so I wanted to get as low-level as possible to figure out which one was malfunctioning.
The reason why __readfsdword wasn't working is because I think the libraries weren't compatible with each other, so I replaced them with the updated versions and now it's working properly.
__readfsdword/__readgsqword are compiler intrinsic functions that will generate more optimized code, there is no reason to use inline assembly. Inline assembly is not even supported by Microsoft's compilers for 64-bit targets.
#include <intrin.h>
__declspec(naked) void* __stdcall GetTEB()
{
__asm mov eax, dword ptr fs:[0x18] ;
__asm ret ;
}
...
void *teb;
__asm push eax ;
__asm mov eax, dword ptr fs:[0x18] ;
__asm mov teb, eax ;
__asm pop eax ;
printf("%p == %p == %p\n", GetTEB(), teb, __readfsdword(0x18));
And as suggested in the comments, NtCurrentTeb() is provided by the Windows SDK. It most likely just uses __readfsdword.

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

How to enable inclusion of x86 and x64 asm files into a single Visual Studio project?

I'm using Visual Studio 2017 Community to build a test console C++ application. I need to include an assembly function into that project:
extern "C" void* __fastcall getBaseFS(void);
To include an asm file I right-clicked the project and went to "Build dependencies" -> "Build Customization" and checked "masm" in the list there.
I can then add an asm file by right-clicking my project -> Add New item -> and then add "asm_x64.asm" file where I write my x86-64 asm code:
.code
getBaseFS PROC
mov ecx, 0C0000100H ; IA32_FS_BASE
rdmsr
shl rdx, 32
or rax, rdx
ret
getBaseFS ENDP
END
This works in a 64-bit project.
The problem is that when I switch solution platform from x64 to x86:
my asm file needs to change. So in a sense I need to include a different "asm_x86.asm" file into compilation that is used only for x86 builds vs. x64 builds.
What's the best way to automate this switch?
OK, thanks to Michael Petch, I got it solved. Had to put both x64 and x86 code in one .asm file.
(There's another proposed option to deal with build configuration, but I prefer the method I'm showing here. I had a bad luck with those build configurations disappearing when solutions were moved from computer to computer.)
So, I'm not sure why using IFDEF RAX works, and Microsoft's own proposed ifndef X64 doesn't. But oh well. If anyone knows, please post a comment.
asm_code.asm file:
IFDEF RAX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; x64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WinAPI to call
extrn Beep : proc
.data
align 8
beep_freq:
dq 700 ; hz
beep_dur:
dq 200 ; ms
str_from:
db "Hail from x64 asm", 0
.code
useless_sh_t_function__get_GS_a_string_and_beep PROC
; parameter = CHAR** for a string pointer
; return = value of GS register selector
mov rax, str_from
mov [rcx], rax
mov rdx, qword ptr [beep_dur]
mov rcx, qword ptr [beep_freq]
call Beep
mov rax, gs
ret
useless_sh_t_function__get_GS_a_string_and_beep ENDP
ELSE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; x86 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.686p
.XMM
.model flat, C
.data
align 4
beep_freq dd 700 ; hz
beep_dur dd 200 ; ms
str_from db "Hail from x86 asm", 0
.code
; WinAPI to call
extrn stdcall Beep#8 : proc
useless_sh_t_function__get_GS_a_string_and_beep PROC
; parameter = CHAR** for a string pointer
; return = value of GS register selector
mov eax, [esp + 4]
mov [eax], OFFSET str_from
push dword ptr [beep_dur]
push dword ptr [beep_freq]
call Beep#8
mov eax, gs
ret
useless_sh_t_function__get_GS_a_string_and_beep ENDP
ENDIF
END
main.cpp file:
#include "stdafx.h"
#include <Windows.h>
extern "C" {
size_t useless_sh_t_function__get_GS_a_string_and_beep(const CHAR** ppString);
};
int main()
{
const char* pString = NULL;
size_t nGS = useless_sh_t_function__get_GS_a_string_and_beep(&pString);
printf("gs=0x%Ix, %s\n", nGS, pString);
return 0;
}
Good that you found a way to handle your use case.
However, if you have more asm files, or only need them for some build types, you could also change the settings for each individual file for the parts where it differs from the project defaults.
Just right-click a file name to get to its individual properties.
To have an asm file included in x64 builds only, you can use these settings:
And then exclude it from 32-bit builds:
These settings are available for all file type, not only for .asm files.

VS debugger skips ctors in base class

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.

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] }
}

Resources