Visual Studio - can be a breakpoint called from code? - c++

I have a unit test project based on UnitTest++. I usually put a breakpoint to the last line of the code so that the I can inspect the console when one of the tests fails:
n = UnitTest::RunAllTests();
if ( n != 0 )
{
// place breakpoint here
return n;
}
return n;
But I have to reinsert it each time I check-out the code anew from SVN. Is it possible to
somewhat place the breakpoint by the compiler?:
n = UnitTest::RunAllTests();
if ( n != 0 )
{
// place breakpoint here
#ifdef __MSVC__
#!!!$$$??___BREAKPOINT;
#endif
return n;
}
return n;

Use the __debugbreak() intrinsic(requires the inclusion of <intrin.h>).
Using __debugbreak() is preferable to directly writing __asm { int 3 } since inline assembly is not permitted when compiling code for the x64 architecture.
And for the record, on Linux and Mac, with GCC, I'm using __builtin_trap().

DebugBreak(void)
From Winbase.h.
MSDN

You could use this in C or C++
__asm
{
int 3
}

If you are using VC6 (yes, outdated but still in use in some places/projects), DebugBreak() will work but you may end up in some obscure location deep withing Windows DLLs, from which you have to walk the stack up back into your code.
That's why I'm using ASSERT() in MFC or assert() in "standard" code.
Your example would work like this:
n = UnitTest::RunAllTests();
ASSERT(n == 0);
//assert(n == 0);
return n;
If you don't need a result and want it just for debugging, you can also do
if(0 != UnitTest::RunAllTests())
{
ASSERT(FALSE);
//assert(false);
}

How about using a Debug or Trace method to output the console info. That may be a better approach than relying on breakpoints.

How often do you check out the project from SVN? This is typically something I only do once per project, or when I rebuild my PC.
If you also checkin the project files, the breakpoints should be stored in the project files.
I think it is in the .suo file. You could also put that under SVN control if you wanted, though I prefer not to.

Related

Debug Assertion Failed! Expression: __acrt_first_block == header

