Preventing Visual Studio 2017 debugger from confusing static variables with equal name - visual-studio-2017

I have observed the following phenonem in the VS 2017 debugger:
if there are two static variables of the same name and type in different files, it confuses the two.
pseudo code of variable declarations
file A:
static char msg[2048];
file B:
static char msg[64];
if I debug file B the debugger shows the contents of file A's msg.
My guess would be that the case of equally named static variables was not foreseen when the debugger was developed and which variable it shows depends on the compilation order.
Question:
how can the VS 2017 debugger be "forced" to access the static variables of the currently debugged file without changing the code that is being debugged?
The trivial advice of renaming the variables is not an option for me and IMHO also not in the spirit of static variables.

This is the same issue reported under VS2019 Debugger Confused by multiple variables with same name, and fixed in VS 2019 version 16.8 back in Nov '20.
Unfortunately, there is no current or planned backport of the fix to VS 2017, per this MSFT reply.
One workaround proposed in another comment for VS 2017 is to lookup the memory address of the target variable, then watch it with the appropriate cast.

Related

Random error in exe_common.inl in Debug build

I am using VS 2022 Community Edition (v17.3.3) to build wxWidgets application (v3.2.0) using C++ (v14.3 - Features from Latest C++). The windows SDK is using the latest installed (10.0.22621). The project is also using C++ modules.
The Debug build succeeds but when I run the project's exe file at random it throws the exception (Access violation reading 0xFFFFFF (ucrtbased.dll)) in exe_common.inl at the following line:
__scrt_current_native_startup_state = __scrt_native_startup_state::initialized;
After a few more compilations (by just making minor changes to trigger a compilation) it succeeds and the exe runs correctly.
I wonder if there is any settings that might be causing this random error. Btw, I am using Win11 but same thing happens on Win10 as well.
Thanks in advance.
EDIT 1:
The project is using boost libraries and at startup boost/json (boost/json is used in other parts of the project as well). Debugger shows that after the following line the above error happens:
static allocator_arg_t allocator_arg = BOOST_CONTAINER_DOC1ST(unspecified, *std_allocator_arg_holder<>::dummy);
There were a few things needed attention:
Discontinued use of wxSQLite (the library was not maintained for over a decade),
The main frame was a singleton data structure, not anymore, and not deriving from wxMDIFrame anymore.
All unnecessary (a chain of them) #include removed.
Inclusion of <boost/json.hpp> in a few files were removed and now using #include <boost/json/src.hpp> only in one .cpp file. However, the project still uses inclusion of <boost/json/value.hpp> in multiple .h files.
All uninitialized pointer variables and others were initialized.
#1 and #4 were especially pointed by the debugger. It has now been more than a few days and haven't had the problem since then.

C++ member variables are not initialized when using a debug version static library

Environment: Windows10, cpp17, visual studio 2019, debug version static library
Recently I tried to use Cesium-Native to read 3DTiles files in my project, but there was a confusing problem that some member variables are not initialized correctly.
As following codes show, Tileset() use initializer list to initialize its member variables, but some of them like_loadsInProgress,_previousFrameNumber are initialized to random value which shoule have been 0. However some of them are initialize correctly like _url, _options, and it works well in Release Library and the same code in its original project. What a strange bug!
Tileset::Tileset(
const TilesetExternals& externals,
const std::string& url,
const TilesetOptions& options)
: _externals(externals),
_asyncSystem(externals.asyncSystem),
_userCredit(
(options.credit && externals.pCreditSystem)
? std::optional<Credit>(externals.pCreditSystem->createCredit(
options.credit.value(),
options.showCreditsOnScreen))
: std::nullopt),
_url(url),
_isRefreshingIonToken(false),
_options(options),
_pRootTile(),
_previousFrameNumber(0),
_loadsInProgress(0),
_subtreeLoadsInProgress(0),
_overlays(*this),
_tileDataBytes(0),
_supportsRasterOverlays(false),
_gltfUpAxis(CesiumGeometry::Axis::Y),
_distancesStack(),
_nextDistancesVector(0) {
if (!url.empty()) {
CESIUM_TRACE_USE_TRACK_SET(this->_loadingSlots);
this->notifyTileStartLoading(nullptr);
LoadTilesetDotJson::start(*this, url).thenInMainThread([this]() {
this->notifyTileDoneLoading(nullptr);
});
}
}
Through debugging, I found that _loadsInProgress was 0 at first, and it changes when a vector construct function is called. Maybe it's because generation of debug static lib?
Any suggestions will be appreciated!
The problem solved by carefully checking all setting in running correctly original project and my project. And try to clean Visual Studio Cache and rebuild project and lib may be helpful for the problem.
At first I used the different library version for inlucde and lib files, then I found that, I change the same version library include files to my project. But due to VS cache and the same file name(I guess), the change failed to apply to my project actually.

