I have some c++ code but I don't know what. For the purposes of example let's say it is:
//main.cpp
#include<iostream>
using namespace std;
int T[100];
int main()
{
for(int i = 0; i < 100; ++i)
T[i] = i;
int x;
cin>>x;
cout<<T[x]<<endl;
return 0;
}
I'm compiling it by cl /O2 /nologo /EHsc main.cpp and running by main < inFile.in. Let's say that inFile.in content is one number 500 and new line. The output is some random number because program reads memory under the address T+500 and printing it.
I want to get runtime error in such cases (any possibility of checking is something like this happened). Is this possible without access to main.cpp?
To be specific I'm running all this programmatically by Process class in C# in ASP.Net MVC Application. I want to check did program threw exception / read not reserved memory etc.
Is this a feature you want to use for development purposes only, or also in your production environment?
In case of development purposes only you may try to run your application under some tool for runtime checking (like Valgrind/Dr Memory), or change the way you compile it to include runtime debug checks (is not guaranteed to work in described case, but helps in many others). Keep in mind that this will make your application much slower (thus should be used only for applications under development)
When it comes to production environment, I am not aware of any way of doing what you want to - in general you can only count on OS segmentation fault in case of reading out of available memory (if you have luck - if you don't it'll "work").
For the exception thing, I'm not 100% sure I understand what you mean - is this "why did the program terminate" ? In such case on you might get a core dump of crashed application (in case of normal termination I assume you have return codes), and you can inspect it later to either get crash reason or possibly also try to recover some data. For instructions how to collect dumps on Windows, you may check out:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb787181%28v=vs.85%29.aspx
However, this is also a feature that is more useful in development environment than in production.
If You can't modify above program's source then run it in 'outside' environment (shell) and get returned value and test it against 0 - any other value would me incorrect behavior.
It is also good to verify such programs' input data that you know it can't handle so rather than waiting for it to crash you can prevent it from happening.
If You could modify program then simple solution would be to use std::vector or std::deque which are similar but important is to use at() method and not the operator[] operator as the at() method checks bounds
#include<iostream>
#include<vector>
using namespace std;
std::vector<int> T(100);
int main()
{
for(int i = 0; i < 100; ++i)
T[i] = i;
int x;
cin>>x;
cout<<T.at(x)<<endl;
return 0;
}
if at() will be called with bad out-of-bound parameter then exception will be throw which You can catch like this:
try{
cin>>x;
cout<<T.at(x)<<endl;
}
catch(...)
{
cout << "exception while accessing vector's data" << endl;
}
Related
I have a class where I define a circular buffer like so:
class cTest
{
public:
boost::circular_buffer<std::vector<std::pair<double, double>>> circDat;
cTest() : circDat(1000)
{
}
};
I then create a stl vector of type cTest
std::vector<cTest> vC;
Afterwards I try to fill the vector like this:
for (unsigned int i = 0; i < 4; ++i)
{
cTest obj;
vC.push_back(obj);
}
While this works in Debug mode, in Release, it crashes (sometimes, when I run with from Visual Studio, I get a Heap Corruption message). The boost documentation mentions, that in Debug mode, the uninitialized memory is filled with '0xcc'. I assume, the error I get, has its root in uninitialized memory. But I am not really sure, how to fix this problem.
If I use pointers, it seems to work:
std::vector<cTest*> vC;
for (unsigned int i = 0; i < 4; ++i)
{
cTest* obj = new cTest;
vC.push_back(obj);
}
But I still do not know, what the problem with the first version is. If anyone does know, I'd appreciate the help.
Edit:
I've tried to create a minimal, reproducable code but failed. It also seemed to crash randomly, not really correlating to the lines added/removed. I then stumbled on the /GL flag in Visual Studio 2015.
After turning the /GL flag off (in the GUI project - in the library project it can stay on), I've been unable to recreate the crash. I do not know, if this is really a fix. But it seems like there was a similar problem present in Visual Studio 2010:
crash-in-program-using-openmp-x64-only
Edit2:
I've managed to pull together a minimal working example. The code can be downloaded here:
https://github.com/davidmarianovak/crashtest
You need Boost (I used 1.60) and QT5 (I used 5.6.3). Build GoAcquire in Release (/GL is active in Visual Studio). Afterwards, build GoGUI in Release (activate /GL and use 'standard' for link-time code generation). After you've built it, run it and it should crash.
The crash can be avoided by changing this in 'GoInterface.hpp' line 22:
void fillGraphicsViews(std::vector<cSensorConstruct> vSens);
to
void fillGraphicsViews(std::vector<cSensorConstruct> &vSens);
But I do not really believe that it is the problem. Can anyone tell me, what I'm doing wrong? I'm using Visual Studio 2015 for this.
I bet you're forgetting about iterator/reference invalidation. So the problem is not with the code shown.
Iterator invalidation rules
This makes sense since you report that pointers seem to work: the pointers stay the same even if push_back causes reallocation.
Simply don't hold on to references/iterators to vector elements when you don't know that they're going to stay valid.
If your vector has a known maximum size, you could "cheat" by reserving the capacity ahead of time:
static constexpr size_t MAX_BUFFERS = 100;
std::vector<cTest> vC;
vC.reserver(MAX_BUFFERS); // never more
And then perhaps guard the invariant:
assert(vC.size() < MAX_BUFFERS);
vC.push_back(obj);
Let's start with a minimal working example:
main.cpp:
#include <iostream>
#include <string>
int main() {
std::cout << "hello " + std::to_string(42);
return 0;
}
I compile this code using the following flags:
[g++/clang++] -std=c++11 -g -Og --coverage -Wall -o main main.cpp
clang 4.0.1
gcc 4.8.5.
I get only 50% code coverage, since the compiler generates exception code, which is not executed, as explained in another stackoverflow question.
The problem is that disabling exceptions via -fno-exceptionsis not an option for me. The code I am writing unit tests for uses exceptions, so disabling all of them is not an option.
In order to generate a report I'm using gcovr, in case of clang++ additionally llvm-cov gcovto convert it. But I am not bound to these tools, so if you have other tools that do not show this behaviour please suggest them!
Basically I need a way to compile/write unit tests for this code and get 100% branch / conditional coverage with exceptions enabled. Is there a way?
Well, I believe your intention is not actually test this small piece of code, but use the concept in a project...
The code you entered throws an exception - bad_alloc is thrown when you have no memory left to store the string that will be created with std::to_string. To be 100% safe, std::to_string should be surrounded with try-catch, where you could handle your exception.
To build a 100% code coverage unit test, you will need to force the exception to happen - in this specific case it is almost impossible to guarantee, since the parameter is a constant number. But, in your project, you probably have some data to be allocated whose size is variable - in this case, you can isolate in your code the methods that allocate memory, to test them separately. Then you pass to these methods, in the test function, a huge amount to be allocated to evaluate what you have put on your catch block (and check if you are handling it properly).
For instance, this code should throw the exception, you could use it to inspire yourself when building your tests (source):
// bad_alloc.cpp
// compile with: /EHsc
#include<new>
#include<iostream>
using namespace std;
int main() {
char* ptr;
try {
ptr = new char[(~unsigned int((int)0)/2) - 1];
delete[] ptr;
}
catch( bad_alloc &ba) {
cout << ba.what( ) << endl;
}
}
However, if you are not planning to handle all bad_alloc exceptions (or absolutely all exceptions) in your code, there is no way to get 100% coverage - since it won't be 100% covered... Most of the cases, true 100% coverage is unnecessary, though.
I've been studying C++ for two months and now I'm studying the chapter in my book (Programming Principles and Practice using C++) about errors. But after studying the first pages I have a question: what is the difference between a runtime error and a logic error? According to my book a runtime error is an error found by checks at runtime and we can further classify runtime errors as:
hardware error / operating system error
errors detected by a library
errors detected by user code (what is user code?)
while logic errors are simply errors found by the programmer looking for the causes of erroneous results.
I thought I had understood this difference but then an example provided by the author created doubts in me. This is the example:
#include "std_lib_facilities.h"
int area(int lenght, int width) // calculate area of rectangle
{
return lenght * width;
}
int framed_area(int x, int y) // calculate area within frame
{
return area(x - 2, y - 2);
}
int main()
{
int x = -1;
int y = 2;
int z = 4;
int area1 = area(x, y);
int area2 = framed_area(1, z);
int area3 = framed_area(y, z);
double ratio = double(area1) / area3;
}
Here is what the author briefly says about this example :
the calls of the function area() and framed_area() lead to negative
values, representing areas, being assigned to area1 and area2. Should
we accept such erroneous results? But before answering these question
look at the calculation of ratio, in the calculation of ratio area3
will be 0 and the division with 0 will lead to hardware-detected error
that terminates the program with some cryptic message. This is the
kind of error that you, or your user, will have to deal with if you
don't detect and deal sensibly with runtime errors.
What I don't understand here is why a negative value used as an argument for a function that calculates the area is treated as a runtime error, isn't it just a logic error? I thought that runtime errors were only errors due for example by dividing a number by 0 and other special cases. Am I wrong or am I just misunderstanding something? What is the real difference between logic errors and runtime errors? Could you show me some little examples?
A runtime error may legitimately happen: e.g. some file containing garbage data, or some wrong human input, or some lack of resource (no more memory, disk space full, broken hardware, network connection failure).
A logic error (or a failing assert ....) is by definition always the symptom of some bug in the program, e.g. a supposedly sorted array used for dichotomical access which happens to be unsorted.
See the documentation of <stdexcept> header:
std::logic_error: This class defines the type of objects thrown as exceptions to report errors in the internal logical of the program, such as violation of logical preconditions or class invariants.
std::runtime_error: This class defines the type of objects thrown as exceptions to report errors that can only be detected during runtime.
I believe that internal logical for std::logic_error is a typo, I understand it as internal logic (of the program), but I am not a native English speaker.
If you formalize the specification of your program (e.g. with the help of Frama C using ACSL), you might find (and perhaps correct) logic errors; but you should care about runtime errors. But you could also have bugs in specification.
Read about Ariane 5 flight 501 failure. And look into J.Pitrat's blog to get some other views.
Your book is certainly right in the first sub-division, compile-time vs. run-time.
If you can, make sure you get the former instead of the latter, as it's automatically detected.
It's also right that both can be further sub-divided, but let us only look at the latter:
External error: hardware-error / operating-system error
Many of those are expected, like the network being unreliable, a user-file missing, and the like. Often, one can recover from them.
Others are unexpected, and often unrecoverable, like a missing required dependency, unreliable RAM, running out the clock, and the like. Expect to simply crash-and-burn.
Input error: Mangled input-data, missing input-data, whatever.
This should be detected by your application, which depending on severity of the error might substitute defaults, try to recover it or just crash-and-burn.
Logic error: The fundamental assumptions of the program have been found wanting.
Nothing can be depended on to hold any longer, the only sane option is to crash-and-burn immediately to try and contain the damage.
Common logic-errors are fencepost-errors (off-by-one), race-conditions, use-after-free and the like.
Be aware that std::logic_error, despite its name, need not always signify a fatal breakdown in the programs logic, and thus might be expected and relatively benign.
With regards to the example you provided, providing negative input to the method calculating area is a logical error because you already (as the developer of the application) know that this is wrong. But assume that you wrote the method to calculate the area and you gave this to a user who does not know what calculating area is about - he may provide input which is incorrect and this would lead to incorrect results. In this case, it would be a runtime error as the user is unaware and there is no error checking in place.
Logic errors are due to flaws in the thinking of the programmer and are preventable. For example, forgetting to safeguard against out of bounds errors in an array.
Runtime errors, on the other hand, arise from computer architecture and operating system and are beyond the control of the programmer and cannot be predicted easily during coding.
#include <iostream>
using std::cout;
using namespace std;
int area(int lenght, int width) // calculate area of rectangle
{
return lenght * width;
}
int framed_area(int x, int y) // calculate area within frame
{
return area(x - 2, y - 2);
}
int main()
{
int x = -1;
int y = 2;
int z = 4;
int area1 = area(x, y);
int area2 = framed_area(1, z);
int area3 = framed_area(y, z);
double ratio = double(area1) / area3;
cout<<area1<<endl
<<area2<<endl
<<area3<<endl
<<ratio<<endl;
system("pause");
return 0;
}
How about trying this there is no runtime error,I don't know how you can see the output result without cout .
I am a new leaner too , I think it is important to practice in short periods of time when studying .
This is just my suggestion as two answers above has well explained .
Runtime error is happening when your computer system(operating system and / or firmware) has to handle unpredicted instructions. Most of the time, your program is crashed when a runtime error is occurred. For example, a memory leak which is an allocation of new memory that is never deallocated. However, logic error can be easily recognized when you have an unpredicted behavior in your program. Let's say you expect your program to add two numbers but instead it multiplies them. This is a type of logic error that can be fixed just by using the right operator.
Hopefully this helps
From my experience with myself :) …
The confusion may stem from our “making life simple” by re-using std exception logic when we are supposed to build one for ourselves. The std exceptions are to be caught (not thrown) by our code. They inform us what has happened when calling a function from the std library and the logic of the exception inheritance tree is not simply transferable outside the library.
std::runtime_error tells us Huh! Something unpredictable has happed
std::logic_error tells us Ohoh! You omitted something important in your code
Your boss can write a program like
try { mainCall(); }
catch (const std::logic_error &) { std::cout << "No premiums this year!"; }
catch(const std::runtime_error &) { std::cout << "I know it’s not your fault..."; }
Now the problem arises when we want to re-use this logic in our code. The exceptions are there, ready for use, with the std::string constructors and the .what() method, so why to reinvent the wheel, right?
Now the dilemma comes:
double a,b;
std::cin >> a;
std::cin >> b;
if (b == 0) EXCEPTION;
else std::cout << a/b;
So what is the EXCEPTION like? Is it a runtime_error or a logic_error?
Did something unpredictable happen? Could we have expected that a user enters 0 for b? Yes we could and we , indeed, did! So it must not be the runtime_error.
Did we omitted something important in our code? No, we did not! So it must not be the logic_error either.
We intuitively tend to assign runtime_errors to hardware errors and logic_errors to “logical” errors – thus one would opt for logic_error in the example above. But intuition is often a bad guide in programing... just supply your code into your boss’ test unit ;)
Conclusion:
Derive your own exception tree starting from the std::exception (or whatever) or do not try to solve the runtime/logic_error dilemma. It does not have a solution outside the std library domain…
You might call me crazy after reading this post, but I would really request you to trust me when you read what I say here. In my attempt to understand situations where memory leak or other errors could be caused, I wrote the following code and tried compiling on my pc,
#include <iostream>
using namespace std;
class game
{
int x;
public :
char *s;
char read();
char manipulation();
};
char game :: read()
{
char string[100];
cout<<"Enter name ";
cin>>string;
s = string;
cout<<"Name is "<<&s<<endl;
}
int main()
{
game games,games1;
// games.read();
cout<<"Name is "<<games.s<<endl;
return 0;
}
If i execute games.read() in my main, my anti-virus software BITDEFENDER shows me the following error, "BITDEFENDER has detected an infected item in c:/c++/inline.exe. Virus name : Gen:Variant.Graftor.51542. The file was disinfected for your protection"
inline.cpp is the name of my program.
If i remove that line "games.read()", it compiles fine. Is the pointer causing a memory leak somewhere?
Your anti-virus program just found a use-after-free vulnerability.
string is a local array.
You can't use it after read() exits.
If your system claims your code is a virus, then it's nothing to worry about in the sense that you are losing your mind; you are not.
Virus scanners will look for patterns of behaviors consistent with viruses and report them. They are not perfect, and non-virus behavior can look like a virus at times.
For instance, a classic virus strategy is to use invalid pointer writes to run arbitrary code. One of the first viruses used this and it's still a common strategy (I recall an IE update not long ago to fix this). So if you have a pointer error (as the previous poster noted) then it could look like a virus.
Is there any way a program can crash before main()?
With gcc, you can tag a function with the constructor attribute (which causes the function to be run before main). In the following function, premain will be called before main:
#include <stdio.h>
void premain() __attribute__ ((constructor));
void premain()
{
fputs("premain\n", stdout);
}
int main()
{
fputs("main\n", stdout);
return 0;
}
So, if there is a crashing bug in premain you will crash before main.
Yes, at least under Windows. If the program utilizes DLLs they can be loaded before main() starts. The DllMain functions of those DLLs will be executed before main(). If they encounter an error they could cause the entire process to halt or crash.
The simple answer is: Yes.
More specifically, we can differentiate between two causes for this. I'll call them implementation-dependent and implementation-independent.
The one case that doesn't depend on your environment at all is that of static objects in C++, which was mentioned here. The following code dies before main():
#include <iostream>
class Useless {
public:
Useless() { throw "You can't construct me!"; }
};
static Useless object;
int main() {
std::cout << "This will never be printed" << std::endl;
return 0;
}
More interesting are the platform-dependent causes. Some were mentioned here. One that was mentioned here a couple of times was the usage of dynamically linked libraries (DLLs in windows, SOs in Linux, etc.) - if your OS's loader loads them before main(), they might cause your application do die before main().
A more general version of this cause is talking about all the things your binary's entry point does before calling your entry point(main()). Usually when you build your binary there's a pretty serious block of code that's called when your operating system's loader starts to run your binary, and when it's done it calls your main(). One common thing this code does is initializing the C/C++ standard library. This code can fail for any number of reasons (shortage of any kind of system resource it tries to allocate for one).
One interesting way on for a binary to execute code before main() on windows is using TLS callbacks (google will tell you more about them). This technique is usually found in malware as a basic anti-debugging trick (this trick used to fool ollydbg back then, don't know if it still does).
The point is that your question is actually equivalent to "is there a way that loading a binary would cause user code to execute before the code in main()?", and the answer is hell, yeah!
If you have a C++ program it can initialize variables and objects through functions and constructors before main is entered. A bug in any of these could cause a program to crash.
certainly in c++; static objects with contructors will get called before main - they can die
not sure about c
here is sample
class X
{
public:
X()
{
char *x = 0;
*x = 1;
}
};
X x;
int main()
{
return 0;
}
this will crash before main
Any program that relies on shared objects (DLLs) being loaded before main can fail before main.
Under Linux code in the dynamic linker library (ld-*.so) is run to supply any library dependancies well before main. If any needed libraries are not able to be located, have permissions which don't allow you to access them, aren't normal files, or don't have some symbol that the dynamic linker that linked your program thought that it should have when it linked your program then this can cause failure.
In addition, each library gets to run some code when it is linked. This is mostly because the library may need to link more libraries or may need to run some constructors (even in a C program, the libraries could have some C++ or something else that uses constroctors).
In addition, standard C programs have already created the stdio FILEs stdin, stdout, and stderr. On many systems these can also be closed. This implies that they are also free()ed, which implies that they (and their buffers) were malloc()ed, which can fail. It also suggests that they may have done some other stuff to the file descriptors that those FILE structures represent, which could fail.
Other things that could possibly happen could be if the OS were to mess up setting up the enviromental variables and/or command line arguments that were passed to the program. Code before main is likely to have had to something with this data before calling main.
Lots of things happen before main. Any of them can concievably fail in a fatal way.
I'm not sure, but if you have a global variable like this :
static SomeClass object;
int main(){
return 0;
}
The 'SomeClass' constructor could possibly crash the program before the main being executed.
There are many possibilities.
First, we need to understand what actually goes on before main is executed:
Load of dynamic libraries
Initialization of globals
One some compilers, some functions can be executed explicitly
Now, any of this can cause a crash in several ways:
the usual undefined behavior (dereferencing null pointer, accessing memory you should not...)
an exception thrown > since there is no catch, terminate is called and the program end
It's really annoying of course and possibly hard to debug, and that is why you should refrain from executing code before main as much as possible, and prefer lazy initialization if you can, or explicit initialization within main.
Of course, when it's a DLL failing and you can't modify it, you're in for a world of pain.
Sort of:
http://blog.ksplice.com/2010/03/libc-free-world/
If you compile without standard library, like this:
gcc -nostdlib -o hello hello.c
it won't know how to run main() and will crash.
Global and static objects in a C++ program will have their constructors called before the first statement in main() is executed, so a bug in one of the constructors can cause a crash.
This can't happen in C programs, though.
It depends what you mean by "before main", but if you mean "before any of your code in main is actually executed" then I can think of one example: if you declare a large array as a local variable in main, and the size of this array exceeds the available stack space, then you may well get a stack overflow on entry to main, before the first line of code executes.
A somewhat contrived example would be:
int a = 1;
int b = 0;
int c = a / b;
int main()
{
return 0;
}
It's unlikely that you'd ever do something like this, but if you're doing a lot of macro-magic, it is entirely possible.
class Crash
{
public:
Crash( int* p )
{ *p = 0; }
};
static Crash static_crash( 0 );
void main()
{
}
I had faced the same issue. The root-cause found was.. Too many local variables(huge arrays) were initialized in the main process leading the local variables size exceeding 1.5 mb.
This results in a big jump as the stack pointer is quite large and the OS detects this jump as invalid and crashes the program as it could be malicious.
To debug this.
1. Fire up GDB
2. Add a breakpoint at main
3. disassemble main
4. Check for sub $0xGGGGGGG,%esp
If this GGGGGG value is too high then you will see the same issue as me.
So check the total size of all the local variables in the main.
Sure, if there's a bug in the operating system or the runtime code. C++ is particularly notorious for this behaviour, but it can still happen in C.
You haven't said which platform/libc. In the embedded world there are frequently many things which run before main() - largely to do with platform setup - which can go wrong. (Or indeed if you are using a funky linker script on a regular OS, all bets are off, but I guess that's pretty rare.)
some platform abstraction libraries override (i personally only know of C++ libraries like Qt or ACE, which do this, but maybe some C libraries do something like that aswell) "main", so that they specify a platform-specific main like a int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ); and setup some library stuff, convert the command line args to the normal int argc, char* argv[] and then call the normal int main(int argc, char* argv[])
Of course such libraries could lead to a crash when they did not implement this correctly (maybe cause of malformed command line args).
And for people who dont know about this, this may look like a crash before main
Best suited example to crash a program before main for stackoverflow:
int main() {
char volatile stackoverflow[1000000000] = {0};
return 0;
}