I am trying to test the dll which I wrote with GoogleTest and when I call one of the tests It throws me this error:
I have come to the conclusion that the problem is in assigning memory to vectors but I don't know how to resolve this as I am fairly new to C++ programming. The code is as follows:
#ArraysCPP11.h
#ifdef ARRAYSCP11_EXPORTS
#define ARRAYSCP11_API __declspec(dllexport)
#else
#define ARRAYSCP11_API __declspec(dllimport)
#endif
__declspec(dllexport) void removeWhiteSpaces(std::vector<std::string> v, std::vector<std::string> &output);
#ArraysCPP11.cpp
void removeWhiteSpaces(std::vector<std::string> v, std::vector<std::string> &output) { //odstranjevanje presledkov iz vector-ja (vsak drugi element je bil presledek)
for (std::vector<std::string>::iterator it = v.begin(); it != v.end(); it++) {
std::string buffer = *it;
if (isdigit(buffer[0])){;
output.push_back(*it);
}
}
}
#TestTemp.h
template<class T>
class TestTemp
{
public:
TestTemp();
void SetValue(T obj_i);
T GetValue();
bool alwaysTrue();
bool TestTemp<T>::formattingTest(std::string input, std::vector<std::string> realVector, std::vector<std::string> formattedInput);
private:
T m_Obj;
};
template<class T>
inline bool TestTemp<T>::formattingTest(std::string input, std::vector<std::string> realVector, std::vector<std::string> formattedVector) {
std::string input2 = input;
// std::vector<std::string> fResult;
std::string first;
std::string second;
bool endResult = true;
std::vector<std::string> end;
//std::vector<std::string> result = split(input2, ' ');
removeWhiteSpaces(formattedVector,end);
std::vector<std::string>::iterator yt = realVector.begin();
for (std::vector<std::string>::iterator it = end.begin(); it != end.end(); it++, yt++) {
first = *it;
second = *yt;
if (first.compare(second) != 0) {
endResult = false;
break;
}
}
return endResult;
}
#ArraysCPP11-UnitTest.cpp
struct formattingTesting{
// formattingTesting* test;
std::string start;
std::vector<std::string> endResult;
formattingTesting() {
}
explicit formattingTesting(const std::string start, const std::vector<std::string> endResult)
: start{start}, endResult{endResult}
{
}
};
struct fTest : testing::Test {
formattingTesting* test;
fTest() {
test = new formattingTesting;
}
~fTest() {
delete test;
}
};
struct format {
std::string start;
std::vector<std::string> end;
};
struct formTest : fTest, testing::WithParamInterface<format> {
formTest() {
test->start = GetParam().start;
test->endResult = GetParam().end;
}
};
TEST_P(formTest, test1) {
bool endResult = true;
TestTemp<int> TempObj;
std::string first;
std::string second;
//std::string start ("1 2 3 4 5 6 7 8 9 10");
//std::vector<std::string> end = { "1","2","3","4","5","6","7","8","9","10" };
std::vector<std::string> start2 = { "1","","2","3","4","5","6","7","8","9","10" };
std::string start = GetParam().start;
std::vector<std::string> end = GetParam().end;
bool result = TempObj.formattingTest(start,end,start2);
EXPECT_TRUE(result);
}
INSTANTIATE_TEST_CASE_P(Default, formTest, testing::Values(
format{ "1", {"1"} },
format{ " ", {} },
format{ "1 2 3 4 5",{"1","2","3","4","5"} },
format{ "1 2 3 4 5 6", {"1","2","3","4","5","6"} }
));
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
RUN_ALL_TESTS();
return 0;
}
As this is a DLL, the problem might lie in different heaps used for allocation and deallocation (try to build the library statically and check if that will work).
The problem is, that DLLs and templates do not agree together very well. In general, depending on the linkage of the MSVC runtime, it might be problem if the memory is allocated in the executable and deallocated in the DLL and vice versa (because they might have different heaps). And that can happen with templates very easily, for example: you push_back() to the vector inside the removeWhiteSpaces() in the DLL, so the vector memory is allocated inside the DLL. Then you use the output vector in the executable and once it gets out of scope, it is deallocated, but inside the executable whose heap doesn't know anything about the heap it has been allocated from. Bang, you're dead.
This can be worked-around if both DLL and the executable use the same heap. To ensure this, both the DLL and the executable must use the dynamic MSVC runtime - so make sure, that both link to the runtime dynamically, not statically. In particular, the exe should be compiled and linked with /MD[d] and the library with /LD[d] or /MD[d] as well, neither one with /MT[d]. Note that afterwards the computer which will be running the app will need the MSVC runtime library to run (for example, by installing "Visual C++ Redistributable" for the particular MSVC version).
You could get that work even with /MT, but that is more difficult - you would need to provide some interface which will allow the objects allocated in the DLL to be deallocated there as well. For example something like:
__declspec(dllexport) void deallocVector(std::vector<std::string> &x);
void deallocVector(std::vector<std::string> &x) {
std::vector<std::string> tmp;
v.swap(tmp);
}
(however this does not work very well in all cases, as this needs to be called explicitly so it will not be called e.g. in case of exception - to solve this properly, you would need to provide some interface from the DLL, which will cover the vector under the hood and will take care about the proper RAII)
EDIT: the final solution was actually was to have all of the projects (the exe, dll and the entire googleTest project) built in Multi-threaded Debug DLL (/MDd)
(the GoogleTest projects are built in Multi-threaded debug(/MTd) by default)
I had a similar problem and it turned out that my unittest project was set to a different code generation runtime library - so by setting it to the same as the DLL project, then no heap exception
That verification was implemented by Microsoft software developers a long time ago in 1992 - 1993 and it is No Longer valid since in case of Heterogeneous or MPI programming a new memory Could Be allocated Not from a Local Heap.
When an application gets a memory using OpenCL or CUDA APIs a GPU driver does all memory allocations and, of course, it doesn't use the Local Heap of the application. However, the application should release the memory before it exits. At that time Microsoft's Memory Leaks Detection API detects it and that assert is displayed.
Please take a look at a Video Technical Report regarding origins of that verification:
Origins of MS Visual Studio 2015 Assert __acrt_first_block == header ( VTR-010 )
https://www.youtube.com/watch?v=NJeA_YkLzxc
Note: A weblink to the youtube video updated since I've uploaded a video with some corrections.
I encountered the same error and I found a way to get more information about the cause of the problem: It is possible to set with visual studio a breakpoint condition on the line that raise this error (so that the debugger breaks before the error message).
It is necessary to open the corresponding file (debug_heap.cpp,somewhere in "C:\Program Files (x86)\Windows Kits\10\Source") and to write the following condition:
Then we can continue debugging and when the breakpoint is hit, we can observe the address of the block that raise the error (the "block" argument of the "free_dbg_nolock" function that contains the breakpoint).
From there you can observe the memory content of the block by copying the address into the memory window (Debug->Windows->Memory). If you are lucky it may be a string or an easily recognizable variable.
You can then identify the variable that causes the bug and try to fix it.
In my case it was a variable that was created in one dll and deleted in another. To correct it I replaced all my objects by pointers to these objects in one dll.
I had the same issue with Microsoft visual studio 2019, simply fixed by changing the "Runtime library" to " Multi-Threaded Debug DLL (/MDd)"
right click on solution on "Solution Explorer" -> "properties" -> "C/C++" -> "Code Generation" , and change "Runtime library" to " Multi-Threaded Debug DLL (/MDd)"
I was seeing this error too and in my case I had all the memory model settings lined up correctly. However having recently upgraded the projects from vs2013 to vs2015 I had stale references between the .exe and .dll, so in fact I was using the old DLL built with 2013. I had to remove the reference between the .exe and .dll and re-add it to update the name of the .lib that the exe was linking against. (Right click on the "References" child item of the .exe project and "Add", while confusingly also allows you to remove a reference).