Debugging into MFC header code does not work with Visual Studio 2019

TL;DR: Debuigging into MFC (CString) header code does not work on both my machines and as far as I can tell this is due to the peculiar way these headers are compiled.
Stepping through MFC header code when entered via disassembly works, but setting brealpoints does not work.
I'm looking for a workaround or at least acknowledgement of my analysis.
System:
Visual Studio 2019 Professional 16.9.6
Windows 10 / 1809 Enterprise LTSC
Setup: (I do apologize for this being rather long.)
Create a Visual Studio 2019 Example MFC Application Project (SDI App)
Make sure Enable Just My Codeis off under Options -> Debugging -> General.
Set the build configuration to Debug/x64 (does not make a difference, but let's all stay on the same page)
Navigate to MFCApplication1.cpp -> CMFCApplication1App::InitInstance()
Insert a CString init like this:
...
InitCommonControlsEx(&InitCtrls);
CWinAppEx::InitInstance(); // please put breakpoint 1 here
// Add this line and set breakpoints
CString this_is_text(L"Debugging into CString Header does not work!"); // breakpoint 2 here
Now, you can start the program under the debugger, and you should stop at the first breakpoint:
Now, make sure all symbols are loaded, easiest done via the Call Stack:
Just select all lines in the call stack window and hit Load Symbols in the context menu. Afterwards the call stack should look roughly like this:
> MFCApplication1.exe!CMFCApplication1App::InitInstance() Line 75 C++
mfc140ud.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00007ff7b5070000, ...) Line 37 C++
MFCApplication1.exe!wWinMain(HINSTANCE__ * hInstance=0x00007ff7b5070000, ...) Line 26 C++
MFCApplication1.exe!invoke_main() Line 123 C++
MFCApplication1.exe!__scrt_common_main_seh() Line 288 C++
MFCApplication1.exe!__scrt_common_main() Line 331 C++
MFCApplication1.exe!wWinMainCRTStartup(void * __formal=0x000000c2b7084000) Line 17 C++
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown
Now, you can try stepping-into (possibly F11) the CWinAppEx::InitInstance() function, which should work without a problem, landing you in mfc140ud.dll!CWinApp::InitInstance() Line 394 - this is OK.
Step out again, and then then try to step-into the CString ctor:
This DOES NOT work on my machine(s)!
What I can do however, is (from the point above) switch to disassembly view, step into the calls there and get into the header code this way:
I can then successfully step through (but never into) the MFC header code. Trying to set a breakpoint will result in the error:
The breakpoint will not currently be hit. No executable code of the debugger's code type is associated with this line.
Possible causes include ...
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29910\atlmfc\include\cstringt.h
And this is where I'm at.
Analysis:
What we can see from the MFC code is that we can step into "regular" cpp code, but as soon as we try to step into (or set breakpoint) code that is inside this CStringt.h it breaks.
Peculiar here: This is template header code, and still the executed code (as shown by the disassembly) is not in the user module but in the mfc###.dll! I think they do some clever tricks with the preprocessor (see defined(_MFC_DLL_BLD) and somesuch) which enables this multi use of the header file, and maybe, possibly this is also what breaks the debugger.
Question:
Is this a known problem, does this happen with all VS2019 installs, is there something peculiar to my setup?
Maybe fixed in a newer VS version?
Iff this is actually broken, what would be a useable workaround, other than constantly switching to disassembly view when into the MFC headers.
The most interesting answer here would actually be as to WHY this breaks - where does the debugger get confused? Is this a general problem with re-define-ing code when debugging library code?
The source shipped with MSVC does not match.
I think this happen, as DLLs got updated with Windows Update or a new vcredist, but Visual Studio includes are not updated. If you build with /MT or /MTd and link MFC statically, the problem does not persist.
Probably this can be reported to http://developercommunity.visualstudio.com if you care.
Workaround 1
Do steps described by #selbie:
Set a breakpoint on the line of code I want to step into.
When
the breakpoint is reached, right click in the editor window and select
"Go To Disassemly".
In disassembly mode, step over until you get to
a call statement. [...] You
can flip out of disassembly mode by right-clicking again and selecting
"go to source code".
(skipped the part not relevant to this issue)
Then pick up the location of the header manually, the debugger will tell that it does not match. The difference seem to be insignificant though, so the header is usable.
Workaround 2
Link MFC statically, compile with /MT or /MTd
Workaround 3
ATL has a similar CString that does not suffer from the issue:
#include <atlbase.h>
#include <atlstr.h>
int main() {
ATL::CString this_is_text("Debugging into CString header works");
}
Analysis went sideways at some point, but we finally found one part of the problem here:
The Require source files to exactly match the original version option:
was the problem, but in a very peculiar way:
When you do NOT require source files to match (that is, disable this default option), then the erroneous behavior of the OP occurs: The debugger can no longer match the symbols to the cstringt.h file.
Unfortunately, I had this disabled on both machines. Pulling in a third machine showed that we could set breakpoints (though F11 still does not work) and by comparing the xml export of the VS settings we found that this was different.
So, long story short: For us, to be able to set breakpoints in the (unmodified!) MFC header, requires us to enable the Require source files to exactly match .. option.
If the option is disabled, which would imply a more lenient behavior by the debugger, it no longer works.
And, yes, we double checked it's always the same source file at C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29910\atlmfc\include\cstringt.h
The mystery with step-into/F11 persists, but I guess this would better be taken to a separate question.
Uncheck the Enable Just My Code option in Tools->Options->Debugging
I know that works for c++ std:: library code debugging. The other technique I do, when I forget to uncheck this option, is similar to what you describe above.
Set a breakpoint on the line of code I want to step into.
When the breakpoint is reached, right click in the editor window and select "Go To Disassemly".
In disassembly mode, step over until you get to a call statement. That's typically the std library. Eventually, you'll navigate into a mix of assembly and system code sources. You can flip out of disassembly mode by right-clicking again and selecting "go to source code".

