Entries for tag "visual studio", ordered from most recent. Entry count: 62.
# How code refactoring can fix stack overflow error?
Sun
07
Feb 2016
tl;dr: A very long C++ function with multiple local variables, even if they are not very big and they are placed in separate scopes, can reserve as much as hundreds of kilobytes of stack frame, causing "Stack Overflow" even without bugs like infinite recursion. So you better split your long functions into shorter ones.
Can refactoring (or the lack of thereof) cause application crashes? If we understand refactoring as changes in code layout without changing its logic, we might think that it's just the matter of readability and unreadable code increases chances of introducing bugs. But here is a story in which refactoring actually fixed a bug.
Long time ago in a software project far far away, there was a bug submitted telling that the application crashes with "Stack Overflow" message. It was a Windows app, developed in C++ using Visual Studio. I thought: - I can handle that, it should be easy! Every beginner/intermediate programmer knows about the call stack and surely seen this error at least once when accidentally caused infinite recursion in his code. So my first idea was that infinite recursion happens because of some logical error in the code (that should be easy to fix) or some unfortunate, invalid input data (that should be validated for safety before usage).
As it turned out, this was not the case. After setting up all the test environment and catching the crash in Visual Studio debugger, I looked at Call Stack and noticed that it looks quite normal. Sure the call depth was significant (as for C++, I'm not talking about Java here ;) and there was even some recursion, but 20 or 30 functions is not that much. The stack ended with a call to non-recursive function that seemed correct, so it was not the recursion that caused stack overflow.
My second idea was that some of these functions allocate some big objects (like arrays) by value, as local variables on the stack and this causes the stack to grow too big. I reviewed code of the functions that I found on the stack and used "Immediate Window" panel to quickly check sizeof(xxx) of variables or their types when they used some class, but I didn't find anything particularly big. Local variable sizes varied from few bytes to at most several hundred bytes and I couldn't find any big arrays defined in these functions. I also fetched address of some local variable in a function near the bottom of the stack (which looks like 0x000000000009a370), address of a parameter from the function at the top of the stack and subtracted them to see how big the stack grown over all these calls. The result was around 50 KB - not that much.
My third idea was to check maximum size of the stack. It is 1 MB by default, but it can be changed in Visual Studio project settings, in Linker > System tab, as "Stack Reserve Size" parameter. I check my project and I found this parameter not changed from its default value.
OK, now this became more difficult than I thought. After many debugging sessions, where I looked at various pointers, addresses and numbers trying to spot some memory override, stack corruption, out-of-bounds indexing etc., I finally opened "Disassembly" and "Registers" panels. I'm not a fan of such low level stuff, so it took me some time and few Google queries to understand these RSP, RBP registers and make sense of some x86-64 opcodes. While debugging step-by-step in the assembly, I found something interesting. At the beginning of my function, there was a call to mysterious function __chkstk
and the crash occurred inside it. That was a clue I could use to ask Google what this all means. I found this: Description of the stack checking for Windows NT-based applications and this: What is the purpose of the _chkstk() function? These articles say that as the stack grows, next 4 KB pages are reserved. Each next page is allocated by the system on first "touch". I could actually see in my debugger that functions which need less than 1 page (4096 B = 1000h) have an instruction at the beginning similar to this:
sub rsp,0A9h
While my debugged function had this instead:
mov eax,26B29h
call __chkstk (018104AA00h)
sub rsp,rax
The articles say that when reserving more than one page of stack memory, this function must be called to loop over addresses with 4 KB step and "touch" each page. This is really what it does:
--- f:\dd\vctools\crt\crtw32\startup\amd64\chkstk.asm ---
sub rsp,10h
mov qword ptr [rsp],r10
mov qword ptr [rsp+8],r11
xor r11,r11
lea r10,[rsp+18h]
sub r10,rax
cmovb r10,r11
mov r11,qword ptr gs:[10h]
cmp r10,r11
jae cs10+10h (018104AA40h)
and r10w,0F000h
lea r11,[r11-1000h]
mov byte ptr [r11],0
cmp r10,r11
jne cs10 (018104AA30h)
mov r10,qword ptr [rsp]
mov r11,qword ptr [rsp+8]
add rsp,10h
ret
Key sentence of the second linked article seems to be: "The parameter in rax is size of data you want to add." In my case, eax is set to 26B29h = 158505. Wait, what?! This is more than 150 KB! Is it really how much of the stack the function needs?!
It was finally the right conclusion. The function was more than 3000-lines long, with lots of nested conditions and all kinds of stuff, but mostly an all-encompassing switch with dozens of different cases. I refactored it, extracting code from under each case to a separate function. This fixed the "Stack Overflow" crash.
Apparently if you have a long function and define a lot of local variables, even if they are not particularly big and they are placed inside separate scopes like if-s or switch case-s, the function may need as much as 150 KB of stack frame, at least in Debug configuration. This can cause crash with "Stack Overflow" message even without infinite recursion or bugs like that. So please keep this in mind as additional argument for refactoring your code as soon as you see the need for it.
Comments | #visual studio #c++ Share
# type_safe_ptr - Idea for Type-Safe void* Pointer
Sat
21
Nov 2015
I was thinking recently about passing raw data pointers (like void* or char*), which we have to do sometimes in C++. Is there any way to check if the type that we cast it to is the same as the type of last assigned value? I came up with an idea of implementing a "smart pointer" class using RTTI (specifically typeof operator) to store type information next to the actual pointer. Example usage:
int i = 123;
type_safe_ptr ptr{&i};
int j = *ptr.get_typed<int>(); // OK
float f = *ptr.get_typed<float>(); // Error
Initially I wanted to store pointer to const type_info struct returned by typeid operator, and it seems to work in Visual Studio 2015, but language standard defines the object returned by typeid as temporary, so it is not formally correct. Finally I decided to store typeid(T).hash_code(). You can find my implementation of classes type_safe_ptr and type_safe_const_ptr in file: type_safe_ptr.hpp. Here is example tesing program:
#include <cstdio>
#include "type_safe_ptr.hpp"
int main()
{
type_safe_ptr ptr1;
// ptr1 is null.
assert(!ptr1);
assert(ptr1.get() == nullptr);
int i = 123;
type_safe_ptr ptr2{&i};
// ptr2 is pointer to int.
assert(*ptr2.get_typed<int>() == 123);
// It would activate assert inside type_safe_ptr.get_typed, because ptr2 is int not float.
//assert(*ptr2.get_typed<float>() == 123.f);
struct STest { int i; } obj;
// itr2 is now pointer to STest.
ptr2 = &obj;
ptr2.get_typed<STest>()->i = 124;
assert(obj.i == 124);
// It would activate assert inside type_safe_ptr.get_typed, because ptr2 is now STest not int.
//assert(*ptr2.get_typed<int>() == 123);
type_safe_const_ptr cptr = type_safe_const_ptr(ptr2);
// cptr is pointer to const STest.
assert(cptr.get_typed<STest>()->i == 124);
const int* constIntPtr = &i;
cptr.reset(constIntPtr);
// cptr is now pointer to const int.
assert(*cptr.get_typed<int>() == 123);
}
Some issues and open question regarding my solution are:
Final question is, whether this whole idea of "type-checking void* smart pointer" makes any sense? I am not sure about that, but anyway it was a funny experiment :)
Comments | #c++ #visual studio Share
# Unicode w Visual C++ - My Old Article
Tue
15
Sep 2015
I just noticed that my old article "Unicode w Visual C++" (in Polish) was a dead link and restored it back online:
It may not be "politically correct" if you believe in what they say in UTF-8 Everywhere manifesto, but I think the information that I have put there are still relevant and useful despite being 7 years old.
Comments | #c++ #visual studio Share
# Adventures with Porting Code to Visual Studio 2015 and No DirectX SDK
Sat
08
Aug 2015
I just installed new Visual Studio 2015 Community Edition and ported my personal project to it. At the same time, I uninstalled old DirectX SDK Jun 2010 and started using new DirectX headers bundled with Windows SDK, which is installed together with Visual Studio. These two transitions are not connected - I could already switch to new DX headers years ago, but I decided to do it now. While transition to VS 2015 was smooth, abandoning DirectX SDK caused some problems, because new DirectX doesn't contain D3DX library. Here is a dump of the problems and solutions that I encountered during this effort:
1. I uninstalled DirectX SDK Jun 2010, Visual Studio 2013 Community Edition and all other components that seemed related to it, like Microsoft SQL. I left all "Microsoft Visual C++ XX Redistributable" though, because these are required by many applications and intended to be installed on target machine, not necessarily as a part of development environment.
Next, I downloaded and installed new Visual Studio 2015 Community Edition. During this long process, I was thinking what should I expect from the new IDE... Whether Microsoft did a good job this time? On one hand, it is suprising that C++ is now an optional installation component, so it seems like native code is in shadow comparing to all these new and trendy cloud/web/mobile/managed technologies. On the other hand, table: C++11/14/17 Features In VS 2015 RTM shows that the new C++ compiler caught up with many features of new C++11/14/17 language, which gives hope that authors still treat native code development seriously.
2. The looks of new IDE is so similar to the previous version it is hard to notice any differences. After launching it, I had to first recompile static libraries that my project depends on. That was zlib 1.2.8 and my CommonLib. Converting project to new version, as well as the build itself went smoothly, without any problems - which is unusual with C/C++ libraries :) Just as in previous version, headers and libs of standard C library, standard C++ library (STL) and WinAPI are already bundled with the Visual Studio, so there is no need to install or configure anything additional before you can use them.
Comments | #visual studio #directx #c++ Share
# How to check size of structure during development in Visual C++?
Wed
08
Jul 2015
Today I wanted to know what is sizeof(SomeStructure) during my coding in C++ in Visual Studio, without compiling and running my program. I needed that to put it into an assertion. Sure I could run the program and then break into debugger and evaluate the sizeof(SomeStructure) e.g. in Watches window, but the project is big and takes long time to build.
It turns out there is no such feature in Visual Studio to check size of structure, but it can be easily hacked using IntelliSense. In just few seconds, from this Google query, through its first result - this StackOverflow page, I have found following solution:
1. Put this line somewhere into your code:
template<size_t S> class Sizer { }; Sizer<sizeof(MY_STRUCTURE)> foo;
2. Replace "MY_STRUCTURE" with the name of your structure, other type or a variable.
3. Hover mouse cursor over "foo" and observe evaluated expression, for example: "Sizer<1296U> foo". 1296 is the size of your structure, in bytes - same as operator sizeof would return in runtime, when your program is compiled in currently selected configuration. "U" is for "unsigned".
By the way, maybe it would be a good feature request to add printing size of a type to the information available in design-time in Visual Studio, e.g. to Properties window, where there already are information about the type like IsTemplate, IsValue etc.?
Comments | #c++ #visual studio Share
# Installing Visual C++ Redistributable Package from Command Line
Wed
20
May 2015
You may think that unless you explicitly use some external library (like FMOD), your program will not require any additional libraries to work, but when coding in C++ using Visual Studio, this is not the case. The functions of standard C/C++ library are implemented in a package of DLL-s called Microsoft Visual C++ Redistributable Package. Each version of Visual Studio has their own set. For example, version for Visual Studio 2013 (Release configuration) consists of files: msvcr120.dll, msvcp120.dll.
You can make your application not requiring this library by setting your project options in Configuration Properties > C/C++ > Code Generation > Runtime Library to "Multi-threaded [Debug]" without the "DLL" part, which makes it statically linked. Alternatively, you can distribute these DLL files (although I'm not sure if this is legal) or the whole library installer together with your application. The library is small and free, available to download from Microsoft website:
The question is: can you launch the installer of these packages with some special parameter so the user doesn't have to go through all the setup wizard, confirming each step? The answer is yes, but as Microsoft likes to change everything very often :) the exact command line is different depending on version. Here is the whole set:
Visual Studio 2005 (original one):
Visual Studio 2005, x86 (32-bit version):vcredist_x86.exe /q:a /c:"VCREDI~1.EXE /q:a /c:""msiexec /i vcredist.msi /qn""
Visual Studio 2005, x64 (64-bit version):vcredist_x64.exe /q:a /c:"VCREDI~2.EXE /q:a /c:""msiexec /i vcredist.msi /qn"" "
Visual Studio 2005 SP1, x86:vcredist_x86.exe /q:a /c:"VCREDI~3.EXE /q:a /c:""msiexec /i vcredist.msi /qn"" "
Visual Studio 2005 SP1, x64:vcredist_x64.exe /q:a /c:"VCREDI~2.EXE /q:a /c:""msiexec /i vcredist.msi /qn"" "
If you would like to install it in unattended mode (which will show a small progress bar but not require any user interaction), you can change the "/qn" switch above to "/qb". Unattended mode + disabled "Cancel" button is "/qb!".
Visual Studio 2005 (updated - the one I use):
/Q
- quiet mode
Visual Studio 2008: Just pass one of these parameters:
/q
- quiet mode, no user interface./qb
- unattended mode, shows progress bar but no user interaction required./qb!
- unattended mode with "Cancel" button disabled.
Visual Studio 2010 and 2012:
/q /norestart
- quiet mode/passive /norestart
- passive (unattended) mode
Visual Studio 2013, 2015, 2017:
/install /quiet /norestart
- quiet mode/install /passive /norestart
- passive (unattended) mode
To quickly install all of these libraries on the machines where lots of different applications are launched that may require them, I gathered all the libraries in one directory and I have written following BAT script:
"2005 Updated\vcredist_x86.exe" /Q "2005 Updated\vcredist_x64.exe" /Q "2008 SP1\vcredist_x86.exe" /qb
"2008 SP1\vcredist_x64.exe" /qb
"2010 SP1\vcredist_x86.exe" /passive /norestart
"2010 SP1\vcredist_x64.exe" /passive /norestart
"2012 Update 4\vcredist_x86.exe" /passive /norestart
"2012 Update 4\vcredist_x64.exe" /passive /norestart
"2013\vcredist_x86.exe" /install /passive /norestart
"2013\vcredist_x64.exe" /install /passive /norestart "2015 Update 3\vc_redist.x86.exe" /install /passive /norestart "2015 Update 3\vc_redist.x64.exe" /install /passive /norestart "2017\vc_redist.x86.exe" /install /passive /norestart "2017\vc_redist.x64.exe" /install /passive /norestart
Update: I also prepared a full package with my script and "pirated" copy of all these installers for your convenience: Microsoft Visual C++ Redistributable Package.zip (77.3 MB).
Update 2019-12-20: I've updated the package to contain latest redistributable installers for Visual Studio 2015/2017/2019, as described on Microsoft's page The latest supported Visual C++ downloads.
Comments | #c++ #visual studio Share
# Review: Deleaker - A tool that finds resource leaks
Wed
14
Jan 2015
Deleaker is a tool for programmers that finds resource leaks in C++ programs. It's commercial, with free trial and unconditional 30 day money back. Here is my review of this tool. I've tested version 3.0.27.0.
Deleaker is installed as a plugin for Visual Studio, any version from 2005 to 2013. It also works with Visual Studio Community 2013, as this new free version also supports plugins. There is also standalone Deleaker application (see below).
The purpose of this tool is to augment debugging of native C++ programs with the ability to list all resources that are allocated at the moment (heap memory, virtual memory, OLE memory, GDI objects, USER objects, handles) and so to detect resource leaks. Here is how it works:
The interface is very simple - it can be learned in just few minutes. You can build your program and start debugging it by hitting F5, Deleaker is enabled automatically. Now just open dedicated panel (menu Deleaker > Deleaker Window) and there press "Take snapshot" button. You don't even have to pause execution, but of course the button works as well when your program is paused at a breakpoint. After few seconds, the panel is populated with a list of currently allocated resources, with the place from which it was allocated shown in first column.
After selecting one, bottom panel displays full call stack. Clicking in this call stacks navigates to the place in the source code where the allocation is specified. Finally, after program exit, the list is filled with resources that were not freed - these are actual leaks!
You can filter the list by module (EXE or DLL file that made the call) and by resource type (memory, GDI objects etc.). There is also a column with size of the resource and "Hit Count" - number of resources that were allocated by that particular place in the code (e.g. inside a loop) and stay allocated at the moment.
"Show full stack" button is a nice feature. Clicking it displays full call stack, while by default, the stack is stripped from entries that don't come from your code, but from system libraries. For example, above my function with the actual allocation instruction, there is MSVCR120D.dll!operator new, then there is MSVCR120D.dll!malloc etc... until ntdll.dll!RtlAllocateHeap. It's good that the program can ignore such call stack entries. It also entirely ignores allocations made by system modules outside of your code.
Unfortunately it does this only by identifying module that the function comes from and not it's name, so it cannot ignore templates, like these from STL containers. Maybe ignoring functions by name specified as wildcard or regular expression would help, e.g. "std::*" or "std\:\:.+" - just like Visual Studio debugger can step over specified functions, as I described in How to Make Visual Studio Debugger not Step Into STL.
You can press "Take snapshot" multiple times and save the snapshots for later view. (They are just numbered, you cannot give them names.) By the way, Deleaker captures F5 key, so even when during debugging session, if the focus is in Deleaker panel, this button doesn't resume your program, but instead refreshes the list of allocations (takes new snapshot). You can also select two snapshots and compare them. Then you see only resources that were allocated in the right snapshot and not in the left, which can indicate a leak that happened during some time of the program execution.
Besides heap memory allocations, the tool can also detect other types of resources, like GDI objects. Unfortunately not all interesting types of resources are covered. For example, an opened file of type FILE* f = fopen(...) is shown as normal memory allocation and opened file of type HANDLE f = CreateFile(...) is not shown at all, but I guess it must be due to some system internals.
I didn't find a single leak in my main home project, so I created a dedicated, simple program to test if it can really find leaks. I also checked that it works with programs compiled in Release configuration as well.
Aside from being a Visual Studio plugin, Deleaker can also work as standalone Windows application.
Overall, I like the program. If its price is not a problem for you or your company, I think it can be very useful in improving quality of developed software. I especially like the fact that it's so easy to learn and use.
Comments | #visual studio #tools #c++ Share
# Microsoft Visual Studio Community 2013 !!!
Thu
13
Nov 2014
Microsoft just released a new edition of Visual Studio that will replace Express. It's called Visual Studio Community 2013 and it's free, while it has all the features of the commercial edition, including support for plugins and many advanced tools. You can download it from Visual Studio Downloads, web installer or DVD ISO. It works with "old" Windows 7 as well. Good move Microsoft! For me it's probably the news of the month :) So far, I installed the IDE and tested on my home project CPU profiling:
...and Graphics Analyzer, which replaces good old PIX: