Why does my code crash? - c++

This is a rather general question.
If you have a programm with many many lines of code, let's say C++. Durring compilation everything runs fine, no warnings no errors. But during executing the programm suddenly freezes, which leads to a crash.
How does one solve this problem, if you have pretty much no information from where this could happening (could be loops, could be pointer, could be wrong initialization, could be ...).
Are there any techniques, or profilers that track the current line of the programm execution ?

Your question is too broad, and there is no general answer. In general, the bug is yours (don't suspect at first the compiler or the implementation to be wrong, almost always you are wrong, not the system!).
First, read carefully about the Halting Problem and Undecidable Problem.
Then, be extremely cautious of undefined behavior (UB) in your code (not all of them give segmentation faults, see this). C++ (& C) code can have a lot of them. Some languages (Haskell, Scheme, Common Lisp....) are better specified and have much less UB.
Concretely,
enable all warnings and debug info in your compiler, so compile with g++ -Wall -Wextra -g if using GCC (or likewise with Clang/LLVM). Sometimes you'll be happy to use some sanitizers, e.g. compile with some -fsanitize= flags.
learn how to use the debugger (e.g. gdb), and also valgrind
learn much more about C++, since it is a difficult language.
understand and follow coding rules and guidelines (e.g. the rule of 5).
be curious and learn many other languages and concepts (so read SICP and learn Scheme).
You'll need ten years to learn programming, so be patient.
PS. My biased advice is to install Linux on your laptop.

Related

Deal with project which may contain undefined behaviour

I would like advice how to proceed in such situation.
Imagine I have large C++ project which works well.
I have suspicion there might be some UB in this code (because in different project written by same author I found UB).
Now, say I need to add new features to this project.
I am afraid because:
if I recompile with new compiler this can increase risk of UB happening if in the code is UB already. (e.g. new compiler might not be OK with UB which the old compiler was fine with).
Is it realistic to eliminate all UB in this large project by eye inspection (before I move to adding new feature)??
If not, then I should at least compile with same version of compiler right? (to decrease chance of problems if there is UB).
Project is done in Visual Studio so I don't know if there are object files, in which case, I could leave object files same and only modify parts in files where I need to add something - thus again minimizing risk of UB.
What is the course of action in such situation? I think this could be pretty common scenario.
I like suggestion that I test the project using new compiler before adding new code, but even then - we know testing might not reveal UB, isn't it?
In order, I would:
Compile with -Wall (/W4 for you Windows folk) and fix errors.
Write tests if there aren't any already.
Use tools like valgrind to detect issues and fix them.
Study synchronization primitives if in use, and use modern paradigms where possible.
Document the code and adhere to a style guide.
I would not attempt to avoid problems by keeping object files around. That's a nightmarish maintenance problem.
Undefined Behavior = Bugs
It's impossible to prove that a project is bug-free. Even the best programmers do create bugs. Even the best code-review cannot eliminate all bugs in a project. No, it's not realistic to eliminate all UB in a project of some size by code inspection or by any other means. Your best option is to review the code and eliminate as many as possible.
Change your perception of UB (bugs): If you encounter a bug during your re-engineering efforts, it's a good thing! You are in the best position to remove one UB.
Don't keep the old compiler just because you are afraid of UB. Recompile the project with the latest and best compiler available. Compilers can also have bugs. Newer compilers will produce better, more robust code. Newer compilers will produce better warnings. Use all warnings possible -Wall.
Eliminate all the warnings that the compiler produces. Every single warning is there for a reason, it highlights a problem. The likelihood of a "false positive" is quite dim nowadays. This is even true for MSVC (I'm not talking about real old compilers like before VC 2005)
Use a static code checker (Cppcheck). It can point you to common problems with the code.
Use a custom rule set for your code checker. It will help you to get the code up to some standard.
If possible, compile the project with another compiler (GCC, Clang) just for the sake of getting the warnings of these compilers.
Don't link against old object files. This will create more problems than what you think it avoids
As others said: First and foremost, try to find the errors, not hide them.
The first and simplest measure is to set the warning level to /W4 (you can try Wall, but due to the large amount of noise this will produce (e.g. from standard headerfiles), it is usually only of help if you know you have an error in a certain part of your code)
Use static analyzers - you can start with the builtin Code Analysis tool and then go for external tools (which are usually much more difficult to set up correctly for a non-trivial project).
Write lots of tests and make sure, you are exercising edge cases - thats where UB usually lurks.
If possible, try to compile the project (or parts of it) under clang and activate the different sanitizers (in particular there is UndefinedBehaviorSanitizer) which will further instrument your code to check for UB (only helpfull if you have tests to exercise that UB though)
Test your code at different optimization levels and combination of flags (in VS, especially _ITERATOR_DEBUG_LEVEL can be helpfull to find out-of-bounds errors)
I'd say any non-trivial code base potentially contains undefined behavior. What is special about that particular Programmer? If he/she is prone to a special kind of UB, then you can focus your efforts on this.

make compiling in "safe mode" for a C++ program

Does make have an option that makes the programs compile safely so that things that cause undefined behavior would instead generate a runtime error; an example being an array out of bounds? Of course, this would mean that the program runs more slowly.
If make itself doesn't have an option, would there be another debug tool that is make-compatible?
If C++ had this feature, it would be Java. Or Python. Or C#. Or ... you get the idea.
There is also 'Managed C++', which is a bit of a camel that could perhaps serve your purposes.
On Non-Windows platforms, the valgrind tool is the next best thing.
Various versions of Microsoft C++ have had options that add some extra checking, but nothing on the scale of these other things.
To my knowledge (15+years of experience) MSVC does not have anything like that. I also never heard about this in other compilers.

Why is clang not used more? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I've done a fair amount of programming in C/C++ before, but nowadays it only accounts for a small percentage of the programming I do (scripting languages are much better suited for a lot of the work I do). I worked on some C programming projects the last few days and was surprised how many little syntactical details I kept forgetting. What's worse is that cc/gcc typically had cryptic or non-informative error messages about these issues (sorry I can't remember any specific examples).
I learned about the clang compiler not too long ago and decided to try that. The error messages were much clearer and helped me identify and fix the problems in my syntax. My question is why this tool is not used/mentioned more than it is? Is it that it is so new compared to the usual suspects (cc/gcc), or is it that it doesn't support features that they support, or is it just harder to obtain? I have a hard time believing that last one, since it was installed with the dev tools on my iMac and required a single command (sudo apt-get install clang) to install on my Ubuntu box.
My question is why this tool is not used/mentioned more than it is?
It's probably because of history, and because how we humans generally behave.
Traditionally gcc has been the only real (free) compiler that can be practically used to compile C programs on atleast all the free *nix clones out there. It's what virtually all the base system and kernel of linux, *BSD, now probably OSX, and others are compiled with.
While flaws are here and there, basically this means: gcc works. And if it isn't broken, don't fix it. Out of this, you now have a huge user base, it's easy to get help with gcc, there's a lot of people that have used gcc, that are working on gcc itself etc.
Generally, if you want to switch a huge community from something they're used to, to something else, that "something else" have to be *significantly" better. Just "better" is often not reason enough. I think you can find examples of this in many areas of society.
clang is newer, some people will just be suspicious if it's up to the task, if it has bugs, if it produces slower code etc. - it seems to be in the human nature to be suspicious - new things are scary. Many don't even know about clang, many don't care because they're happy with gcc.
Though, if you rather want to use clang, go for it - error messages are indeed "better" and easier to understand vs gcc.
The clang front end is relatively new. For example, the 2.8 release in October 2010 marks the completion of the C++ 98/03 support.
It seems likely that with increasing maturity, there will be an increasing adoption. For example, there is ongoing work on making the FreeBSD OS (and other BSD OS's) build with clang, eliminating a dependence on GCC/G++.
Apple are pushing the LLVM/clang combination. It seems likely that they will cease to support their old GCC toolchain branch (based on 4.2) and come to depend solely on clang tools for OSX/iOS development.
Clang is also seeing increasing adoption in custom compilers for C-like languages (e.g. shader language compilers for OpenCL)
LLVM has been around for a while, but — at least in my neck of the woods — it has only risen to prominence very recently, possibly due to the fact that Apple has been pushing heavily of late to replace gcc with Clang in their own tool-chain.
Also, I believe it's C++ support has only recently become production-grade. EDIT: It appears that it isn't even that yet. (See comments below.)
Another factor might be that LLVM is largely backed by a single vendor, towards which non-Apple developers have an innate mistrust.
My question is why this tool is not used/mentioned more than it is? Is it that it is so new compared to the usual suspects…
This is exactly the reason. It is still new and core functionality is still being actively developed. Remember that existing projects may be making use of compiler-specific features – or using libraries which do – and developers are, in any case, loath to change working tools for experimental ones that may have unexpected bugs or unknown performance/size/etc. tradeoffs, even when the new tools are increasingly getting better every day.
As a student programmer I find it a total godsend mainly due to it's helpful and understandable error messages. I use it mainly for programming in C, though I am beginning to branch out into C++ also using Clang.
As to why is it not mentioned more, I suspect it is since GCC has been established for so long, for most users it is THE compiler. GCC for me works fine except for it's extremely cryptic error messages which as a student does throw me off quite a bit.
Overall I do highly recommend Clang for use by both students and developers. Since it is now the official compiler for Apple and Xcode, I suspect it's use and name recognition will quickly pickup. FreeBSD seems to have also adopted it as their main compiler though I suspect that will have less impact on it's popularity than it's adoption by Apple.
Addendum: Due to the competition from Clang, the clarity of the error messages in GCC 4.8 and 4.9 has shown a significant improvement; though I still find Clang a little more lucid, the gap however has narrowed significantly.
Today, clang is replacing gcc in most places. i.e., most *NIX-like operating system and Linux distributions. Some examples oare FreeBSD,Minix and mac(a bit obvious) clang that switched clang as default compiler. Some of my friends too,when I showed them.
This IMHO, looks like some peoples had problems with it,probably in older versions. But with clang version 3.0, I don't have any of this problems. As I metioned before, I'm using it really in all my new projects. Almost my default compiler, sometimes I do make C=gcc just to seen how difference to clang error/warning. And clang win ever. With better explanations and make a great effort to optimization. It include suggestions for use extensions(some are gcc inerhid) of the compiler to a best perfomance in the code generation.
I had written a trivial function that print an error message. But I would to exit from program after printed the error message on standard output. So,I make a simple modification,put an exit(1) as last statement in the function. As the following:
void error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "error: ");
vfprintf(stderr, fmt, ap);
va_end(ap);
exit(1);
}
And so the clang show
warning: function 'error' could be declared with attribute 'noreturn'
[-Wmissing-noreturn]`
(gcc doesn't produce it even not with -Wall -Wextra -Wunreachable-code -O3 flags)
I say "that seems like nice. But what is 'nonreturn' attribute? I'd never listen or read about this. I jump to google and search for clang could be declared with attribute 'noreturn' (oh,yeah,I could just written clang nonreturn attribute,but forget it) and I found this link with a good explanation of what it this attribute and the possible gain of perfomance that I could get.
So I run to add this attribute to my function prototype(of course,if it is the gcc or clang compiler; macros will do the trick-detection). Oh yeah,to me,any small gain of perfomance(of course,without making the code unreadable) it a win.
And don't ends here,some year ago,I make return in a function where the proviously is a switch as default handling defined(as in the error() function here). But even so, gcc clains about function without return-value(I'm sorry,I don't recall to exactly error/warning message) how it possible? there is no more statements after switch,if no case match,default value is executed and don't really matter the below statements,if any. But clang think different,like me,and give a warning about this declaration,helping me make better code.
And for this kind of very small thing, I'm loving the clang.
(Note: I'm sorry for my bad english. English isn't my native language speaker, but despite it I'm trying express me here)

debugging C++ when compared to debugging C

HI,
I am normally a C programmer.
I do regularly debug C programs on unix environment using tools like gdb,dbx.
i have never done debugging of big applications of C++.
Is that much different from how we debug in C.
theoretically i am quite good in C++ but have never got a chance to debug C++ programs.
I am also not sure about what kind of technical problems we face in c++ which will lead a developer to switch on the debugger for finding out the problem.
what are the common issues we face in C++ which will make debugger to be started
what are the challenges that a c programmer might face while debugging a C++ program?
Is it difficult and complex when compared to C?
It is basically the same.
Just remember when setting break points manually you need to fully qualify the method name with both the namespace(s) and class (As a resul i someti es find it easier to use line numbers to define break points)
Don't forget that calls to destructors are invisible in the source, but you can still step into them at the end of a block.
A few minor differences:
When typing a full-qualified symbol such as foo::bar::fum(args) in the gdb shell you have to start with a single quote for gdb to recognize it and calculate completions.
As others have said, library templates expose their internals in the debugger. You can poke around in std::vector pretty easily, but poking through std::map may not be a wise way to spend your time.
The aggressive and abundant inlining common in C++ programs can make a single line of code have seemingly endless steps. Things like shared_ptr can be particularly annoying because every access to the pointer expands inline to the template internals. You never really get to used it.
If you've got a ton of overloaded symbol names, selecting which one you want from the readline completion can be unpleasant. (Which "foo" did you want? All of them? Just these two?)
GDB can be used to debug C++ as well, so if you have an understanding of how C++ works (and understand problems that can stem from the object-oriented side of things), then you shouldn't have all that much trouble (at least, not much more than you would debugging a C program). I think...
Quite a few issues really, but it also depends on the debugger you are using, its versioning etc:
Accessing individual members of templatized class is not easy
Exception handling is a problem -- i have seen debuggers doing a better job with setjmp/longjmp
Setting breakpoints with something like obj1 == obj2, where these are not POD types may not work
The good thing that I like about debuggers is that to access private/protected class members I don't have to call get routines; just [obj-name].[var-name] is good enough.
Arpan
GDB has had a rocky past with regard to debugging c++. For a while it couldn't efficiently break inside constructors/destructors.
Also stl container were netoriously difficult to inspect in gdb. std::string was painful but generally workable. std::map was so difficult, that I generally added print statements unless there was no other way.
The constructor/destructor problem has been fixed for a few years.
The stl support got fixed in gdb 7.0.
You might still have issues with boost's libraries. I at time had difficulty getting gdb to give me asses to the contents of a shared_ptr.
So I guess debugging your own C++ isn't really that difficult, it's debugging 3rd party classes and template code that could be a problem.
C++ objects might be sometimes harder to analyze. Also as data is sometimes nested in several classes (across several layers) it might take some time to "unfold" it (as already said by others in this thread). Its hard to generally say so, as it depends very much on C++ features used and programming style and complexity of the problem to analyze (actually that is language independent).
IMO: if someone finds himselfself in the need to debug very often he should reconsider his programming style.
Usually for me it is all about error handling at the end. If a program behaves unexpected your error logs should indicate enough information to reconstruct what happened at any stage.
This also gives you the benefit that you can "debug" problems offline later once your program gets shipped to end users.

How to setup VS2008 for efficient C++ development

Normally I program in C# but have been forced to do some work in C++. It seems that the integration with Visual Studio (2008) is really poor compared to C# but I was wondering if there are any good tools, plugins or configurations that can improve the situation.
Another post pointed out the program Visual Assist X, which at least helps with some things such as refactoring (though it is a bit expensive for me). My major problem is, though, that the compile errors give little clue about what is wrong and I spend most of my time figuring out what I did wrong. It just feels like it is possibly to statically check for a lot more errors than VS does out of the box. And why doesn't it provide the blue underlines as with C#, that shouldn't be too hard?!
I realize that half the problem is just the fact that I am new to C++ but I really feel that it can be unreasonably hard to get a program to compile. Are there any tools of this sort out there or are my demands too high?
I think there are two possibilities: 1) either you're trying out C++ stuff that is waaay over your knowledge (and consequently, you don't know what you did wrong and how to interpret error messages), 2) you have too high expectations.
A hint: many subsequent errors are caused by the first error. When I get a huge list of errors, I usually correct just the first error and recompile. You'd be amazed how much garbage (in terms of error messages) a missing delimiter or type declaration could produce :)
It is difficult to syntactically analyze a C++ program before compilation mainly for two reasons: 1) the C++ grammar is context-dependent, 2) templates are Turing-complete (think of them as of a functional programming language with a weird syntax).
My suggestions:
If you want more features like you get in C#, get VisualAssist X, and learn how to use it. It isn't free but it can save you a lot of time.
Set your warning level high (this will initially generate more compile-errors but as you fix them, you'll get a feel for common mistakes).
Set warning as error so you don't get in the habit of ignoring warnings.
To understand compile errors, use Google (don't waste your time with the help system) to search on warning error numbers (they look like this: C4127).
Avoid templates until you get your code compiling without errors using the above methods. If you don't know templates well, study! Get some books, do some tutorials and start small. Template compile errors are notoriously hard to figure out. Visual C++ 2008 has much better error messages than previous versions but it's still hard.
If you start doing templates in earnest, get a wide-screen monitor (maybe even two) to make reading the verbose errors easier.
+1 for Visual Assist, maybe not now - but when you turn the hobby into a profession you will need it.
In my experience, the diagnsotics are already much better than in VC6, but you will need to "learn" their true meaning as part of learning the IDE.
Static checking of C++ is much more complicated than C#, due to the build mode, and the incredibly more complex language. PC-Lint (best together with Visual Lint to integrate it into the IDE) is the canonical static analysis. Not cheap either, though...
The C++ standard sometimes reads like scripture, but without a trained preacher to interpret it. One excellent interpreter is Marshal Cline with his C++ FAQ. Note that the online FAQ, while extensive, covers much less than the book.
What helped me a lot understanding complex error messages is trying to reproduce the problem in a smaller environment - but then, there was no internet back then...