Declaring a static pointer in class [duplicate]

While compiling on x64 plattform I am getting following error:
c:\codavs05\hpsw-sc\ovpacc\tools\codaaccesstest\coda_access.cpp(1572): fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'f:\dd\vctools\compiler\utc\src\p2\sizeopt.c', line 55)
To work around this problem, try simplifying or changing the program near the locations listed above.
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
------ Build started: Project: asyncexample, Configuration: Release Win32 ------
If I change settings to preprocessor file (Yes) i am not getting any error.
About my environment: Upgrading Microsoft Visual Studio 2005 to 2010
Please help.
I have had this problem with VS2015 while building locally in Windows.
In order to solve it, I deleted my build folder (Output Directory as seen in Properties/General) and rebuilt the project.
This always seems to help when strange things happen during the build.
I’ve encountered this error many times in VC++. Do the following steps. They’ve sometimes helped me with this issue:
Take a look at the exact location, pointed out by compiler error.
Find any external types or classes used there at that location.
Change the order of “include path” of those files found in step 2 and rebuild the solution.
I hope that help !!!!
I am getting same error with VC2012. Setting up the project properties Optimization to Disabled (/Od) resolved the issue.
In my solution, i've removed output dll file of the project, and I've made project rebuild.
I encountered the same error and spent quite a bit of time hunting for the problem. Finally I discovered that function that the error was pointing to had an infinite while loop. Fixed that and the error went away.
In my case was the use of a static lambda function with a QStringList argument. If I commented the regions where the QStringList was used the file compiled, otherwise the compiler reported the C1001 error. Changing the lambda function to non-static solved the problem (obviously other options could have been to use a global function within an anonymous namespace or a static private method of the class).
I got this error using boost library with VS2017. Cleaning the solution and rebuilding it, solved the problem.
I also had this problem while upgrading from VS2008 to VS2010.
To fix, I have to install a VS2008 patch (KB976656).
Maybe there is a similar patch for VS2005 ?
I got the same error, but with a different file referenced in the error message, on a VS 2015 / x64 / Win7 build. In my case the file was main.cpp. Fixing it for me was as easy as doing a rebuild all (and finding something else to do while the million plus lines of code got processed).
Update: it turns out the root cause is my hard drive is failing. After other symptoms prompted me to run chkdsk, I discovered that most of the bad sectors that were replaced were in .obj, .pdb, and other compiler-generated files.
I got this one with code during refactoring with a lack of care (and with templates, it case that was what made an ICE rather than a normal compile time error)
Simplified code:
void myFunction() {
using std::is_same_v;
for (auto i ...) {
myOtherFunction(..., i);
}
}
void myOtherFunction(..., size_t idx) {
// no statement using std::is_same_v;
if constexpr (is_same_v<T, char>) {
...
}
}
I had this error when I was compiling to a x64 target.
Changing to x86 let me compile the program.
Sometimes helps reordering the code. I had once this error in Visual Studio 2013 and this was only solved by reordering the members of the class (I had an enum member, few strings members and some more enum members of the same enum class. It only compiled after I've put the enum members first).
In my case, this was causing the problem:
std::count_if(data.cbegin(), data.cend(), [](const auto& el) { return el.t == t; });
Changing auto to the explicit type fixed the problem.
Had similar problem with Visual Studio 2017 after switching to C++17:
boost/mpl/aux_/preprocessed/plain/full_lambda.hpp(203): fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'msc1.cpp', line 1518)
1> To work around this problem, try simplifying or changing the program near the locations listed above.
Solved by using Visual Studio 2019.
I first encountered this problem when i was trying to allocate memory to a char* using new char['size']{'text'}, but removing the braces and the text between them solved my problem (just new char['size'];)
Another fix on Windows 10 if you have WSL installed is to disable LxssManager service and reboot the PC.

