Take a look at this one: http://ideone.com/
It supports:
Ada, Assembler, AWK, Bash, bc, Brainf**k, C, C#, C++ se, C++0x, C99 strict, CLIPS, Clojure, COBOL, COBOL 85, Common Lisp (clisp), D (dmd), Erlang, F#, Factor, Falcon, Forth, Fortran, Go, Groovy, Haskell, Icon, Intercal, Java, JavaScript (rhino), JavaScript (spidermonkey), Lua, Nemerle, Nice, Nimrod, Objective-C, Ocaml, Oz, Pascal (fpc), Pascal (gpc), Perl, Perl 6, PHP, Pike, Prolog (gnu), Prolog (swi), Python, Python 3, R, Ruby, Scala, Scheme (guile), Smalltalk, SQL, Tcl, Text, Unlambda, Visual Basic .NET, Whitespace
It's very useful when you want to check little programs, like the ones I tried when writing Freaking behavior of a small little C/C++ bug:
[1]
[2]
Thursday, January 13, 2011
Online IDE for almost any SW lang you can think of
Freaking behavior of a small little C/C++ bug
Oh boy.
Read till the end the event and its root cause. Important morals follow below.
We run systems that on high capacity events handle thousands of transactions per second. One of the most heavy-traffic periods is New-Year's-Eve, the 31st of December, were most of our systems are under heavy stress around the world, stress that tends to difuse to our support teams. Structured and strict preparations usually make us pass this heavy-traffic day properly in most, if not all sites. Which happily was the case also this year.
Shockingly, on January 2nd we had a crash in two sites.
Analyzing the crash led to a timer that instead of re-scheduling itself for every 5 seconds, keeps snapping abruptly in periods of milliseconds.
While still analyzing the case, reproducing it in our labs, the problem vanished as suddenly as it appeared, on the end of the same day. January 3rd, 00:00, systems went back to behave nicely.
That's really odd. How does the bug relates to the date? Is it a coincidence? It doesn't look so, as a second after midnight problem disappears. Trying to reproduce it in the lab we got the same behavior: it is the bug of January 2nd 2011. (By the way, when running the system in our labs in debug mode, problem didn't reproduce! Bug appears only when running without debug! That's common for memory related bugs, smears etc.)
To some of us, it sounded like the iPhone alarm bug. Which was reported also not to work properly on 2011 start, being fixed on its own, by January 3rd.
http://www.tipb.com/2010/12/31/iphone-bugs-alarms-working-2011/
Maybe it's the same bug?
iPhone runs on iOS which is Linux based. We also run on Linux. Maybe there is something with Linux timers on beginning of 2011?
Looking for something in this direction led to nothing.
On the other hand, analytical investigation led to the following:
- The timer, when awakes, calls our callbak function. The callback function shall return an int value. Any value except 1 says "OK", 1 says - please call me again.
- Our callback function didn't return a value at all
Unfortunately, in C/C++ it is. And the bevior is undefined. The function do return a value, in some environmnets it will be the last value from the register. And, well, occasionaly it can be 1.
See:
http://stackoverflow.com/questions/1610030/why-can-you-return-from-a-non-void-function-without-returning-a-value-without-pro/1610454#1610454
http://stackoverflow.com/questions/2598084/function-with-missing-return-value-behavior-at-runtime
What shall be done?
Read:
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-Wreturn-type
Warn whenever a function is defined with a return-type that defaults to int. Also warn about any return statement with no return-value in a function whose return-type is not void (falling off the end of the function body is considered returning without a value), and about a return statement with an expression in a function whose return-type is void. For C++, a function without return type always produces a diagnostic message, even when -Wno-return-type is specified. The only exceptions are `main' and functions defined in system headers. This warning is enabled by -Wall.
Morals
- Listen to compiler warnings!
Solve all warnings, you should have a zero warnings policy.
The problem above could be caught and solved as a warning (-Wreturn-type). - If you don't keep a policy of zero warnings, which you should, turn bad warnings as the one above into an error, with a compilation flag, e.g.: -Werror=return-type
- You may want to test your software in future time, for example, have a test system that runs all the time 30 days ahead, if there is a time related bug it may help catching it on time. It won't probably catch everything, but it could have catch the problem we had above!
Thursday, August 19, 2010
Semi-colon and java.lang.OutOfMemoryError
; ; ; ; ; ; ; ; ; ; ; ; ; ;
I want to share with you a crash at customer site caused by java.lang.OutOfMemoryError.
Here is the original code:
if (synchRemove(lobj.getSeqNum()) != null);
____timeoutedList.add(lobj);
Can you see the problem?
(Well it's much easier after the relevant lines of code are isolated. In reality it took a few days and nights to get to these lines, remember it occurred in customer environment where not all relevant info is easily available for the development team. The OOM doesn't necessarily occur at this line).
Moral:
- Small semicolon can cause big troubles
- It's hard to see everything in code review. A trouble-making redundant semicolon can skip the eyes of the reviewer
- Load test may find such cases (but may still miss them, if the relevant scenario was not created)
- Good unit tests may also help
- Most Coding Guidelines require curly brackets for any block, even containing only one line. This could possibly reveal the error (if not by the developer, by the reviewer in code review)
- Static code analysis tools, like FindBugs – which is free, do point at such errors!
- In some IDEs (e.g. Eclipse) you can configure the IDE to present warnings on such cases
in the above case, analyzing the heap dump, using MAT, led to the problematic giant list, then tracking all insertions into the list in the code, led to the faulty line.
Thursday, August 13, 2009
When a bug makes you crazy
This week I was sitting on one of those bugs which almost make you scream. Something is wrong, but you cannot find what creates this f-word behavior.
I was working on some web page example for some Taglib framework, but the page insisted on having an extra element that I didn't create. And when picked using FireFox, it pointed at a node in the XHTML that I'm definitely not rendering...
Step 1
Nothing in the code should make this happen. First suspicion is that I'm running an old instance, so I'm running a clean+compile and restarting the server, then when this doesn't change anything I'm adding a printout just to make sure. The new printout appears. Damn! I'm running the code that I'm looking at, but nothing there seems to be responsible for this result.
Step 2
I know that in order to debug I need a theory. But I cannot raise any theory, as clearly the result that I see is not something that is in the code... So I start playing (though I know it's not the methodic way for debugging, but I'm trying to play methodically). I find all places where I render this kind of element that is being rudely added where not belonged and I mark them each with a unique id. The id appears. Now I can identify the exact place that is responsible for this behavior, but I can't understand why it happens. An XHTML tag is added in a place in the document that surely I'm not printing.
Step 3
It took me some time. Maybe too much time. But I understand now that FireFox tree view of the page is cheating me... The element that FF is presenting at a certain place on the tree cannot be there. I'm not printing it there. Suddenly a strike hits me: GET BACK TO THE BASICS. Instead of using FireFox to locate for me the wicked node, let's view the source of the page. How simple and basic, though yet I spent about an hour before thinking about this simple thing.
And indeed, when viewing the page source I see that the problem is that I'm opening some HTML tag somewhere and not closing it, but FF closes it for me way beyond this point, creating a very strange node that I didn't create. In the treeview of the page FF presented a tag with a start and an end, while I accidentatlly opened a tag at some point and didn't close it. Now it's much easier to see the problem. And I also note that indeed FF showed that there are errors on page, with this error listed.
Moral
- When the tool you debug with shows something that you cannot explain, go back to the basics: tcpdump, sniffer, printouts. The debug tool may be misleading you!
Believe only to bits and bytes, not to any fancy tool. - If you are working on a Web page, first look at the "errors on page", if you always insist on first fixing these you will save valuable time.
- When a bug makes you crazy look him in his eyes, tell him that you will beat him. Don't show any weakness signs as these bastards know well how to recognize such signs.
Wednesday, April 9, 2008
Do you have a theory?
In many cases when I sit with a novice developer who is working on fixing a bug I see him or her throwing lines of code from here to there. When I ask "why did you do that", usually when the code looks already like after a burglar paid a visit, the answer I get is "it wasn't working, so I'm trying to fix it."
Would you like someone to fix your car that way?
Debugging is considered sometimes a non-sceintific trial and error process - you try this and that, eventually the bug will be exhausted and you will break it. Well, it is not. This would only make you to mess your code and put new bugs in, break the original structure and leave the code in a strange, shaky position, usually explained later as "we needed to do that because there was a misterious bug in the original, proper code."
Just as when fixing your car, the mechanic would probably not try to shove your carburetor into the fuel tank as a possible solution (well, we haven't tried this yet, who knows maybe it works), this is not the way for debugging.
Debugging should be methodical.
- Have a theory before you act
- Try to prove your theory on a simple code
- Divide and conquer - try to eliminate the bug by putting code in comments till the bug is gone, then analyze what is wrong in the lines commented out. But don't just throw these lines away, even if they look redundant at first sight, and don't move them around without understanding the problem
- Analyze the problem and what causes the bug before you start changing your code, use logs to analyze the problem in complex scenarios
- If you are changing the code as part of a theory ("I think we might have to call the super class at the beginning of the function and not at the end...") - remember what you have changed, if your theory fails (the bug persists and the change does not have a value of its own, it was just a whim of the moment) - return to the original code before you go on
- If your theory prove itself right, still make sure that you fully understand it (moving the call to the super class to the beginning of the function fixed the problem - now let's understand why it should be this way... does it always have to be this way? do we need to check other similar places?)