Internal compiler error in condition with bool property

lately I have been faced with a strange problem that a simple source did not want to compile. I was looking for solutions (and cause) in many sites but without good effects (except bugs reports but I have not found there direct cause ).
Below I present simple code to reproduce that situation:
struct Foo {
Foo() : m_x( true ) {}
__property bool x = { read=m_x };
private:
bool m_x;
};
template<typename T>
struct TMyPointer {
T * m_ptr;
TMyPointer( T * ptr ) : m_ptr( ptr ) {}
~TMyPointer()
{
delete m_ptr;
}
T * operator->() const
{
return Get();
}
T * Get() const
{
if( m_ptr == NULL )
; // some error handling
return m_ptr;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
TMyPointer<Foo> bar( new Foo );
if( bar->x && 1 == 1 ) ; // Failed
if( 1 == 1 && bar->x ) ; // OK
if( !!bar->x && 1 == 1 ) ; // OK
if( bar->x == true && 1 == 1 ) ; // OK
if( (bar->x) && 1 == 1 ) ; // OK
return 0;
}
Compiler has failed to compile first condition inside main function. What stranger compilation of other equivalent conditions is finished successfully.
That's behavior I have only during release compilation. To reproduce I have used Embarcadero® C++Builder® XE5 Version 19.0.13476.4176
Error message: [bcc32 Fatal Error] File1.cpp(43): F1004 Internal
compiler error at 0x14470090 with base 0x14410000
Anybody knows what is the problematic in above example? Maybe usage templates with properties mechanism is the cause?
In my case is simple solution it seems to be problematic condition inside Get method. When I change
if( m_ptr == NULL )
to equivalent form
if( !m_ptr )
everything compile without errors.
I am writing about it here becouse I would like to share my insights - it can be helpfully for somebody.
recently I got similar ICE (once my source code grows in size) and your solution seemingly helped for a while but not really as after some minor changes in code ICE resurfaced again. Based on the behavior of mine problem:
IDE: BDS2006 Turbo C++ explorer (its version of BCB between BCB6 and RAD)
Huge win32 project (several MBytes of code involving USB,OpenGL,CAD/CAM)
Each part of code is tested for years and compilable separably problem occurs once they together and code grows too big
Project compiles fine at first run but after that any recompile fails
The temporary workaround was to close IDE, delete all obj,tds,exe,... files restart IDE and compile again.
I assumed compiler and or IDE leaks or overwrites some parts of itself corrupting its functionality. As the problem persist after IDE restart without deleting temp files I assumed it has something to do with debug info stored in them.
So I played with Project->Options->Debugging settings and turning off this:
Inline function expansion (-vi)
Helped (not even IDE restart or temp file removal was needed).
Don't have enough reputation to upvote or comment someone else's posts, but I have recently found the same solution as in #Spektre reply.
Disabling Inline function expansion fixed our multiple-year problems with completely unrelated internal compiler errors on random projects. We only experienced them on MSBUILD scripts in Release config.
I found this out by going over all the compiler options in Release config that were different from Debug config and changed them one-by-one to match Debug config through msbuild parameters for the entire solution/projectgroup. And eventually it started to build without any errors when I've disabled Inline function expansion option.
These problems happened and I confirmed the fix on C++ Builder XE5;
This kept on resurfacing at random for as long as I can remember (Borland C++ 2006 and later)
The older developers used to try and revert latest commits until it started compiling again... Which is a pain in the behind.
Anyone looking for solution to pass a parameter to an MSBUILD command (for all targets in the script) add this line to the msbuild.exe call:
msbuild.exe Targets.xml /p:BCC_InlineFunctionExpansion=false /t:Build

Visual Studio 2010 O2 optimization give wrong result?

int listenPort()
{
//if (server)
//{
// return server->port();
//}
//std::cout << server->port() << std::endl;
//return 0;
//add below 2 lines only to make it work right under Realease.
//std::fstream f("Z:/fsfasjlfjal.txt");
//f.close();
if (_listenPort != -1)
{
return _listenPort;
}
return 0;
}
I have one function named listenPort, variable _listenPort has been set to -1 in construct function, I want to check its value. When it changes return it or return 0.
I use Visual Studio 2010 to compile the code, DEBUG everything is OK. But when I change to Release(/O2), function always return 0. I tried add two lines code: fstream open and close. Now it seems everything is right.
But this solution is ugly, I just open and close some file. What should I do? Thanks.
One not recommended solution is to make replace int _listenPort; with volatile int _listenPort;. Read this to understand why this solution is not recommended.
A good solution would use synchronized writing and reading of _listenPort.
Or As I suggested before move definitions of class to a different file. This way, compiler won't inline your code and function will return expected value.
You're probably trying to run a debugger on an optimised (/O2) code and set breakpoints in your function. This is not going to work. Compiler is free to change order of your code as it sees fit, provided that the outcome of the code is the same as if it were untouched.
If you really want to test some values with optimised code, you need to log the values somewhere (a file) or print them out in the console.

C++ DLL returning pointer to std::list<std::wstring>

I got a dll with the following prototype:
DLL_EXPORT std::list<std::wstring>* c_ExplodeWStringToList(std::wstring in_delimiter, std::wstring in_string, int in_limit);
The application uses this like that:
std::list<std::wstring>* exploded = mydllclass->c_ExplodeWStringToList(L" ", in_command.c_str(), 0);
This works great under XP 32, but when I try this at home with my Vista 64 my program just closes itself. No error and no warning?
Some days ago the DLL was returning the list directly - no pointer. But I switched to VC++ 2010 Express, and I could not compile my DLL without this modification.
Anything I am not seeing here?
Thank you :)
Update:
DLL_EXPORT std::list<std::wstring>* c_ExplodeWStringToList(std::wstring in_delimiter, std::wstring in_string, int in_limit)
{
std::list<std::wstring>* returnlist = new std::list<std::wstring>();
std::list<std::wstring>* stringlist = new std::list<std::wstring>();
UINT pos = 0;
while(true)
{
pos = in_string.find(in_delimiter, 0);
if(pos == std::string::npos)
{
stringlist->push_back(in_string.substr(0, pos));
break;
}
else
{
stringlist->push_back(in_string.substr(0, pos));
in_string = in_string.substr(pos + in_delimiter.length());
}
}
// ****
// Here is missing some code I've commented out while searching for the error.
// ****
returnlist = stringlist;
return returnlist;
}
T
I didn't dig into the code, but a conclusion I came to regarding working with DLLs is to not return anything but primitive types from DLL functions. This is because due to different compilers or different switches or project settings structs and classes are not aligned the same not have the same size in the DLL and in the code calling the DLL.
So returning a list from a DLL might be considered malformed in the caller application.
Same thing regards throwing exceptions from a DLL - the class thrown might be misinterpreted by the catching code.
So, best is export only C functions that return primitive types (to denote error codes).