'TypeInfo<char>(char *)' isn't defined but worked pre-C++11; what changed, and how can I fix the error?

I am trying to build a DLL from source-code from the Crysis Wars SDK, and have successfully done so in the past on previous versions of Visual Studio (namely 2005, 2008, and 2010).
My specific problem is this:
Error 4 error LNK2019: unresolved external symbol "struct CTypeInfo const & __cdecl
TypeInfo<char>(char *)" (??$TypeInfo#D##YAABUCTypeInfo##PAD#Z) referenced in function
"void __cdecl SwapEndian<char>(char *,unsigned int)" (??$SwapEndian#D##YAXPADI#Z)
G:\Noctis\Mods\Noctis\Code\GameCVars.obj GameDll
I have attempted to clean the code in Visual Studio and rebuild it on the off-chance this'll work, but this has not changed anything.
Am I missing something here, or has something changed from C++03 to C++11 that means that this code is no longer compilable without reverting to an older version of C++?
I have successfully compiled this code on Visual Studio 2010 in both 64 bit and 32 bit, so it must be some issue related to migrating the project to Visual Studio 2015.
Compilation on 2012, 2013, and 2015 versions of Visual Studio reproduce this error but not 2010, so it seems that the change to trigger this problem was introduced in C++11.
What am I doing wrong?
Reading the answer to mem-fun is not a member of std, it could just be that I need to include a standard library that I didn't need to include in earlier versions of Visual Studio.
If this is true, which library would I need to #include?
I have also created a GitHub repository containing only the original unmodified code provided from the SDK, for testing purposes (in the event I myself made a typo, which doesn't seem to be the case here but I've put the link here as it may be helpful).
If it matters, I'm using Visual Studio 2015 Enterprise edition on Windows 10 Professional x64.
What does the error mean?
The error message hints towards a classic "declared but not defined" scenario.
TypeInfo<char>(char*) is declared in TypeInfo.h (through some macros) and declared in AutoTypeInfo.cpp in project CryCommon.
Usually you would just make sure the CryCommon project is built correctly and linked into your final GameDll project properly and that's it.
But it turns out here that the CryCommon project has not been built for a long time - it references many other Crytek libraries etc. So the problem must be that something now needs these TypeInfo<> definitions and previously it did not.
What is referencing the TypeInfo<> code?
In your project it's function CmdHelp() in Aurora/Code/GameCVars.cpp, precisely this line:
nRead = gEnv->pCryPak->FRead( buf, BUFSZ, f );
The implementation of the FRead() method is in CryCommon/ICryPak.h:
template<class T>
size_t FRead(T *data, size_t elems, FILE *handle, bool bSwap = true)
{
size_t count = FReadRaw(data, sizeof(T), elems, handle);
if (bSwap)
SwapEndian(data, count);
return count;
}
As you can see, if bSwap is true (the default), SwapEndian() is invoked there.
Why hasn't this manifested before?
Perhaps the compiler was indeed behaving differently.
Or, more likely, you have been always compiling the project as Release before. The whole byte-swapping functionality is enabled only on big-endian systems (and your target is most probably not one of those) or during debug - then the bytes are actually swapped twice to test the related code (see CryCommon/Endian.h).
What can be done to fix it?
You have several options now:
Keep compiling as release only (probably as before). Perhaps you will never be debugging the code in a debugger anyway.
Just comment the swap call in FRead() code out. You are using it to load a text file anyway, no point in swapping the characters around.
...
FWIW, other things I had to do to make your code compile:
Check out the earlier commit before "Broken"
Load Mods\Aurora\Code\Aurora.sln
Remove non-existing .vcprojx projects
Add all 3 .vcproj files again, let them be converted to VS2015 ones
For GameDll project, add preprocessor definition _SILENCE_STDEXT_HASH_DEPRECATION_WARNING
For GameDll project, set enabled C++ exception handling /EHsc
Comment out the code above