What Debugger Is Best For Multithreaded Apps? 257
pollyp asks: "I'm on a team that's working on a multi-threaded (pthreads) C++ application running on GNU/Debian 2.2. One of the challenges of this project is trying to debug the app, or making sense of core files; the feeling is that gdb is just too difficult to work with in a heavily threaded app. We're looking for better tools, and if that means changing languages or going to another UN*X, we're ready to do it. So what is the best, most mature OS/language/tool UN*X environment for doing multi-threaded application development on Intel?"
"One part of the team wants to stay on GNU/Linux but use Java. Java's performance is becoming less and less of an issue, and the GNU/Linux development tools are reasonably attractive (e.g., Visual Age's debugger). The other part of the team wants to stick with C++, but move over to Solaris. But none of us have any practical experience with Solaris, nor do any of us have a sense of how fully baked their Intel development environment is."
We use the Paradigm C++ Debugger (Score:1)
You can start a debugging session by double clicking the
You can build your application in real or protected mode. Choosing a Target platform is as easy as right-clicking the
Paradigm C++ even has the smarts to inspect an object by simply passing the mouse cursor over it in the Edit Window. Since it also knows the debug symbols in the current scope, you always have access to the most frequently used debug information without any additional effort.
During debugging, the editor view includes local menus containing debugging options such as Inspect or Watch. Source lines with debugging information are marked with red dots and the current execution point and enabled/disabled breakpoints are all marked.
You can open a CPU view to see the actual code created by the compiler or assembler or see register contents. This window handles viewing of memory, registers, processor flags, and stack and includes options to help you checkout low-level code. You can bring up the CPU view at the current CS:IP by using the View menu command. Or to bring up the CPU view corresponding to any source line, use theView CPU command from the Edit view local menu.
Re:We use the Paradigm C++ Debugger (Score:2)
I mean 10 minutes after the article was posted we get this 6 paragraph commercial posted by an AC. Don't mean to sound bitchy, Paradigm C++ could be good and I might give it a try when/if I develop in C++ again, but at least you should try being more honest about what you are doing...
Gnu Visual Debugger (Score:2)
The gnu visual debugger [act-europe.fr] is based on gdb, and claims to have much-improved support for multithreaded code. I haven't used it myself, though.
If you're considering a different language, Ada is worth a look. Gnat [gnuada.org] is a complete and stable compiler in a way that g++ is not, and the language was designed for multithreading from the start.
Avoid Solaris/86 like the plague it is.... (Score:2)
The best tool (Score:3)
So what is the best ... tool ... for doing ... application development?
16 cups of this [lavazza.it].
If you can afford it, move to Java (Score:4)
As to performance: if you're not writing a nuclear explosion simulator, Java's performance is probably adequate. (Think StarOffice here.)
--
Don't change horses in the middle of the stream (Score:5)
Are you really changing Language and OS for better multi-thread debug?
This is one of the symptomathics of IT today. You start out analyzing the problem, then you choose an aproprite tool. Some month's later you hit trouble and you consider moving to new language, OS, architecture, whatever, totally discarding the initial analysis that led to the choises you made!
On topic: You should not expect multi-threaded code to be easily debugged, afterall it is hard to write!
You should instead put effort into the really core components that are multi-threading sensitive (synchronization when referencing datastructures and stuff like that, btw. C++ is excellent for that, using Monitors), and make all other code REQUIRE to use the methodology you develop in these components.
Try to collect the multi-thread sensitivity in small, well-defined areas of your program, and try to prove, or at least reason, about the correctness of the code there. One thing you may wan't to do is define (in C++) Locking Iterators, which Lock datastructures they work on, and (using reference counts) automatically unlocks the structure when Iterators fall out of scope.
You may also have some luck in using some of the design patterns that deal with multi-threading.
Morale:You cannot debug away every race-condition, that's bad practice you HAVE to think.
Fun programming (Score:3)
-- Faré @ TUNES [tunes.org].org
Ada 95 (Score:1)
As for debuggers, I've used DDD (a gdb frontend) but never with threads. I tend to just use the old trick of sticking a few printf statements in key places.
Re:We use the Paradigm C++ Debugger (Score:1)
I think that too. The company would have actually answered the question (and said something about threading, which is totally absent in the Paradigm post)
The few lowlevel workarounds that are included (single handedly setting cs:ip), can be done in GDB too afaik.
debugger and threads (Score:3)
I would also suggest using a thread class that encapsulates the pthreads interface. I have a system in production that uses the omniThreads thread library. omniThreads is part of the omniORB library, but it compiles stand alone without any ORB related stuff. (FYI: I compiled it as a shared library ) It is very portable across machines (may help when switching to another machine)
Writing threaded programs is very easy in Java. However, my apps have been simple enough that I have not had to debug the threaded application. If your application is a server app, with not so realtime requirements, you may want to try java. If it is a GUI app, you probably should not !!
Re:If you can afford it, move to Java (Score:1)
I think that is a pretty severe performance hit.
I would rather use the Ada as suggested before.
Re:Don't change horses in the middle of the stream (Score:2)
In the true open source mind, it would be better to say:
You are changing a debugger because it misses a feature? THEN IMPLEMENT IT
I'm sure the GDB team is curiously awaiting your patches.
You can CVS the GDB source up to date every day.
(I use a gdb from the devel branch, because it compiles easier on FreeBSD)
Re:Don't change horses in the middle of the stream (Score:1)
Re:Don't change horses in the middle of the stream (Score:1)
Re:If you can afford it, move to Java (Score:1)
Totalview (Score:3)
Solaris (Score:5)
The debugger is dbx, fully supporting multithreaded debugging, and has a full GUI on top of it, as well as full visual integration into Emacs (better than you've ever seen gdb do).
Some people think that Solaris' thread libraries are less than adequate. Personally, I've never used a better multithreading system. The entire "kernel-scheduled LWP managing user-scheduled threads" many-many concept is more efficient and works far better than Linux's one-one kernel-scheduled threads. And all your threads run with the same PID - what a concept!
The obvious disclaimers are that I haven't used the newest Solaris tools, nor was this done on x86, but definitely consider not only the tool quality but also the OS' attitude towards threads. Solaris is better than Linux in that regard, IMO.
Michael J.
Try GVD and FSU Threads (Score:1)
On the other hand, I've experienced that LinuxThreads (the thread implementation provided by GNU libc) and GDB don't mix too well. Maybe you can try another pthreads implementation, for example the one from Florida State University (FSU Threads).
Thread problems (Score:1)
Re:Solaris (Score:1)
GNU Visual Debugger (Score:2)
I've been usign GVD for a couple of weeks and works well with multithreaded programs:
http://www.act-europe.fr/gvd" [act-europe.fr]
And it also supports native and cross debuggers (VxWorks, LynxOS, JVM, ...), remote launching of debuggers, different languages, etc.
--
To visit or not to visit: findusclub.com [findusclub.com]
"Best" debugger is no debugger (Score:1)
Almost all of the Linux kernel was debugged that way.
Re:If you can afford it, move to Java (Score:5)
I don't know about debuggers for Linux... (Score:2)
but Irix has a couple of really handy debugging utilities, Purify and TotalView Debugger. I haven't used Purify much, but TotalView is incredibly handy.
-fnord
Don't change (Score:5)
I can not know much of your situation, but on the surface it looks like a perfect example of the need of a clean rewrite. Scrap all the code you have, and the whole design, and consider all of it at most a preliminary study. But for crying alound, keep the same people and the same tools, unless it is blindingly obvious you are trying to use a totally wrong tool for the job - and C++ for multithreaded programming is not such a bad choice. If need be you may have to add one or two good, experienced people in your team.
Then, start from the beginning. Design the system all again. You know you have problems with thread, so do not overuse them. Consider each thread a black box, and specify its interfaces, just like you are supposed to do with single-threaded systems. Specify the lockings and controls you need for things to work. Then implement bottom up, and test everything as you go.
Spend more time in designing end implementing test suites than on the project itself - this will cost more at the onset, but increases your chances of getting the job done, probably faster than without the investment.Build a good debugging log that can be written from any thread, and where you control bufering. Build test routines to delay things, and pepper your code with them. Routines to exercise each module independently, and various combinations. And what ever else you can think of, that might come in handy. Make most tests automatic, so you can leave them running every night if need be. But most of all, make a clean and understandable design, and do not introduce new languages, tools, methods, or any other reasons for confusion!
DDD + GDB 5.0 (Score:2)
I wouldn't go with the latest beta version of DDD, but use the latest release version. You *must* use GBD 5.0 in order to get a hope to work with threads.
I was expecting someone (Score:2)
1. What the hell has this got to do with his suggestion - he's asking about debugging threads. It would have made some sense if you had talked about threads in Java and the tools provided to debug them (for instance JbuilderX allows thread debugging, but it's far from ideal). Java threads are notoriously error prone same as threads everywhere.
2. "Given the fact that 90% of all C / C++ bugs.."
This is a fact that you pulled out of your ass. It may be roughly true for novices or students, but is nonsense for experienced developers. With tools like purify, these problems are very easy to track down in C/C++, and 2nd nature to avoid.
Java encourages people to forget about these problems and rely on gc, then they leave dangling references dotted around and wonder why their disk is grinding.
3. The performance hit is not minor. Sometimes, in simple cases, Java works great, but it depends what you're doing. An uncontrived comparison is at http://sprout.stanford.edu/uli/java_cpp.html
In summary, with HotSpot 1.3 beta, (a JIT that Sun touted as being faster than C++ !!) Java was roughly 5 times slower than C++.
4. Is StarOffice supposed to be an example of a good Java application with acceptable performance ? Heaven help us, it makes Word2000 seem slick and efficient.
Are there *any* examples of serious Java applications with acceptable performance ?
Re:Gnu Visual Debugger (Score:2)
SunWorkshop C++/Solaris on SPARC (Score:2)
Bullshit (Score:2)
A doctor "fixes" patients by examining their symptoms, determining what their disease is, and then curing it.
Programmers do the same thing. Merely thinking about a problem and mentally stepping through code is a piss-poor way to figure out what's going wrong. Stepping through code with a debugger is a hundred times more effective, especially in a team environment where you are debugging code you didn't write, or when a junior programmer is misusing a library routine he thinks he understands.
While it is true that some programmers take stupid actions based on what they see from the debugger, that is because their brains are stupid -- not because they are using a debugger. The debugger is merely another tool for diagnosing a problem, and provides food for thought. Nobody has ever claimed that is a replacement for a good brain. Yeesh.
--
Thinking and discipline (Score:3)
The best way to get a parallel program working is discipline and understanding. Think about how the threads will interface with each other. Design those interfaces using appropriate known and proven synchronization methodologies. Adhere rigorously to those designs. If you're tempted to leave out a lock in some place, you'd better be able to prove that it can be done safely.
If necessary, write wrappers around your synchronization primitives for better observability and controllability. For example, when the program crashes, you want to be able to see which threads are holding which locks, which are waiting for what conditions, etc. Being able to log the sequence of synchronization actions to a file and to force a replay of those actions in the same order will help in reproducing bugs that otherwise would manifest themselves only once every hundred runs.
Have manual inspections of the code with a coworker. Play a game where either of you can propose a failing scenario and the other must explain using the code why that can't happen. If neither of you can explain why it can't happen, it probably can.
Your basic philosophy should be that it's impossible to convince yourself of the correctness of the synchronization through testing. If you can't prove that your synchronization is right, it's most likely wrong. And if it's not wrong, it's so complicated that you'll break it later because you don't understand it.
How about for C on Linux? (Score:2)
--
Re:Gnu Visual Debugger (Score:2)
It is supposedly designed where support for other languages can be added, so if you use C++ you may want to ask around and find out what the current status/prospect for C++ support is.
--
you're right about soffice, but (Score:2)
I spent about two years doing full time java
development (full fledged scientific java application for Alcan). I first learned java five years ago, and have tried it on and off since then. I recommended using it in that project because the superficial impression it gives is pretty positive, and *anything* is better than using MFC. (I wish I had known about FLTK back then)
I would not recommend Java for client side application development. If you really care I could drone on for days about why it's a bad idea. Personally I wouldn't use it on server side either, but I agree that it is pretty good for that. Sun has spent many millions of dollars putting together suitable libraries and tools to make it a good tool for server development.
Actually, I had thought soffice was largely java because it's a misconception that's quite common and also because soffice is slow and bloated, but not as bad as I expected for a java application. I think it's largely C++ though. Please give me an example of a good, substantial Java client-side application if you believe I'm just spreading FUD.
Check out spin (Score:2)
As for Java vs. C++, well Java isn't a bad language, and having threading built in rather then slapped on as a bag on the side makes it nicer (pop quiz: what C++ facet operations are thread safe?). On the other hand I feel a bit limited in Java, and I miss the STL. As far as I know SPIN will help Java coders as well.
I don't think Solaris x86 is a good idea. If you want Solaris, get a SPARC. Otherwise you are always behind the support curve, and the hardware support is far more limited then Linuxes. Besides the SPARC hardware is extreamly reliable (if not all that fast), and works great for lights-out operations.
Re:Don't change horses in the middle of the stream (Score:3)
The problem is, that, under Linux, if you load the resultant core file (from any multithreaded program) into GDB, it often dumps core. Which isn't very useful.
The end result of this is that you can have a dual PIII-800 workstation, running the very latest in tools, with a highly trained developer, doing a friggin' binary search through the code with printfs trying to figure out where the stomped pointer is coming from.
Believe me, you do this a few time and you're gonna start thinking that a language that does memory management for you probably wouldn't be such a bad idea, either.
My OT rant - RedHat/Cygnus (leader of the gdb effort) needs to get this fixed. Quite frankly, it's hard to take Linux as a serious development platform when multithreaded debugging is twenty years back. Support the developers, first, and everything else will follow.
Re:Ada 95 (Score:2)
Be forewarned that when you first start using Ada you will find it very annoying that it actually expects you to say what you mean with respect to types. People who say they like C++ because "it has a stronger type system than C" don't know what "type system" actually means. (No famebait intended; just a warning to brace yourself for the shock if you do decide to give Ada a try.)
However, in my experience, once you get into the habit of thinking out what you are trying to do, you will find that most of your bugs are discovered at compile time, and your ratio of Coding_Time:Debugging_Time will go way up.
Notice this quote from the GVD home page [act-europe.fr]: Raymond and Hoare notwithstanding (yes, I saw that
Also, another party has mentioned that Ada is designed for multithreading; I would just like to add that MT support is in the syntax of the language itself, and has been since 1983.
--
Re:"Best" debugger is no debugger (Score:2)
As they say, "...we tend not to use debuggers beyond getting a stack trace or the value of a variable or two. One reason is that it is easy to get lost in the details of complicated data structures and control flow; .... It is more helpful to use the debugger to discover the state of the program when it fails, then think about how the failure could have happened. ..."
Just my 0.02...
R.
Re:Check out spin (Score:2)
The best debugger is 'printf' (Score:3)
Personally, I despise IDEs because they always slow me down. I've noticed that the best programmers never seem to use them. I think putting well-chosen printf's in the code forces you to think about what you're actually writing, rather than writing a bunch of garbage and then using the debugger to bail you out.
A lot of people think I'm crazy when I say this, but both Linus Torvalds and Gostling have said similar things.
I've developed both ways, and there is no doubt in my mind that it takes me less time to develop when I just use printf's. But -- it does take more discipline, and that's probably why you see so many mediocre programmers slaves to the debugger and IDE.
vi, make and printf (with the occasional grep and find) -- that's my debugging environment, and I'm known for my development speed and code quality.
--
Reference please (Score:2)
score -1, offtopic (Score:3)
I've actually USED paradigm C++, along with paradigm link and locate tools. It's for embedded application development. (ie: raw rom hanging off an x86 processor bus with no bios (you actually run where a BIOS would be), no OS, etc). The dev tools themselves run on ms-windows.
This tool has little to do with multithreading, in fact I don't belive it contains a thread library at all. (I could be wrong, but I never saw one and it's not a listed feature) It supports real mode, and if you're x86 can do it, protected. It will target as low as 80186's and NEC v## processors.
It also has nothing to do with UNIX. It's for people building non-pc x86 based systems that have no BIOS and no OS. It's for bare-metal embedded c++. You can't even run the IDE on UNIX, much less the target.
They have a site at devtools.com, visit if you're bored, see how much Multithreaded Unix support they have...
My personal opinions of this software aren't very high, but mostly because my opinion of x86 for raw-soldered embedded is pretty low. The product itself is relatively well written.
Things to consider... (Score:2)
#1: Can you really switch your language or OS?
At best I'm dubious as far as your suggestion of switching language or operating system. Unless your project is only at the very first stages, you have almost undoubtedly invested far too much effort to reasonably consider backing out. Why did you choose C++ and GNU/Linux in the first place? Surely more thought went into it than "we like C++" and "Linux is nifty", so go back to those decisions and sift for clues.
#2: Why are you spending so much time in a debugger?
You should be spending more time with your concepts, flow charts, and whatever else you came up with before you laid it all into code. Spend some time pondering what exactly you're trying to do, then go look at your code and make sure it's really doing what you want. A few well-placed debugging output statements (printf/cout/whatever), some good comments, and a clear head will get you much farther than a debugger, even the best. Debuggers absolutely cannot tell you what you're thinking.
#3: Do you really need threads?
Is your application specifically designed to be run on parallel systems? Is it designed to take the majority of a system's resources? Chances are you don't need threads, most programs don't. There are usually better ways to do things than multithreading. Also, writing threaded code is considerably more time-consuming than non-threaded code. Are you writing something so complex you need threads? If you haven't really evaluated this, now is the time.
-wd
--
chip norkus(rl); white_dragon('net'); wd@anduril.org
mercenary albino programmer for hire
Shouldn't be the major decision factor (Score:3)
Re:Fun programming (Score:2)
Re:you're right about soffice, but (Score:2)
Re:Gnu Visual Debugger (Score:4)
If you need a visual dbugger. It acts like gdb, which I already love, but adds a visual edge that gdb alone doesn't have. When I am really stumped with gdb, I go to ddd.
Re:The best debugger is 'printf' (Score:2)
I remember a C++ programmer asking me what debuggers were loaded on our HP system. I turned to him and said 'printf
Debugging code is very easy
To be fair, I do use debuggers from time to time, but usually only has a last resort. I find it is much easier to add extra printfs than it is to set up conditional breakpoints and then step through code for hours.
Using the above information, it is usually possible to narrow the issue down to a few lines of code. Time then to add some more printf's to dump values.
One very large advantage of using vi (or emacs) and printfs is they are available on all UNIX systems and all compilers. When changing jobs, the last thing I want to do is be neck deep in a bug while trying to learn a new debugger
I only use the 6 editor....
Re:The best debugger is 'printf' (Score:2)
Re:you're right about soffice, but (Score:2)
It's unuseable with less than 128M or RAM. It's almost tolerable with 256M. It suffers from random freezes and needs to be restarted from time to time, otherwise memory consumption rises mysteriously. If you build a sizeable jar file from within Jbuilder it takes about 10 minutes - create the same jar from command line (jar -cvf) will take 20 seconds. It randomly caches class files, so you can never quite tell whether a source change has really taken effect - you can manually delete all the class files, do a full rebuild, and it will still use some cached class file from memory somewhere - misleading you into thinking that your code change didn't fix the bug. In the end we abandoned it and reverted to using jdk1.1.8 command line tools together with gnu make.
Does anything else sping to mind ?
Re:The best debugger is 'printf' (Score:2)
Re:The best debugger is 'printf' (Score:2)
I fail to see how your way is faster.
In my experience, people who are slower with IDEs just haven't bothered to learn how to use them. They are the people who spend a few days playing around with VisualStudio and then give up saying "it is too complicated, it slows me down" all the while forgetting that it took them WEEKS or MONTHS to get to the level of profiency they currently have with vi and make.
CodeWarrior (Score:5)
We've used Metrowerks CodeWarrior [metrowerks.com] to develop and debug very heavily multithreaded applications on MacOS, NT, Solaris, and Linux for about five years now; the CodeWarrior tools seem very much 'up to the job' and thread-aware. As a nice plus, CodeWarrior runs on multiple platforms (including Mac OS X now), which is a nice plus for our development, which is all multiplatform.
We now use a diversity of compilers/IDEs/debuggers, but CodeWarrior is still a favorite, even if it's just because of the "Blood, Sweat, and Code [devdepot.com]" T-shirts.
Comments from Pro with Lots of Experience (Score:5)
To all this I'll add:
Java is a lot more productive than C++.
C/C++ can be lots more runtime efficient.
Aside from that, you're better off in Java.
I miss C++ (and even C) sometimes, but Java is usually a better language overall. Not hard to migrate.
If you go with Java, take a strong look at Doug Lea's stuff.
Re:Check out spin (Score:2)
TotalView (Score:4)
It's a parallel debugger, which means that it has built-in support for manipulating groups of objects, as if they were one: threads [etnus.com] in a proceses, processes in a group, groups in a cluster, and so on. This means you don't need 20 windows to control a 20-thread app; we roll up an aggregated view into one window, commands work on the entire batch.
And yes, we support Linux [etnus.com], as well as almost every other Unix out there. You can snag a free demo license [etnus.com] and download the bits from our website. And for those of you who like printf(), you can add them on-the-fly without recompiling. That saves time.
Disclosure: I am a developer on TotalView, but I do "eat my own dog food"- we use it every day on itself.
Re:If you can afford it, move to Java (Score:3)
Actually, it is a misconception that java doesn't suffer from memory leaks.
A classic memory leak is one where you have memory allocated but no longer have any way to make use of it. These kinds of errors aren't possible in a garbage collected language. Once you let go of your last pointer to something in Java (or, say, Perl) then the GC takes care of everything automatically.
When debugging other people's C code, the most common memory leak I see is the temporary allocation of scratch space in some low-level routine without a corresponding release of the memory. This does not happen in Java.
If you don't explicitly design in creation/destruction of your objects you will leak memory.
Agreed. This is especially a problem with people new to OO design, where they haven't yet developed a good understanding of modular integrity. In practice, though, I find these kinds of errors much less frequent and much easier to find than classic memory leaks.
Real real-time debugging (Score:2)
Re:I was expecting someone (Score:5)
I was expecting someone to make this stupid suggestion. [...] What the hell has this got to do with his suggestion - he's asking about debugging threads. [...] This is a fact that you pulled out of your ass.
When a developer (or team of developers) is spending a lot of time debugging and still not solving the problems, I ususally take this as a sign that there are more fundamental problems than the quality of the debugger. I've been developing serious software for 15 years in Pascal, C, Perl, C++, Objective-C, and Java, and I rarely need to us anything more than the occasional printf.
Admittedly, developing threaded code is hard stuff, and I don't know enough about the original poster's problems to say what is going on. But it is possible that they are in over their heads, in which case it may behoove them to a) admit that they don't know enough and start again from basics, and b) they may wish to choose a language that is more forgiving of inexperienced developers.
In that case, suggesting Java is a good idea. That's not to say that C is bad; if I am doing something speed-critical and am working with a team of crackerjack developers, then C would be my first choice.
But if I'm doing something where maximizing CPU efficiency isn't our #1 issue, or if I'm working with developers who are less than stellar, then I lean towards Java. Why?
Ergo, there was no need for you to be an asshole about it.
Stay with C++, use DDD to tame gdb (Score:2)
As many other posters have said wisely, switching tools midstream is a sure route to pain. Trust me, once you've made core tech decisions, stick with them! At least until you get version 1.0 out the door...
I too don't like using gdb on the command line, but combined with DDD [gnu.org], the Data Display Debugger (works natively on pretty much any Unix, linux strain, I've seen ports to win32, etc) debugging is a much nicer experience. I don't write multitrheaded stuff being a pretty neophyte C++ programmer (eh, we all have to start somewhere :-) ), but I did notice in the online manual that it does have at least rudimentary support for threads.
Plus it's free and doesn't require any changes to your environoment or toolchain. (Basically just install it, it defaults to using gdb as the "inferior" debugger (as opposed to dbx or any of the perl/python/java/whatever debuggers), and you type "ddd progname" instead of "gdb progname". It even has a command window to interact with gdb directly if you so wish...) Last but not least it has a cute logo. ;-)
--
In Java, I like (Score:2)
A few months back, we purchased a suite of tools from an outfit called Sitraka [sitraka.com] (nee KLGroup). They have three products that are part of the JProbe Suite [sitraka.com], a CPU and memory profiler [sitraka.com], a thread analysis program [sitraka.com], and a code coverage tool [sitraka.com].
These are all good tools; when I was having some problems that I suspected were due to my less-than-perfect understanding of threading, I used their thread analysis tool under simulated load, and it immediately identfied my race condition, plus a couple more potential races I hadn't noticed yet.
(This is a little off-topic, but I have to mention that their memory/CPU profiler is, pardon my french, fucking awesome; it is the best thing I have ever seen for visualizing the interior structure of a running program. After a day with the profiler, my Java code was substantially faster than the C it was replacing, despite having more features and being more secure.)
Another tool I'm very pleased with is JUnit [junit.org], a unit-testing framework. If you're interested in trying out the Extreme Programming [extremeprogramming.org]-style approach to testing [extremeprogramming.org] (wherein you make automated, integrated unit tests that are run more or less continuously) then this is for you. And if you are having so many problems with bugs that you are considering changing languages, then I would strongly recommend that you do this. Good unit tests slow initial writing down a little, and save you extraordinary amounts of time and agony later.
Oh, and run out right now and buy several copies of Code Complete [amazon.com] and Rapid Development [amazon.com] for the team. If you are having such large problems on the project, the problem is probably not with your choice of debugger. These books will help you figure out what the problem actually is, and give you all sorts of solutions.
--
For the record, and I don't have any financial interest in any of the things I've mentioned here; I just use 'em and like 'em.
fair enough (Score:2)
One thing though:
"You're right that novice Java developers take longer to learn the value of reference handling than C developers, but this is mainly because Java extracts a much smaller penalty for those errors. By your logic, presumably, C++ would be even better if each time the developer left a dangling reference they received a high-voltage shock to the nipples."
Exactly ! yes, that is an excellent idea. Having the program die horribly would probably suffice, but the high-voltage shock to the nipples would be even better. Immediate catastophic failure is a far more useful reaction to bugs during development than limping along, papering over the cracks.
Re:fair enough (Score:3)
Me too. As far as I can tell, these are people who have never done any serious work in Java. Or if they have, then Java is the only language they've used on a serious project.
Luckily, these people get what they deserve. Eventually they will be dumb enough to say things like this to a boss, who will be dumb enough believe them. And then when their optimistically-scheduled, poorly-scoped, under-budgeted project goes up in flames, they will get fucked with the sandpaper condoms. The smart ones learn after the first time that no tool is perfect for every job. The dumb ones, of course, talk trash about last tool and find the next perfect tool to talk about.
Having the program die horribly would probably suffice, but the high-voltage shock to the nipples would be even better. Immediate catastophic failure is a far more useful reaction to bugs during development than limping along, papering over the cracks.
And people call Java a bondage-and-discipline language [tuxedo.org]! Heh. Maybe we should dress this idea up in a lot of fancy talk about neuropsychology and maximizing feedback loop efficiency and see if we can get VCs to cough up a few million dollars to get us going.
One coment on Solaris x86 vs. Sparc.... (Score:2)
I've run production environments with Solaris on both x86 and SPARC. I'm primarily a SysAdmin/Architect, not a developer, so take your coding cues from someone else (I program, but not heavy-duty professionally).
Previous to Solaris 8, there were A LOT of serious bugs in Solaris x86 that caused it to be unusable for serious work. For web serving and simiar crap it was fine, but any complex app tended to expose bugs in the OS. Solaris for SPARC doesn't have these problems.
Solaris 8 for x86 seems to have fixed most of the egregarious problems, and I would trust it to run your app. HOWEVER, x86 still seems to have random low-level (ie driver and the like) problems with certain hardware. Thus, I would seriously recommend that you DEVELOP on a SPARC box, which doesn't have these problems. That way, you can be sure that the bug you've just found is really in YOUR code, and not some obscure problem in the OS. One you have stable code, Solaris 8 for x86 is stable enough to run as your production OS.
Both x86 and SPARC use the same codebase - thus, the system libraries and similar stuff all work equally well (or at least, have identical bugs...). However, the Hardware Abstraction Layer implementaion for x86 is of poorer quality than the one for SPARC (which makes sense, given Sun's priorities).
Best of Luck.
-Erik
Re:If you can afford it, move to Java (Score:3)
The problem arises when, from the designers point of view, the object will no longer be used, but from the VMs point of view, the object is still alive. An object that has a root parent in the reference hierarchy will not be garbage collected.
Things I have seen that hold onto large object trees are things like, anonymous innner classes (implcit "this" reference), listeners on gui components not being removed, and static class variables holding onto objects.
Java is a great programming language because it is easy to use thanks to all the built in stuff, but nothing is free. You generally pay for it with performance and memory usage.
Here's an article discussing "memory leaks" in java
http://www.devx.com/upload/free/features/javapro/1 999/06jun99/tl0699/tl0699.asp
printf isn't thread safe (Score:2)
He is asking for a good debugger for multi-threaded programming such as dbx on Solaris because gdb cannot handle threaded debugging. Instead you respond with an uninformative post that describes the worst way to debug multithreaded programs. printf isn't thread safe so it's use in multithreaded programming as a debugging tool is frowned upon unless you are using additional mutexes for logging (adding complexity) or you are using a thread safe print function such as OutputDebugString in the Win32 API.
Grabel's Law
Are you kidding? (Score:4)
You are changing a debugger because it misses a feature? THEN IMPLEMENT IT
Comments like this make me wonder exactly whether Slashdot is read by programmers or simply people who have heard about programming and think it's cool. Multithreaded applications are hard to design correctly and difficult to debug from an application writer's point of view. Your simplistic statements belie the fact that you must be an inexperienced programmer because in the real world people don't have time to start om mammoth projects simply to help with a medium sized one. Adding threading support to gdb is more difficult than writing a multithreaded application that uses the pthread library unless the application is very complex like a compiler, relational database management system or a web browser.
Your comment is like telling someone to hack garbage collection into C when they complain about memory leaks instead of simply pointing the person to Purify or BoundsChecker.
Grabel's Law
Re:Poor multi-thread debug support on Linux (Score:2)
Could you be a little more specific when you say that collections can't be type-safe? Are you referring to putting several different instances of different objects into a collection and then being able to weed out the different instances by object type? I've done that in Java. It's really easy if they all implement the same interface. Once can iterate through the collection and call the same method for totally different objects. Also according to this page [sun.com], one can create constants in Java. Or are you referring to defining parameters to methods as const so that the compiler won't let you modify them? I will admit that having to have wrapper classes for the primitive types is a pain.
Re:If you can afford it, move to Java (Score:2)
Re:If you can afford it, move to Java (Score:2)
That link didn't work for me, but here's another article on the same topic, at Java Report magazine's site: here [javareport.com]
BdosError
Use processes instead of threads (Score:3)
Re:The common JAVA chant (Score:3)
They did this for a reason though. For a lot of real-world software development, you have to do the work with painfully small amounts of time, money, and talent. So they banned a number of things that it takes an expert to use wisely. E.g., pointers, multiple inheritance, allowing unreachable code, preprocessor macros, raw memory allocation, random memory access, self-modifying code, and so on. As cool as those features are in the hands of a genius, they are plain dangerous in the hands of a mediocre developer. And 99% of the time, the genius will be doing what Java would be doing anyhow; it's only the 1% of the time that it sucks.
That's why I'd much rather inherit a bunch of J. Random Programmer [tuxedo.org]'s code in Java than almost any other language. There will be little impressive wizardry in it, but there are also unlikely to be many sections that will make me bleed through my eye sockets.
And you're also right about some of the other feature lacks; the whole primitive type thing is just ugly, and it's clear that they haven't heard about the whole mutable/immutable thing yet. Really, it saddens me that they are just now catching up with a lot of the things that NeXT was doing right with Objective C 5-10 years ago.
But as far as getting things done in the real world for server side stuff goes, it seems perfectly adequate for all the OO work I do. And to be fair to them, they're making a fair bit of progress [sun.com]; the java.lang.ref [sun.com] package, for example, answered a lot of my gripes about pointers and garbage collection.
One thing I didn't understand in your post was the section "lack of parametrised types"; could you talk more about that?
Re:I was expecting someone (Score:2)
Although this can be true, for most people it just doesn't matter. Why? A few reasons:
That said, I should mention that I've only done server-side Java stuff. I have no idea how GUI Java programs could still be so damned slow after years of effort, but at least under Linux, they really suck. But this is some sort of GUI library issue, as my console and HTML has all come out surprisingly zippy.
Re:Poor multi-thread debug support on Linux (Score:2)
I can very easily override the insertion routeines for collections with, something that calls the instanceof operator... and return if it returns false. This gives me the sort of typesafety you're talking about.
Java doesn't have "const" (and friends) which means that when you give someone an object reference you have no control over what they do with that. When returning read-only object, the only solution is to clone() them. Very expensive!
Java does have final, so you can pass parameters can prevent thier alteration.
But where I really take issue here is the statement that generic programming is impossible in Java. Consider how STL (C++ standard template librarary) defines the use of your own types in its defined datastructures and algorithms library. They say: you must provide your own implementations of (for example) the == operator for list searches to be effective (don't have my book in front of me so can't be more specific right now). This is exactly analagous to saying in java, you must implement a specific interface, and only those classes which implement that interface can be operated on. The fact that you don't have templates is offset by the fact that you do have a common base class (Object), so you don't need templates. I can define a method in java to accept an instance of an interface, I can also define a method in C++ to accept an instance of a base, or virtual base class. These both acomplish the same thing, accept a general type in some algorithm, and allow operation using just a set of base methods. In both cases I can (if I want a big maintenance headache later) try to cast the objects passed in to any type I want to in the method.
The way you right generic code in Java and in C++ is different, but both allow it.
--locust
Re:The best debugger is 'printf' (Score:3)
Debuggers (both command line and GUI) are all essentially the same. Learning one isn't doesn't take very long (on the order of a few minutes) to do the basic things like set breakpoints, step, and watch variables.
Here are the problems with printf (and other diagnostic output):
Think of it this way: You go to a doctor saying you dont' feel well. The printf doctor pokes and prods you until you yell 'ow!'. The debugging doctor uses the intelligent approach where he looks at your symptoms, runs some tests and makes a much more accurate diagnosis of your problem.
- Rick Alther
Re:If you can afford it, move to Java (Score:2)
As we covered elsewhere in this thread, it's true that Java tends to penalize developers (and users) for programmer error a little less than C/C++. That's not intrinsically good or bad; that's just how it is. It's practical goodness/badness depends on circumstance.
If you're using the language mainly as a training tool, then this insulation is bad. It allows developers to become sloppy, and keeps them from learning why sloppy is bad. A more raw language is a steeper learning curve, but that just means that you get to the high ground more quickly.
But if you're using the language to deliver a real-world product, then this insulation is good. Your goal is to deliver a useful thing quickly. SEGVs are certainly helpful to the developer, but the user of a piece of crashing software generally doesn't share that opinion.
And really, the goals of developer improvement and user satisfaction aren't mutually exclusive; you just have to use different tools than crashing code. Instead, you use things like walk-throughs, design review, code review, and pair programming. All of these techniques results in better people, better code, and happier users. And this is true regardless of how forgiving your language of choice is.
Note also that your argument applies even better to, say, assembler. The closer you are to the hardware, the better your code is likely to be, because there's less to take up your slack. But I take it you don't do most of your work in assembler, right?
[...]chasing marketing-driven rainbows.
The silver-bullet syndrome [construx.com] has been around much longer than Java. Indeed, many people had exactly the same gripes about OO programming or, for that matter, C.
The so called "evils" of C/C++ [...] Are solved quite well with tools [... and] good disciplined techniques.
Instead of C/C++, you can insert any language in that statement. A skilled developer with the right tools and a sense of discipline can do good work in almost any language. Comparing the work of experts in one language with the work of fools in another is not a very useful thing to do.
Re:The common JAVA chant -- parameterized types (Score:3)
With templates, you can write a function like this:
template
DataType max(DataType a, DataType b)
{ return (a>b ? a : b); }
This function returns an object by value, and is type safe. By type-safe, I mean that it require s that the two arguments and the return type all be the same (or compatible) types. For example, this would be a compiler error:
int x = 3;
complex c(3,4);
int y = max(x, c);
This is actually impossible to do Java. You can't make it return a by-value object, and it's awkward to enforce the type constraints.
Templates allow generic programming, where you write functions and classes (think abstract data types) that are agnostic as to the exact type of some of their parameters. But, you still get compile-time type safety. Templates are great for container classes and algorithms. Container classes in Java are workable, but a bit awkward. You don't have compile-time type safety. The container's values get cast to Object going in, and have to be manually cast back to the desired type when getting an element from a collection. With C++ templates, you can declare containers of specific types, like 'vector' or 'vector'.
For example:
vector v(3);
v[0] = 45;
v[1] = 3;
v[2] = 4;
sort(v.begin(), v.end());
int first = v[0];
All of this is type-safe, and about as efficient as hand-written code.
Also note that the sort function is generic too -- it works for lots of different container types (like list), including container types you write, that the author of sort did not anticipate. Templates are very 'pluggable', both horizontally and vertically. Generic programming has a very different feel from OO programming. It's less hierarchical, easier to plug and play things piecemeal. Of course, you can still use a vector of MyPolyMorphicObject references,('vector to combine OO and generic programming.
There's a lot more to templates then what I just described. The STL is a great example of a powerful, flexible and efficient generic library. Some people say that ML's generic facilities are even better than C++'s. This may be true; I've never used ML. Other people say that you don't need templates at all, that the real problem is strong typing. In languages like Smalltalk, Python and Perl, you don't have to declare the types of arguments, so every thing is generic. Of course, you can get run-time errors if you pass in the wrong type. But you can also get run-time errors in Java if you try to cast to the wrong type.
Strong typing without templates is the worst of both worlds, in my opinion. If you're going to have strong typing (which I personally like), then you really must have support for templates or something like them. Otherwise you get the huge proliferation of complicated interface hierarchies that you see in Java, just to make sure that classes are useable various contexts. Templates decrease the need for multiple inheritence (or interfaces) somewhat.
Re:The common JAVA chant -- parameterized types (Score:2)
vector v(3);
should have been:
vector<int> v(3);
Hopefully that makes things clearer -- the point is you declare the exact type of a container when you instantiate (use) it.
Should have used preview!
Is cross-platform development an option? (Score:2)
If this is at all possible, try developing the initial framework under NT (yes, NT). Let me explain.
If most of your code is platform-independent, and, in my experience, this is often the case, you will be able to develop on any platform that supports threads if you are willing to put simple wrapper classes around the platform-specific bits. This gives you the double advantage of being able to hide ugly or repetitive API details, as well as letting you port to another platform by reimplementing a simple inner class. I've put together 200-line or less wrappers for threads & mutexes, file IO, ODBC, etc., that work under BSD, Solaris and NT. This makes writing cross-platform code almost trivial.
Now, about that NT business. NT supports Berkeley sockets, stdio, and almost-POSIX threads, so if you're writing daemons and such, you can write 90% of your code without ever cracking the Win32 SDK documentation. Just use main() and forget all the heinous Windows I/O stuff.
As to the original question of the post, the development tools on NT are pretty damn robust. If you're willing to use commercial (i.e. pay-for, non-open source) tools, the VC++ compiler and Dev Studio debugger are mature and top-rate. You don't need to use the IDE except for debugging if you don't want - makefiles and the commandline compiler work 98% the same as Unix. The Dev Studio debugger handles multiple threads as smoothly as anything you can find, it has breakpoints and watchpoints, you can view and change memory easily.
The other commercial tool for Win32 that is invaluable is BoundsChecker from NuMega (now Compuware). The is the most amazing thing for finding both kinds of memory problems - invalid memory reads/wriites and leaks. It runs your app like a debugger would, (optionally) popping up to the exact source line whenever anything tries to write past a buffer (static or alloced). After your app exits, it gives you detailed report of all memory leaks, their sizes, and the lines *and stack traces* where they were allocated. It can run standalone or plug into the Dev Studio environment. This is what I wish Electric Fence could do.
I realize this is a big change to suggest, and may well be impossible depending on your application/financial requirements. However, if you're in the early enough stages that you're able to change languages/platforms, and you have a budget, then this would be my suggestion: develop the basic app core and threading logic under NT, using Boundschecker religiously. Use makefiles. Periodically move the code to the Unix platform and make required changes to compile. Keep all platform-specific code nicely #ifdeffed. Write simple wrapper classes around any system services that take more than one or two lines of code (again, threads).
This is how I've been working for the last year or so. I've been writing utilities and daemons that run under NT and Unix, and I'm still amazed at how easily the ports go. It just works. And I will tell you this: The difference between tracing back in core files with gdb and letting your app run in the IDE until the debugger pops up with the exact line of source code, with stack context, where your bad pointer/divide by 0/whatever happened, with the app still running, is indescribable.
All that said, I really miss Turbo Debugger. Now *that* was a debugger.
minimize debugging; use checks and abstractions (Score:4)
A better way is to avoid bugs in the first place. And for multithreaded programs, a message passing paradigm is generally the best approach in my experience.
I also use assertions and consistency check liberally, so that problems are caught close to where they occur. As a result, the few serious bugs that I have had were usually solvable by inspection of the source code alone.
If you are looking for languages that make avoiding bugs easier, look beyond C++. Java is slightly better than C++ for multithreaded programs because errors tend to be more localized, but Java doesn't have much in the way of useful higher-level abstractions for building multithreaded programs. The currently conceptually best languages for multithreaded programs, in my opinion, are SML/NJ, OCAML, and Erlang.
The Truth In The Middle? (Score:2)
I've used both the IDE and printfs for debugging. The IDE is great for tracing flow through deeply nested calls. It's also good for pinpointing problems like infinite loops. For example, you keep hitting F-10, and then it goes grey on line 532. Bingo! That's the function that's gone loopy.
But then printf is better for checking the contents of things sometimes. For example, after you read in the data file, you can write a simple "dump" function for the data structure to check and make sure that it has the right contents. In general, printf is great when you know what value a variable should have at a particular point.
As for threads, I can't really say since I haven't done any.
If you need a debugger to deal with your code... (Score:2)
... you must make your code more simple, as you will never catch all possible troubles with a debugger. If multithreading caused it to be more complex, switch to either single thread with nonblocking operations, multiple processes or any combination of two.
And, of course, Java will ALWAYS remain inadequate by both performance and reliability -- five years is more than enough to fix a bad product even for Sun (ex: Solaris) if it really cared about doing that.
Re:If you can afford it, move to Java (Score:2)
WRONG! (mostly) (Score:2)
The wise programmer uses the right tool for the right job, and an interactive debugger is usually the wrong tool. If you have a core dump, it's worthwhile to take a quick look at the stack dump, etc., but beyond that, you should carefully question time spent on further interactive debugging. It's a mental monkey trap--it feels like work and it's the easy thing to do. And five hours later it'll still seem that way.
The disadvantages listed for printf debugging are either incorrect, or also true for interactive debugging.
Likewise, the advantages listed for interactive debugging are incorrect, or do not consider the tremendous timesuck that interactive debugging can be. Consider, for example, the first point: Yes, you may immediately discover that a null pointer was dereferenced, but this may well tell you nothing about what really happened. The true bug could have occurred hours ago in a completely different part of the program.
Stepping through your program is no replacement for really thinking about what's going on.
This of it this way: You go to a doctor saying you don't feel well. The printf doctor eyeballs you, carefully forms theories about what might be wrong with you and takes various measurements to validate/invalidate those theories. The (interactive) debugging doctor says, "Nurse--scalpel!"
Use a CVS snapshot of gdb. (Score:3)
Kernel patches exist to fix the core dump issue... (Score:2)
Regarding those kernel patches, though: There are several available on linux-kernel. The simplest, by Patrick Wildi, is a patch for 2.2.x which dumps only the thread which actually failed. Another patch by Terje Malmedal against 2.2.x dumps each thread into an individual core file. I'd post links, but (I just realized) my mouse is unplugged so I can't cut+paste; they shouldn't be too hard to find.
A quick search on Google shows another interesting-looking multithreaded core patch labeled as for 2.4.0t8 by John Jones and Jason Villarreal, apparently funded by Spinway Inc (good 'fer them!). At a quick glance-over, it looks to make a single combined core dump file for all threads. Once again, I can't cut+paste the URL, so you go find it yourself. :)
There's other work ongoing on 2.4test on the topic; see the thread "Anyone working on multi-threaded core files for 2.4 ?" for more information.
So fear not, folks, there's light at the end of the tunnel! :)
Anything except Linux is good for threads (Score:2)
IMHO the very worst Unix platform for doing anything thread-related is Linux. And it's got nothing to do with gdb, but with the Linux kernel. On Solaris, Irix and HP, gdb is available and works fine with threads.
It doesn't work with Linux threads because threads are independent processes in Linux. When you have one applications with 500 threads, it's just not practical to launch 500 copies of gdb on each of the processes in order to set one breakpoint accross all threads. You have to use another platform with decent debugging tools in order to do that.
FYI, at home I use OS/2, and IBM has an excellent multithreaded debugger too, as part of Visual Age C++ 3.0/3.6 for OS/2. IMHO it's the best debugger of all for threads. Unfortunately IBM hasn't got anything remotely close to it in its VisualAge C++ for AIX.
Re:If you can afford it, move to Java (Score:2)
Java has proper garbage collection. That is, any object that is no longer accessible gets collected (so isolated cycles of objects get collected for example).
The issues they are discussing are problems with garbage collection in general, they are not unique to java. You are likely to find yourself facing the same issues if you write nontrivial programs.
Re:I was expecting someone (Score:2)
In C++, you can avoid pointer errors if you don't care about performance. Use vector instead of array. Use string. Only use pointers to get polymorphic behaviour. (these pointers are less likely to cause grief than array-style pointers where arithmatic is performed) This use of pointers is not as problematic (for example, in Qt one uses new to create all widgets, but parent widgets always delete their children, so one only needs delete the top level widget.)
In conclusion, most of the error-prone pointer code is there for performance reasons. And most of the complaints about C++ are pre-STL.
Exception handling
Exception handling is part of the standard. Exceptions are first class objects, and can be caught polymorphically. AFAIK, they're not much different to javas.
Re:Poor multi-thread debug support on Linux (Score:2)
Re:Comments from Pro with Lots of Experience (Score:2)
So C++/Java is usually moot point regards efficiency trade-offs, because programmers product is such slop anyway.
I don't know about java, but at least in C++, there are generic container classes, and the C++ standard has performance gaurantees (big-O) on the effectiveness of these algorithms. So it's not accurate that the C++ programmers product is always "slop", because they can reuse well designed and implemented container classes for a lot of their work.
Java is a lot more productive than C++.
Or so they say. It's true that C++ code that makes heavy use of pointers is error-prone and needs extra care maintenance-wise, and should be locked up in a library where client code can't see it. But if we only require java-like performance, then why use pointer-arrays instead of vectors, and why use char* instead of string ? Most of the things that are error-prone in C++ boil down to instances of the developer choosing speed over safety. If you want to sacrifice a little speed and forget about pointer arithmatic, you can do that, and you'll still be faster than java.
Re:Fun programming (Score:2)
Fare also wrote the vast majority of one of the vastest programming language comparisons I have seem. See The Language Review Subproject [tunes.org] at Tunes.org.
And Tunes *has* produced at least one line of code...I think it was a prototype implementation of their programming language---Slate, I beleive.
Re:I was expecting someone (Score:2)
Lastly, to get back to the topic at hand, the SGI compiler comes with a fairly nice multi-threaded debugger, though I haven't used it very much (I work in the kernel where you basically don't get a debugger other than "printf").
Re:Poor multi-thread debug support on Linux (Score:2)
Given that in java I can load a class from anywhere at anytime, the class cast exception may be generated by my code, but might have its root in some code that was made to invoke my code long after I finished it. I don't know if this is completely feasible in Java.
Java does have final, so you can pass parameters can prevent thier alteration. Java has value constants, not reference constants. Please try to think a bit about the difference: class A { B bInstance; const b getbInstance() { return bInstance; } }
I never claimed that you could return a constant from a function in general. However, once a final reference is initialized it cann't be changed. So I can go:
B getB(final C c){...}
and in the invoking function declare:
final B b = a.getB(new C())
They (final B b, and final C c) are reference constants, but I realize this is not what you're after... You want to specify the constness, not to rely on the invoker, then again in C++ what prevents me from casting away the constness? So whats the diff? A properly constructed B will prevent me from altering its internals, and if I lose my reference to it, well its my own damn fault. So if you don't want me to change it, you shouldn't be returning it. You should provide accessors to the relevant data memebers.
The trick is, that you wish to specify the concrete type that an algorithm work on (specializing the interface if you will, some call this compile-time type refinement), so that you will get compile-time type-errors if the (type-instantiated) algorithm is applied to data of the wrong type.
I think they might want compile time refinement for the speed... Its faster to figure it out at compile time than runtime. In any case, if I create a class foo. and then declare: list<foo*> bar;
now I try to do a bar.find on this list for some specific foo. Unless I've overridden the == operator for the foo* type this operation will compare pointers not the values of the foo objects. No compile time check will catch this.
Further after a look around the web, I came across a comparison of OO and GP [camelot.de] and to quote the author: We note that a significant part of the generic programming paradigm can be expressed in terms of C++ language constructs; other parts cannot be expressed by means of the programming language. There are requirements to containers, iterators, and algorithms that are not expressed by means of language features and hence will not even be detected at compile or template instantiation time.
Under the premise that generic programming requires full knowledge of types at compile time. Java cannot (at least under java 1.2 not sure about 1.3) support generic programming (neither can C++ using virtuals) yet Java Collections looks and behaves a hell of a lot like STL. The latter is by all acounts an example of generic programming. The STL (to me at least) and Java collections represent abstract generic data structures, algorithms, and access methods. The implementation differences are mainly syntactic, as are the compile/runtime differences. These last are a result of the implemtation language not a fundamental property.
--locust
Re:Ada 95 (Score:2)
I never use IDEs -- just naked code and a compiler. However, for the two Ada compilers I have used, you get minimal component recompilations based on the timestamp of the source file vs. the timestamp of an information file that was automatically built last time you compiled.
I'm not sure, but I think this is a requirement in the language spec. Forcing certain dependency recompilations is a safety issue, but forcing global recompilation merely be a waste.
It certainly motivates modularity, since you can change a line of code in a single module, and then recompile a huge project in half a second.
--
It depends on app type/completeness (Score:3)
That said, I do a lot of multithreaded programming in both Java and C++, and I would give damn near anything to switch completely over to Java. The threading design makes it FAR easier to build correct programs from the ground up without using a debugger. We've known for 15 years that monitors (Java's synchronized blocks, basically) were a better way to write multithreaded programs, and it's embarassing that it took this long to get the idea into a mainstream language.
Also, you should check out jlint (http://www.ispras.ru/~knizhnik/jlint/ReadMe.htm)
As for actual debuggers, JBuilder 4 is quite good. I've only used the foundation (free) version, but the enterprise edition can also dynamically detect stalls, deadlocks, and race conditions (see http://www.borland.com/jbuilder/jb4/feamatrix/deb
On the down side, you'll have to pick a good implementation of the JDK on Linux and stick by it, as the different JVMs tend to have threading incompatabilities. IBM's are quite good, and they support native threads very well. In Sun's 1.2 implementation, at least, native threads were an undocumented feature (with green threads only officially supported).
Hope this helps!
--JRZ
Re:Poor multi-thread debug support on Linux (Score:2)
Feel free to take this off line if you like.
i.e. inserting real's into a list of (conceptually, when you dont have parametrised types) integers.
I guess, first off I don't see this as so common an error. Next, my point has been that in order to generate the above errors (at least in Java) you must wrap the Java collection in a class whose interface verifies the type. This will give you at least a basic compile time verification.
On dynamicly loaded code
Therefore you will not have problems with later loaded dynamic code.
But then this is a compile time error, regardless of whether or not we have generic programming.
This is why you need generic programming and parametrised types in the first place
Parameterised types do guarantee that you don't try to further refine the parameters. But I thought that was just good programming practice, not to further refine the types of arguments, regardless of having or not having templates.
On constant References, Reader-Writer, etc, and class hierarchies.
Regardless of the implementation language you can't use finally or const to return your references because both of these rely on the cooperation of the invoker to use finally or not to cast away constness. For the writer, the relevant reference type must provide setValue and getValue operations. For the readers it must only provide get operations. In java this would mean two interfaces. A refValueReader interface and a refValueWriter interface that extend the first. The the monitor writer you put the data to be written in instances of the refValueWriter type, in the readers you are returned instances of the refValueReader interface. In C++ terms the difference is in how you override the functions of the operators on the type. You would have to (forexample) override the = operator to prevent the reftype from being an lvalue in some cases...
The STL collections are programmed using generic programming, which means, that they operate on any compile-time refined type.
In C++ it would be hard to implement collections in the OO paradigm, since classes do not inherit from a common base class.
I'll quote again from the same source: In sum, we achieve genericity by means of a design idea, i.e. separation of data structures from algorithms, and by use of programming techniques supported by the programming language, i.e. C++ class and function templates. Although generic programming uses classical object-oriented C++ language features such as class (template) declarations, it is not object-oriented. How does generic programming contrast to object-oriented ideas? In object-oriented programs abstractions are expressed by means of base classes. In generic programs the abstractions are described in terms of formal, yet verbal requirements. Examples of such requirements are: A container must provide certain iterators. An iterator must provide certain operations, such as increment and dereference. An algorithm must work on iterator ranges.
In my (admittedly brief) online search for definitions of generic programming that include compile time constraints as a fundamental property of genericity I've come up with: bubkas. The underlying feature is that inheritance is spearated from polymorphism. The problem with it as expressed in C++ is that there is no formal way to guarantee compliance with the stated verbal interface that can be gauraneeted by the programming language. If one looks at the base functionalities of types in C++, and compares them with the base functionalities of (reference) types in Java one notices that they are strikingly similar. Further if one speaks strictly, things such as operators are in fact short hands for function calls of the the nature int plus(int, int). Thus the fact that operator overloading is not allowed in java is irrelevant. The point is that C++ has an implicit common base type (operations I can do any any type, and infact it has a number of types derived from it (pointer types etc) but this is done by the language not the user), where as java has an explict one (Object). Template operations with in STL collections use these implicit common bases in order to be meaningfull. Java Collection operations use an explicit common base to be meaningfull (such is the language). In both cases a greater guarantee can be made of smenatic correctness of a program by insisting on an abstract base class that overrides given default operations. But this would taint the purity of the genericity.
The key point is that generic programming sperates algorithm from data structure. I can do this in java, but I must stipulate that all reference are to Object. The most generic type. I can also stiplate some semantic ordering of the basic operations on arbirary types, but then the programming language cannot help me short of using object orientation. Java Collections (like STL) allows me precisely this separation of algorithm from datastructure.
--locust
Forte (formerly Sun Workshop debugger) (Score:2)
Re:Gnu Visual Debugger (Score:2)
Similarly, smartgdb [ukans.edu] has long claimed to have improved thread support, although I don't know if it's been kept up to date. The web site doesn't appear to have been updated in a while.