_matherr does not get called in release build (C++ Builder 2007)

I have a code with possible floating point overflows which cannot be managed by checking arguments of functions. I have to define _matherr and throw an exception from inside it in order to give a chance to caller to manage the problem.
There is something strange: in Debug build, _matherr is called as supposed, but not in Release. I use CodeGear C++ Builder 2007. Under MSVC 2010 the handler works fine, but I need VCL features for the whole application. Googling gives nothing but messages about _matherr not working in DLL (that is known from documentation).
And my question is: what could be the reason for _matherr to not work in Release?
// One of the methods with overflows.
double DoubleExponential::F(double x) const
{
try
{
double y=pow(fabs(x),a);
return 0.5 + sign(x)*G(y,1/a)/(2*G(1/a));
}
catch(PowExpOverflow)
{
return 0.5;
}
}
// Exception.
struct PowExpOverflow {};
int _matherr (struct _exception *a){
Application->MessageBox("Inside custom _matherr", "", MB_OK);
if (a->type == OVERFLOW)
if (!strcmp(a->name,"pow") ||
!strcmp(a->name,"powl") ||
!strcmp(a->name,"exp") ||
!strcmp(a->name,"expl"))
{
throw PowExpOverflow();
}
return 0;
}
The problem is due to bug in the dynamic RTL which I use in the release build (description). The bug was not fixed in the version of IDE I use, so the only working solution is to upgrade to a higher version. Nevertheless, having a clear explanation helps a lot.