Softpanorama
(slightly skeptical) Open Source Software Educational Society

May the source be with you, but remember the KISS principle ;-)

Google   


Softpanorama Debugging Links

News Recommended books Recommended Links Tutorials IDE GDB GCC Program instrumentation
Software Testing Program understanding HTMLization of programs Data display and data prettyprinting Memory Leaks Disassemblers Reverse engineering Expect
Assembler C M4 Perl debugging Beautifiers and Pretty Printers Orthodox File Managers Humor Etc

All through my life, I've always used the programming language that blended
 best with the debugging system and operating system that I'm using.
If I had a better debugger for language X, and if X went well
with the operating system, I would be using that.

Donald Knuth


Any bug not detected in the design phase
will cost ten times more time to detect at the coding phase
and an additional ten times more at the debugging phase.

A Second Look at the Cathedral and the Bazaar

I never make stupid mistakes. Only very, very clever ones.
 
"Dr Who"

 

This document will hopefully provides useful links for students learning debugging.  It is partially based on my lectures on the subject at FDU.

DeMillo and Mathur have analyzed the errors of T E X reported by Knuth. Their analysis clearly reveals that simple errors do represent a significant fraction, though not the majority, of the errors in production programs. It also reveals that such errors remain hidden for a long time before testing or users exposes them.

The quality of debugger is as important as the quality of the language and here some old languages are definitely preferable to newcomers like Java. At least now ;-)

Historical note (from the Jargon File):

Admiral Grace Hopper (an early computing pioneer better known for inventing COBOL) liked to tell a story in which a technician solved a glitch in the Harvard Mark II machine by pulling an actual insect out from between the contacts of one of its relays, and she subsequently promulgated bug in its hackish sense as a joke about the incident (though, as she was careful to admit, she was not there when it happened). For many years the logbook associated with the incident and the actual bug in question (a moth) sat in a display case at the Naval Surface Warfare Center (NSWC). The entire story, with a picture of the logbook and the moth taped into it, is recorded in the Annals of the History of Computing, Vol. 3, No. 3 (July 1981), pp. 285-286.

In my paper A Second Look at the Cathedral and the Bazaar, I used the following simplified classification of bugs:

  1. Coding bugs Coding bugs are the result of not understanding the programming language throughly. These are the most common type of bugs and are relatively easy to debug. It is common for beginner programmers to blame these bugs on the compiler. So, the next time you suspect there's something wrong with the compiler, think again.
  2. Logical bugs (10 times as difficult to debug) A typical example is when an array index counter counts past the end of the array thus accessing an out-of-bounds memory location or a pointer that is uninitialized (points to NULL) is de-referenced. What is a segmentation fault? If your program exits (crashes) with the message "segmentation fault", it means that a pointer in your program is accessing (de-referencing) a memory location outside of it's permitted boundaries (or memory segment).
  3. Architectural bugs (impossible to debug; requires a major re-write of code). Architectural bugs are a result of flaws in the underlying operating system; Microsoft Windows is a good example of this. A lack of operating system security permits viruses to attack and kernel instability results in application GPFs. Limitations in the design of programming languages also contribute to architectural bugs; e.g. the lack of memory bounds checking in the C language results in memory leaks and overflows.

One can greatly benefit from learning Expect. This is a great tool to automate any debugger !!!

Dr. Nikolai Bezroukov


Notes:
  • Those pages are written by people for whom English is not a native language. Some amount of grammar and spelling errors should be expected.
  • This is a Spartan WHYFF (We Help You For Free) site. It cannot replace the best teachers and the best books.
  • The site contain some obsolete pages as it develops like a living tree... Some links on older pages are broken. Please try to use Google, Open directory, etc. to find a replacement link (see HOWTO search the WEB for details). We would appreciate if you can mail us a correct link.

Search Amazon by keywords:

Google   
Open directory

Research Index

 

Old News ;-)

[Oct 10, 2007] GNU Project Debugger More fun with GDB by Bill Zimmerly (bill@zimmerly.com),

03 Oct 2006
GDB, the GNU Project Debugger, has a macro capability that is sophisticated and allows you to personalize and customize GDB to have just the tools you need. The mechanism for providing help documentation on your customized commands makes it an easy tool to share with others as well.

The previous article on this topic, "Fun with strace and GDB," covered the basics of using these tools to explore your system and attach to programs that are already running to see what they were doing. This article presses on to customize the debugger to make the experience more personal and efficient.

When GDB, the GNU Project Debugger, starts up, it looks for a file in the current user's home directory called .gdbinit; if the file exists, GDB executes all the commands in the file. Normally, this file is used for simple configuration commands, such as setting the default assembler format desired (Intelฎ or Motorola) or default radix to display input and output data (decimal or hexadecimal). It can also read a macro-coding language that allows more powerful customizations. The language follows this basic format:

define <command>
<code>
end
document <command>
<help text>
end

 

The command is known as a user command. All other standard GDB commands can be combined with flow-control instructions and passed parameters to create a language that allows you to customize the behavior of the debugger for the specific application being debugged.

Start simple: Clear the screen

It's always good to start simple and build up from there. Start the xterm, fire up your favorite editor, and let's begin creating a useful .gdbinit file! The output from debuggers can be messy and, as a matter of personal preference, many people like to be able to clear the screen when working with any tool that has the potential for creating cluttering. GDB has no built-in command for clearing the screen, but it can call shell functions; the following code steps outside the debugger to clear the xterm console with the cls command:

define cls
shell clear
end
document cls
Clears the screen with a simple command.
end

 

The upper portion of the definition, bounded by the define ... end verbs, frames the code that is executed when the command is invoked.

The lower portion of the definition, bounded by document ... end, is used by the GDB command interpreter to display help text associated with the cls command when you type help cls.

After you type the code into the .gdbinit file, fire up GDB and enter the cls command. Your screen clears, and all you see is the GDB prompt. Your journey into GDB customization has begun!

The importance of documentation

If you enter the help user command, you see a summary of all the user commands you've entered in the .gdbinit file. The designers of the .gdbinit user-defined commands have provided an important feature that you shouldn't ignore when you're writing your own commands: the document ... end clause. Maintaining functional documentation of how commands work becomes critical as the number of these commands increase.

You might have already experienced the problem. Suppose you wrote some code from a few years ago; then, when you revisit it, perhaps to fix a bug or modify it by adding a new feature, you realize that you're having a hard time understanding your own code. Good programmers make it a habit to keep code short, simple, and well-documented so that it's maintainable.

What's true for programming code in general is true for debugger code. Keeping careful notes and well-documented code will serve you well as you work your way through this most rewarding of careers.

Community uses for GDB

Human beings learn new things many ways, including by studying what others have done. Budding automotive engineers start by opening the hood of their first car, pulling out their tools, and removing parts to clean and study. Such an exercise lets them keep a clean machine while learning how the automobile engine works.

Budding computer scientists are no different in that they want to see just how programs work -- how they interact with dynamic libraries and the native operating system. The tool for seeing how these things work is the debugger. Computer programming is a complex activity, and by being able to interact with a community of like-minded people, asking questions and getting answers, new computer scientists can satisfy their need for knowledge.

In the global programming community, there are always a healthy number of people who hunger and thirst for knowledge. They aren't content with just running programs on their computers -- they want to know more. They want to know how those programs run, and they enjoy exploring the functionality of their systems with the best tool available for the purpose: the debugger. By reverse engineering, a way of learning how programs work by running them under a debugger and keeping careful notes of how they do what they do, you can learn a lot from what the authors of the program being studied have done. Many low-level details involved in programming are undocumented; the only way to learn about them is to see them in action.

Reverse engineering has an undeserved reputation as a black art practiced only by hackers and criminals intent on breaking copy-protection systems and writing worms and viruses to inflict harm on the world of computers. Although there are such people, the vast majority of those who study how programs work, using debuggers and reverse engineering, are the present and future software engineers who want and need to know how these things work. They have formed online communities to share their knowledge and discoveries; discouraging this activity is destructive and retards the future progress of computer science.

Many of the user functions defined in this article come from such communities of hungry knowledge seekers. If you want to know more about them, you're encouraged to study the Web sites referenced in the Resources section of this document.

Breakpoint aliases

It's a well-known fact that many of the GDB commands are too verbose. Even though they can be abbreviated, the GDB macro language allows for even greater simplifications. Commands, such as info breakpoints, can be made as simple as bpl. Listing 1 shows a great set of such simple and highly useful breakpoint alias user commands to edit into your growing .gdbinit file.


Listing 1: Breakpoint alias commands
 
define bpl
info breakpoints
end
document bpl
List breakpoints
end

define bp
set $SHOW_CONTEXT = 1
break * $arg0
end
document bp
Set a breakpoint on address
Usage: bp addr
end

define bpc
clear $arg0
end
document bpc
Clear breakpoint at function/address
Usage: bpc addr
end

define bpe
enable $arg0
end
document bpe
Enable breakpoint #
Usage: bpe num
end

define bpd
disable $arg0
end
document bpd
Disable breakpoint #
Usage: bpd num
end

define bpt
set $SHOW_CONTEXT = 1
tbreak $arg0
end
document bpt
Set a temporary breakpoint on address
Usage: bpt addr
end

define bpm
set $SHOW_CONTEXT = 1
awatch $arg0
end
document bpm
Set a read/write breakpoint on address
Usage: bpm addr
end

 

Once you get used to using breakpoint alias commands, your debugging sessions become more rewarding; these commands greatly increase the debugger's effectiveness, because you can accomplish more with less effort.

Displaying process information

The GDB user-defined commands can be called by other user-defined commands, leading to greater effectiveness for them all. This is the incremental nature of programming languages -- writing lower-level functions that are called by progressively higher-level functions until the tools conveniently do what you want them to do with minimal effort on your part. The next set of GDB definitions to incorporate into your .gdbinit file display useful process information when they're invoked, as shown in Listing 2.


Listing 2: Process information commands
 
define argv
show args
end
document argv
Print program arguments
end

define stack
info stack
end
document stack
Print call stack
end

define frame
info frame
info args
info locals
end
document

[Oct 7, 2006] Insecurity in Open Source

So how come open-source software isn't saving the day?

BETTER ISN'T BEST.  The answer is that it can—just not yet. The open-source development community must first graduate from Lake Wobegon University, where all of their software is just above average. They need to take lessons from the all-stars in closed-source software development. Likely, this means more thorough and rigorous end-to-end quality testing. Open source developers have a lot of pride in the quality of their individual contributions to code, but many proprietary organizations understand how to (and are required to) vouch for the high quality of the software system as a whole.

The irony is that our research shows that on average, open-source software is of higher quality than proprietary software. Indeed, open-source projects tend to clump together in the higher-quality range. Proprietary software applications scatter across the quality continuum, but the best ones tend to be considerably better than open source, and customers don't choose software based on industry averages.

The best of closed-source software is found in so-called mission-critical applications: things like jet engines, nuclear power plants, telephone systems, medical devices. These are things that simply can't fail, or people may die.

TESTING, TESTING.  It's apparent from our research that the masters of proprietary software development know a few things—or simply utilize strict development practices—that could benefit the oftentimes brilliant (but perhaps less disciplined) open-source community.

This matters, since software is increasingly pervasive in business and government. And more and more of it is open source. As the lines of code pile up, applications become more complicated, more difficult to troubleshoot, and unfortunately, more likely to crash.

We see two trends in proprietary development that promise to make open-source software better, too. First, companies are paying a lot more attention to the lifecycle of their software. That means better end-to-end quality measurement that helps ensure the entire software system delivers on its promise. Second, there's a trend toward automated testing. As software gets more complicated, testing has to be done by machines as well as people. It's just too much for humans. The 2002 NIST study estimated that $22 billion of the cost of buggy software would vanish with better testing.

GOING MAINSTREAM?  Because of the higher average quality of open-source software revealed by our research, we strongly believe it can cross the chasm into mainstream use. It offers too many advantages for both developers and consumers.

But in order for open-source software to become more prevalent in mission-critical applications, the open-source community must put more emphasis on industry best practices. We challenge this community to take a closer look at how the best proprietary software gets built and learn from that. Software quality and security are the most important factors in the choices that developers and companies make— not open-source vs. proprietary.
---

I scanned through the article, it didn't seem to mention how they tested the top proprietary software. I can well understand that there are are a lot of bugs in open source code since it is written by humans. But human also right the proprietary code. How did they test it?

---

they tested it by using a program that systemattically scans code for common errors.

I don't know if the closed source statistics are online somewhere, but these are the open source statistics.
http://scan.coverity.com/ [coverity.com]

---

You are assuming that "a whole lot of people" actually check the code and submit patches for FOSS projects... My guess is that most testing, even of FOSS software, is done with the compiled program, not by reading the source code.

  • by teg (97890) on Saturday October 07, @02:00PM (#16349367)
    (http://www.pvv.ntnu.no/~teg/)
    An open source software is tested by a whole lot of people over the world and everyone is free to take the code and test if. On the other hand in case of proprietary software this is not the case and is tested by far less number of individuals.

    That sounds rather idealistic... The coverage on OSS varies a lot. Most is not tested much, and the testing is not systematic and analyzed, but ad hoc. And if a bug is found, many just shrug and think of it as buggy software, but don't do more about it. There is a world of difference between the high standards of large projects like the linux kernel, apache and eclipse vs. the thousands of small projects found on freshmeat or just googling for something to scratch your itch.

  • I figured I should chip in, since I'm a Dev that works in QA.
    Somebody please explain to me exactly what kind of software bug can be found by automatic scanning that isn't found by standard debugging and compile-time checks. If a computer can ascertain exactly what the programmer intended to do, why do we need programmers?

    Well first of all, you have to assume that all programmers even do the "standard debugging and compile-time checks". Even then, those checks are often hardly comprehensive. You can build some scanners that will catch rudimentary bugs that SHOULD have been caught, but were not. For example, assign things to null, test boundary conditions, etc. These are all things that should be part of a standard unit test that's delivered along with the code.

    Also, things like memory leaks can be difficult to pinpoint. That's where tools like BoundsChecker [compuware.com] are nifty.

    Considering that most software bugs are logic bugs (off by one, etc) that can't be directly seen in the code without actually, you know, RUNNING the program, I find it difficult to believe that AI has come to the point where it can guess the coder's intentions and infer the purpose of an application.

    No one is saying that a program or "AI" (as you call it) can find all bugs. But it can certainly be used to find some rather simple ones. Overall, though, I agree that you can't depend on running programs to catch bugs. You've got to have a solid QA department, which will use all the right tools to get the job done and try to maintain quality to the highest degree.

    I'm not saying that OSS can't do this at all. I certainly think it can be done, but it does take more process and structure. Not having worked on any OSS projects myself, I imagine the largest, most important code-bases have a lot of this in place to drive quality. But your smaller or even mid-size OSS projects may be lacking in that department (much in the same way smaller and mid-size dev houses lack a decent QA department).

Somebody please explain to me exactly what kind of software bug can be found by automatic scanning that isn't found by standard debugging and compile-time checks. If a computer can ascertain exactly what the programmer intended to do, why do we need programmers?

Decimal one = 1;
Decimal two = 2;

one.add(two);

System.out.printline(one);

Guess whats printed? Similar errors are made if you use methods on java.lang.String like replace(pattern, replacement, pos).

The simple answer to this is that they can't.
Thats a very uninformed oppion! Tools like http://pmd.sourceforge.net/ [sourceforge.net] have a data base of over 100 "bug patterns" to check your code againt. That does not mean all found points are truely positive, but thy definitely are bad coding practice and my end in a bug later if the code gets changed. There are lots of simialr tools, check IBMs alaphaworks and developerworks e.g.

angel'o'sphere

  • Somebody please explain to me exactly what kind of software bug can be found by automatic scanning that isn't found by standard debugging and compile-time checks.

    A *LOT*. The existance of bugs such as buffer overflows PROVES that the "standard debugging and compile-time checkes" are insufficient.

    CCured found bugs in a couple different applications. Three separate programs in the SPECINT benchmark set (compress, ijpeg, and go) had bugs. In SPECINT! Probably one of the most heavily analyzed programs ever -- people have been known to tune their programs to perform particularily well on those benchmarks.

    CQual found several unchecked dereferences of user pointers in the Linux kernel (2.4 at the time) and device drivers. Which, btw, could have been used as, say, a priviledge escalation mechanism. One of the drivers had just undergone a security audit specifically looking for user/kernel bugs and passed. Linus's Sparse does the same sort of thing as CQual.

    Microsoft's Static Driver Verifier found a race condition that could have led to a bug check in the parallel port driver that had been there for years. (Granted, the set of circumstances required to trigger it are absurdly remote, and require removing the physical port form the computer (perhaps by removing a laptop from a dock) at the same time you're doing something else.)

    Fact is that there's a LOT that can be detected statically that programmers get wrong.
    •  
      by EvanED (569694) <evaned@gm[ ].com ['ail' in gap]> on Saturday October 07, @05:20PM (#16350693)
      BTW, in full disclosure, CCured isn't a static analysis tool per se, and may have required running the programs to find the above bugs. But without the instrumentation CCured they would have gone undetected.

      Another paper from UC Santa Barbra and (I think) the Technical Institute of Vienna used static analysis of compiled code (not even source!) to try to determine if a kernel module was malicious. (In this context, "malicious" means that it acts like a rootkit; in other words, if it modifies internal kernel data structures that don't belong to the kernel module itself.) They tested 7 rootkits and the entire driver database that comes with Red Hat. Their tool god a perfect detection rate -- no false positives, no false negatives. (The paper does have some issues -- like how did they pick the rootkits they tested, did they analyze them and then build the tool or the other way around, are there other rootkits they didn't test, how easily would it be to make a kernel module that would pass their test, etc., but it does provide a demonstration of the sort of power that static analysis can give you.)
  • by Anonymous Coward on Saturday October 07, @02:03PM (#16349389)
    ...and while it is on the list on the web page, I was happy to determine that most of the issues they found were false alarms. They found three real bugs, none of which were likely to bite, and even if they did bite it is not exploitable. Nonetheless, those bugs probably wouldn't have been found otherwise, so I was happy for the scan.

    Rather than brag (I won't say who I am or the name of my project), I'm just going to sit back and read all the defensive flames from self-appointed "security experts" whose open-source project didn't do so well. After all the flames from these "security experts" that I've endured, I'm going to enjoy watching them squirm.

    It's karma.
    • by tb3 (313150) on Saturday October 07, @02:38PM (#16349681)
      (http://slashdot.org/)
      Are you nuts? Or are you just trying to see how many vapid over-generalizations you can jam into a single comment?
      Propriety software traditionally undergoes a formalized, designed testing process. It's not perfect, but it's an ordered approach to boundary testing, design level implementation of quality, and more.
      Says who? QA and testing covers the entire gamut, from formalized unit-testing at every level, to 'throw it at the beta testers and hope nothing breaks'. it's got nothing to do with 'proprietary' (not 'propriety') vs open source.
      Open source software must rely on after-the-fact testing in the form of "this broke when I tried to do this".
      Where on Earth did you get that? Are you completely oblivious to all the testing methodologies and systems developed by the open source community? Here's a few for you to research: JUnit, Test::Unit, and Selenium.
      Commercial software has a strong QA engineering component. Open Source software relies primarily on a black box testing approach.
      Again with the generalizations! Commercial software development is, by definition, proprietary, so you don't know how they do it! They might tell you they have a 'strong QA engineering component' (whatever that means) but they could be full of shit!
  • by rduke15 (721841) <rduke15@g[ ]l.com ['mai' in gap]> on Saturday October 07, @02:16PM (#16349511)
    The article makes it quite clear that the proprietary software which is much better that open source is mission-critical software. A class of software where ensuring minimum bugs is a top priority, and also a class of software which mostly does just not exist in OSS. If you are an OSS developer, would you try to develop open source air traffic control software? And even if yes, how would you do it anyway?

    Basically, my own conclusion from reading the article was that it IS possible to write excellent software with very few bugs, if that is a top priority. And, that the author seems to say that while mission-critical software (which happens to be proprietary) is fortunately much better than the rest, among all that other non-mission-critical software, open source tends to be better than proprietary.

    Not surprising, and quite encouraging...
  • Nice way to generate publicity

    (Score:3, Insightful)

    by wannabgeek (323414) on Saturday October 07, @02:35PM (#16349649)
    This is just smart marketing. Imagine they put up a survey that did not make any controversial claims (something like, open source and proprietary software are comparable), then would that generate as much heat? Now many people hear about the company because more people talk about this now than if the survey said something less controversial.

    Now to compare every open source software application to aerospace software is really comparing apples to oranges. There is a big difference in the expected quality between an editor and an aerospace application. It's alright even if my editor crashes once in every 20 times I invoke it. Is that acceptable with an aeroplane?

    I'm sure the folks at Coverity understand all this. But if they really speak what is right, they will not get all the eyeballs and publicity. In classic slashdot lingo:
    1. Do something (anything) that involves open source and proprietary software
    2. Make claims that sound outrageous / controversial
    3. Profit! (with all the free publicity)Nice way to generate publicity

    (Score:3, Insightful)

    by wannabgeek (323414) on Saturday October 07, @02:35PM (#16349649)
    This is just smart marketing. Imagine they put up a survey that did not make any controversial claims (something like, open source and proprietary software are comparable), then would that generate as much heat? Now many people hear about the company because more people talk about this now than if the survey said something less controversial.

    Now to compare every open source software application to aerospace software is really comparing apples to oranges. There is a big difference in the expected quality between an editor and an aerospace application. It's alright even if my editor crashes once in every 20 times I invoke it. Is that acceptable with an aeroplane?

    I'm sure the folks at Coverity understand all this. But if they really speak what is right, they will not get all the eyeballs and publicity. In classic slashdot lingo:
    1. Do something (anything) that involves open source and proprietary software
    2. Make claims that sound outrageous / controversial
    3. Profit! (with all the free publicity)
  • by vtcodger (957785) on Saturday October 07, @03:31PM (#16350051)
    What they seem to have done is run a bunch of software through some sort of automatic bug checker that may or may not be a a pile of manure, identified the "best" product which chances to be what the military would call mission critical proprietary software. Then they proclaim that open source isn't as good (Duh) and doesn't meet their high standards.

    What they have not done is compare comperable projects -- IE to Firefox, Open Office to MS Office, Windows to OS-X to Linux-KDE. There is, as far as I know, no Open Source software product that is really intended for mission critical applications -- I guess maybe SSH might qualify, but I don't see it in their list.

    So, I think what we have here is a comparison of Apples to Turnips using a dubiously calibrated error-o-graph machine that uses an unknown technology to perform undefined tests on software.

    Don't get me wrong. I sure as hell wouldn't run a nuclear power plant with Linux-X-Windows-whatever. Nor with Windows -- neither Windows 9 nor NT based Windows. They don't meet my admittedly subjective standards of quality either. But if we waited for near perfect software quality, we'd still be trying to get text mode right. Personally, I 'd vote for that because I think building major structures on weak foundations will likely lead to big trouble a decade or three out, but I think I'd lose that vote about 93 to 1 with maybe 6 abstensions.

  • by Peter_Pork (627313) on Saturday October 07, @05:08PM (#16350629)
    This is the usual completely meaningless accounting, with a myriad of methodological flaws. You cannot make a general statement about bugginess of open-source vs. closed-source code. There are just too many variables to conduct a statistically meaningful study. The reason why open source code is better bug-wise is very simple: the user of the code can fix the bugs. As a developer, I hate to depend on closed-source code. Why? Because *every* moderately large code, open or closed, has bugs, and they invariably show up at some point. I much rather go fix the issue myself that wait for some random amount of time (including forever) for someone else to fix the bug for me.
  • Hook it up ...

    (Score:1)

    by LeeMeador (924391) on Saturday October 07, @06:08PM (#16350963)
    to Jira (or Bugzilla or whatever) on the Open Source projects and it could submit the bug reports automatically and after only ... three days to three years all those bugs would get fixed.

[Dec 11, 2003] ONLamp.com Myths Open Source Developers Tell Ourselves by chromatic

One persistent mis-feature of open source development is thoughtless mimicry, copying the behaviors of other projects without considering if they work or if there are better options under the current circumstances. At best, these practices are conventional wisdom, things that everybody believes even if nobody really remembers why. At worst, they're lies we tell ourselves.

Perhaps "lies" is too strong a word. "Myths" is better; these ideas may not be true, but we don't intend to deceive ourselves. We may not even be dogmatic about them, either. Ask any experienced open source developer if his users really want to track the latest CVS sources. Chances are, he doesn't really believe that.

In practice, though, what we do is more important than what we say. Here's the problem. Many developers act as if these myths are true. Maybe it's time to reconsider our ideas about open source development. Are they true today? Were they ever true? Can we do better?

Some of these myths also apply to proprietary software development. Both proprietary and open models have much room to improve in reliability, accessibility of the codebase, and maturity of the development process. Other myths are specific to open source development, though most stem from treating code as the primary artifact of development (not binaries), not from any relative immaturity in its participants or practices.

Not every open source developer believes every one of these ideas, either. Many experienced coders already have good discipline and well-reasoned habits. The rest of us should learn from their example, understanding when and why certain practices work and don't work.

Publishing your Code Will Attract Many Skilled and Frequent Contributors

Myth: Publicly releasing open source code will attract flurries of patches and new contributors.

Reality: You'll be lucky to hear from people merely using your code, much less those interested in modifying it.

While user (and developer) feedback is an advantage of open source software, it's not required by most licenses, nor is it guaranteed by any social or technical means. When was the last time you reported a bug? When was the last time you tried to fix a bug? When was the last time you produced a patch? When was the last time you told a developer how her work solved your problem?

Some projects grow large and attract many developers. Many more projects have only a few developers. Most of the code in a given project comes from one or a few developers. That's not bad — most projects don't need to be huge to be successful — but it's worth keeping in mind.

The problem may be the definition of success. If your goal is to become famous, open source development probably isn't for you. If your goal is to become influential, open source development probably isn't for you. Those may both happen, but it's far more important to write and to share good software. Success is also hard to judge by other traditional means. It's difficult to count the number of people using your code, for example.

It's far more important to write and to share good software. Be content to produce a useful program of sufficiently high quality. Be happy to get a couple of patches now and then. Be proud if one or two developers join your project. There's your success.

This isn't a myth because it never happens. It's a myth because it doesn't happen as often as we'd like.

Feature Freezes Help Stability

Myth: Stopping new development for weeks or months to fix bugs is the best way to produce stable, polished software.

Reality: Stopping new development for awhile to find and fix unknown bugs is fine. That's only a part of writing good software.

The best way to write good software is not to write bugs in the first place. Several techniques can help, including test-driven development, code reviews, and working in small steps. All three ideas address the concept of managing technical debt: entropy increases, so take care of small problems before they grow large.

Think of your project as your home. If you put things back when you're done with them, take out the trash every few days, and generally keep things in order, it's easy to tidy up before having friends over. If you rush around in the hours before your party, you'll end up stuffing things in drawers and closets. That may work in the short term, but eventually you'll need something you stashed away. Good luck.

By avoiding bugs where possible, keeping the project clean and working as well as possible, and fixing things as you go, you'll make it easier for users to test your project. They'll probably find smaller bugs, as the big ones just won't be there. If you're lucky (the kind of luck attracted by clear-thinking and hard work), you'll pick up ideas for avoiding those bugs next time.

Another goal of feature freezes is to solicit feedback from a wider range of users, especially those who use the code in their own projects. This is a good practice. At best, only a portion of the intended users will participate. The only way to get feedback from your entire audience is to release your code so that it reaches as many of them as possible.

Many of the users you most want to test your code before an official release won't. The phrase "stable release" has special magic that "alpha," "beta," and "prelease" lack. The best way to get user feedback is to release your code in a stable form.

Make it easy to keep your software clean, stable, and releasable. Make it a priority to fix bugs as you find them. Seek feedback during development, but don't lose momentum for weeks on end as you try to convince everyone to switch gears from writing new code to finding and closing old bugs.

This isn't a myth because it's bad advice. It's only a myth because there's better advice.

The Best Way to Learn a Project is to Fix its Bugs and Read its Code

Myth: New developers interested in the project will best learn the project by fixing bugs and reading the source code.

Reality: Reading code is difficult. Fixing bugs is difficult and probably something you don't want to do anyway. While giving someone unglamorous work is a good way to test his dedication, it relies on unstructured learning by osmosis.

Learning a new project can be difficult. Given a huge archive of source code, where do you start? Do you just pick a corner and start reading? Do you fire up the debugger and step through? Do you search for strings seen in the user interface?

While there's no substitute for reading the code, using the code as your only guide to the project is like mapping the California coast one pebble at a time. Sure, you'll get a sense of all the details, but how will you tell one pebble from the next? It's possible to understand a project by working your way up from the details, but it's easier to understand how the individual pieces fit together if you've already seen them from ten thousand feet.

Writing any project over a few hundred lines of code means creating a vocabulary. Usually this is expressed through function and variable names. (Think of "interrupts," "pages," and "faults" in a kernel, for example.) Sometimes it takes the form of a larger metaphor. (Python's Twisted framework uses a sandwich metaphor.)

Your project needs an overview. This should describe your goals and offer enough of a roadmap so people know where development is headed. You may not be able to predict volunteer contributions (or even if you'll receive any), but you should have a rough idea of the features you've implemented, the features you want to implement, and the problems you've encountered along the way.

If you're writing automated tests as you go along (and you certainly should be), these tests can help make sense of the code. Customer tests, named appropriately, can provide conceptual links from working code to required features.

Keep your overview and your tests up-to-date, though. Outdated documentation can be better than no documentation, but misleading documentation is, at best, annoying and unpleasant.

This isn't a myth because reading the code and fixing bugs won't help people understand the project. It's a myth because the code is only an artifact of the project.

Packaging Doesn't Matter

Myth: Installation and configuration aren't as important as making the source available.

Reality: If it takes too much work just to get the software working, many people will silently quit.

Potential users become actual users through several steps. They hear about the project. Next, they find and download the software. Then they must brave the installation process. The easier it is to install your software, the sooner people can play with it. Conversely, the more difficult the installation, the more people will give up, often without giving you any feedback.

Granted, you may find people who struggle through the installation, report bugs, and even send in patches, but they're relatively few in number. (I once wrote an installation guide for a piece of open source software and then took a job working on the code several months later. Sometimes it's worth persisting.)

Difficulties often arise in two areas: managing dependencies and creating the initial configuration. For a good example of installation and customization, see Brian Ingerson's Kwiki. The amount of time he put into making installation easier has paid off by saving many users hours of customization. Those savings, in turn, have increased the number of people willing to continue using his code. It's so easy to use, why not set up a Kwiki for every good idea that comes along?

It's OK to expect that mostly programmers will use development tools and libraries. It's also OK to assume that people should skim the details in the README and INSTALL files before trying to build the code. If you can't easily build, test, and install your code on another machine, though, you have no business releasing it to other people.

It's not always possible, nor advisable, to avoid dependencies. Complex web applications likely require a database, a web server with special configurations (mod_perl, mod_php, mod_python, or a Java stack). Meta-distributions can help. Apache Toolbox can take out much of the pain of Apache configuration. Perl bundles can make it easier to install several CPAN modules. OS packages (RPMs, debs, ebuilds, ports, and packages) can help.

It takes time to make these bundles and you might not have the hardware, software, or time to write and test them on all possible combinations. That's understandable; source code is the real compatibility layer on the free Unix platforms anyway.

At a minimum, however, you should make your dependencies clear. Your configuration process should detect as many dependencies as possible without user input. It's OK to require more customization for more advanced features. However, users should be able to build and to install your software without having to dig through a manual or suck down the latest and greatest code from CVS for a dozen other projects.

This isn't a myth because people really believe software should be difficult to install. It's a myth because many projects don't make it easier to install.

It's Better to Start from Scratch

Myth: Bad or unappealing code or projects should be thrown away completely.

Reality: Solving the same simple problems again and again wastes time that could be applied to solving new, larger problems.

Writing maintainable code is important. Perhaps it's the most important practice of software development. It's secondary, though, to solving a problem. While you should strive for clean, well-tested, and well-designed code that's reasonably easy to modify as you add features, it's even more important that your code actually works.

Throwing away working code is usually a mistake. This applies to functions and libraries as well as entire programs. Sometimes it seems as if most of the effort in writing open source software goes to creating simple text editors, weblogs, and IRC clients that will never attract more than a handful of users.

Many codebases are hard to read. It's hard to justify throwing away the things the code does well, though. Software isn't physical — it's relatively easy to change, even at the design level. It's not a building, where deciding to build four stories instead of two means digging up the entire foundation and starting over. Chances are, you've already solved several problems that you'd need to rediscover, reconsider, re-code, and re-debug if you threw everything away.

Every new line of code you write has potential bugs. You will spend time debugging them. Though discipline (such as test-driven development, continual code review, and working in small steps) mitigates the effects, they don't compare in effectiveness to working on already-debugged, already-tested, and already-reviewed code.

Too much effort is spent rewriting the simple things and not enough effort is spent reusing existing code. That doesn't mean you have to put up with bad (or simply different) ideas in the existing code. Clean them up as you go along. It's usually faster to refine code into something great than to wait for it to spring fully formed and perfect from your mind.

This isn't a myth because rewriting bad code is wrong. It's a myth because it can be much easier to reuse and to refactor code than to replace it wholesale.

Programs Suck; Frameworks Rule!

Myth: It's better to provide a framework for lots of people to solve lots of problems than to solve only one problem well.

Reality: It's really hard to write a good framework unless you're already using it to solve at least one real problem.

Which is better, writing a library for one specific project or writing a library that lots of projects can use?

Software developers have long pursued abstraction and reuse. These twin goals have driven the adoption of structured programming, object orientation, and modern aspects and traits, though not exactly to roaring successes. Whether proprietary code, patent encumbrances, or not-invented-here stubbornness, there may be more people producing "reusable" code than actually reusing code.

Part of the problem is that it's more glamorous (in the delusive sense of the word) to solve a huge problem. Compare "Wouldn't it be nice if people had a fast, cross-platform engine that could handle any kind of 3D game, from shooter to multiplayer RPG to adventure?" to "Wouldn't it be nice to have a simple but fun open source shooter?"

Big ambitions, while laudable, have at least two drawbacks. First, big goals make for big projects — projects that need more resources than you may have. Can you draw in enough people to spend dozens of man-years on a project, especially as that project only makes it possible to spend more time making the actual game? Can you keep the whole project in your head?

Second, it's exceedingly difficult to know what is useful and good in a framework unless you're actually using it. Is one particular function call awkward? Does it take more setup work than you need? Have you optimized for the wrong ideas?

Curiously, some of the most portable and flexible open source projects today started out deliberately small. The Linux kernel originally ran only on x86 processors. It's now impressively portable, from embedded processors to mainframes and super-computer clusters. The architecture-dependent portions of the code tend to be small. Code reuse in the kernel grew out of refining the design over time.

Solve your real problem first. Generalize after you have working code. Repeat. This kind of reuse is opportunistic.

This isn't a myth because frameworks are bad. This is a myth because it's amazingly difficult to know what every project of a type will need until you have at least one working project of that type.

I'll Do it Right *This* Time

Myth: Even though your previous code was buggy, undocumented, hard to maintain, or slow, your next attempt will be perfect.

Reality: If you weren't disciplined then, why would you be disciplined now?

Widespread Internet connectivity and adoption of Free and Open programming languages and tools make it easy to distribute code. On one hand, this lowers the barriers for people to contribute to open source software. On the other hand, the ease of distribution makes finding errors less crucial. This article has been copyedited, but not to the same degree as a print book; it's very easy to make corrections on the Web.

It's very easy to put out code that works, though it's buggy, undocumented, slow, or hard to maintain. Of course, imperfect code that solves a problem is much better than perfect code that doesn't exist. It's OK (and even commendable) to release code with limitations, as long as you're honest about its limitations — though you should remove the ones that don't make sense.

The problem is putting out bad code knowingly, expecting that you'll fix it later. You probably won't. Don't keep bad code around. Fix it or throw it away.

This may seem to contradict the idea of not rewriting code from scratch. In conjunction, though, both ideas summarize to the rule of "Know what's worth keeping." It's OK to write quick and dirty code to figure out a problem. Just don't distribute it. Clean it up first.

Develop good coding habits. Training yourself to write clean, sensible, and well-tested code takes time. Practice on all code you write. Getting out of the habit is, unfortunately, very easy.

If you find yourself needing to rewrite code before you publish it, take notes on what you improve. If a maintainer rejects a patch over cleanliness issues, ask the project for suggestions to improve your next attempt. (If you're the maintainer, set some guidelines and spend some time coaching people along as an investment. If it doesn't immediately pay off to your project, it may help along other projects.) The opportunity for code review is a prime benefit of participating in open source development. Take advantage of it.

This isn't a myth because it's impossible to improve your coding habits. This is a myth because too few developers actually have concrete, sensible plans to improve.

Warnings Are OK

Myth: Warnings are just warnings. They're not errors and no one really cares about them.

Reality: Warnings can hide real problems, especially if you get used to them.

It's difficult to design a truly generic language, compiler, or library partially because it's impossible to imagine all of its potential uses. The same rule applies to reporting warnings. While you can detect some dangerous or nonsensical conditions, it's possible that users who really know what they are doing should be able to bypass those warnings. In effect, it's sometimes very useful to be able to say, "I realize this is a nasty hack, but I'm willing to put up with the consequences in this one situation."

Other times, what you consider a warnable or exceptional condition may not be worth mentioning in another context. Of course, the developer using the tool could just ignore the warnings, especially if they're nonfatal and are easily shunted off elsewhere (even if it is /dev/null). This is a problem.

When the "low oil pressure" or "low battery" light comes on in a car, the proper response is to make sure that everything is running well. It's possible that the light or a sensor is malfunctioning, but ignoring the real problem — whether bad light or oil leak — may exacerbate further problems. If you assume that the light has malfunctioned but never replace it, how will you know if you're really out of oil?

Similarly, an error log filled with trivial, fixable warnings may hide serious problems. Any well-designed tool generates warnings for a good reason: you're doing something suspicious.

When possible, purge all warnings from your code. If you expect a warning to occur — and if you have a good reason for it — disable it in the narrowest possible scope. If it's generated by something the user does and if the user is privy to the warning, make it clear how to avoid that condition.

Running a program that spews crazy font configuration questions and null widget access messages to the console is noisy and incredibly useless to anyone who'd rather run your software than fix your mess. Besides that, it's much easier to dig through error logs that only track real bugs and failures. Anything that makes it easier to find and fix bugs is nice.

This isn't a myth because people really ignore warnings. It's a myth because too few people take the effort to clean them up.

End Users Love Tracking CVS

Myth: Users don't mind upgrading to the latest version from CVS for a bugfix or a long-awaited feature.

Reality: If it's difficult for you to provide important bugfixes for previous releases, your CVS tree probably isn't very stable.

It's tricky to stay abreast of a project's latest development sources. Not only do you have to keep track of the latest check-ins, you may have to guess when things are likely to spend more time working than crashing and build binaries right then. You can waste a lot of time watching compiles fail. That's not much fun for a developer. It's even less exciting for someone who just wants to use the software.

Building software from CVS also likely means bypassing your distribution's usual package manager. That can get tangled very quickly. Try to keep required libraries up-to-date for only two applications you compiled on your own for awhile. You'll gain a new appreciation for people who make and test packages.

There are two main solutions to this trouble.

First, keep your main development sources stable and releasable. It should be possible for a dedicated user (or, at least, a package maintainer for a distribution) to check out the current development sources and build a working program with reasonable effort. This is also in your best interests as a developer: the easier the build and the fewer compile, build, and installation errors you allow to persist, the easier it is for existing developers to continue their work and for new developers to start their work.

Second, release your code regularly. Backport fixes if you have to fix really important bugs between releases; that's why tags and branches exist in CVS. This is much easier if you keep your code stable and releasable. Though there's no guarantee users will update every release, working on a couple of features per release tends to be easier anyway.

This isn't a myth because developers believe that development moves too fast for snapshots. It's a myth because developers aren't putting out smaller, more stable, more frequent releases.

Common Sense Conclusions

Again, these aren't myths because they're never true. There are good reasons to have a feature freeze. There are good reasons to invite new developers to get to know a project by looking through small or simple bug reports. Sometimes, it does make sense to write a framework. They're just not always true.

It's always worth examining why you do what you do. What prevents you from releasing a new stable version every month or two? Can you solve that problem? Solve it. Would building up a good test suite help you cut your bug rates? Build it. Can you refactor a scary piece of code into something saner in a series of small steps? Refactor it.

Making your source code available to the world doesn't make all of the problems of software development go away. You still need discipline, intelligence, and sometimes, creative solutions to weird problems. Fortunately, open source developers have more options. Not only can we work with smart people from all over the world, we have the opportunity to watch other projects solve problems well (and, occasionally, poorly).

Learn from their examples, not just their code.

chromatic is the technical editor of the O'Reilly Network and the co-author of Perl Testing: A Developer's Notebook.

General Programming Concepts: Writing and Debugging Programs ... -- good book with large debugging section. AIX oriented but can be used for any Unix.

list.unix-haters

From: FG - Usenet Repost 1999-01-28 (blackhart@mindspring.com)
Subject: Programming errors
style="color: #000; font-family: arial,sans-serif">View: Original Format Newsgroups: list.unix-haters, misc.test
Date: 1999/01/31
Date: Thu, 28 Jan 1999 18:35:19 -0800
From: FG
Subject: Programming errors

I am reminded again of how shaky the software world is.

Someone has been making a major effort to clean up the code in the
FreeBSD tree.  In two days he has reported three instances of the
following common C error:

     if (x = y)

instead of

     if (x == y)

This is in running code, in an OS whose developers consider stability
to be one of its major advantages over other offerings.

He also reported some missing breaks in a switch statement---many of
us remember what THAT error did not too long ago.  [RISKS-9.61 to 71.  
Trojan horse switches in midstream?  PGN]

freshmeat.net Editorials - Providing Good Feedback for Bug Reporters

Providing Good Feedback for Bug Reporters
 
by Tracey Clark, in Editorials - Saturday, January 24th 2004 00:00 PST

A comment on a bug I submitted recently spurred me to provide some feedback from an application user's perspective on bug reports. There are ways of responding to a bug report that encourage the types of responses that are helpful to developers, and there are ways of responding that only produce anger and frustration, without getting anything fixed. My hope is to encourage good communication between bug reporters and developers to enable better, quicker bugfixes.


Copyright notice: All reader-contributed material on freshmeat.net is the property and responsibility of its author; for reprint rights, please contact the author directly.


My Background

I have been reporting bugs for a few years, on various pieces of software. I've had both positive and negative experiences with the responses I've received from developers. I come from a professional background of using computers, supporting computers, change control, and basic programming, so I've seen problem reporting from a few angles.

To begin, I'll outline responses I have received or seen that were unhelpful. Following that will be responses I have seen that were helpful. Finally, I'll outline some general guidelines which I feel promote good communication between developers and reporters.

Unhelpful Responses
It's not our product, it's some other software causing the problem (with no debugging or troubleshooting).

Trying to shift blame with no investigation does nobody and nothing any good. It only makes the developers look like they don't want to take responsibility for a possible bug or don't want to do any troubleshooting. Some reported bugs do wind up really being a problem with other software. If properly investigated, you've got the data to back the position that other software caused the bug. Posting the exact reason it's a problem with other software to the report is great feedback for the bug reporters, who can then report it to the correct place. They also know you cared enough about their bug to help them get it to the right place, making them more likely to report future bugs.

I can't reproduce it/works for me (with no other qualifications).

That doesn't help anyone, and it sounds like another "I don't wanna do work" response. The fact that person B cannot reproduce a bug does not negate the fact that person A can always reproduce it. Helpful information to add to a comment like this would be: Did you use the same version on the same OS, following exactly the same steps (using menus as opposed to an icon), etc.? The programmers may have done things exactly the same way, but maybe they didn't. The bug reporters don't know unless they are told. Also helpful are comments about what you're trying to do to reproduce the problem, such as "I'm continuing to try this on another machine" or "I'm working with a few people to see if we can reproduce this bug". One failed attempt to reproduce the bug with no further work isn't working the bug, it's akin to lip service. Tell the reporters instead what other troubleshooting information they need to give you to track the bug down.

The two responses above are unfortunately so common in the IT world, and so well-known by users (who aren't fooled), that a company made an IT-style Magic 8-Ball. The answers include:

&!*#*&... We've said a million times not to report x because blah blah...

(And other not-so-subtle "You're stupid for having contacted us" or abusive types of responses).

A polite pointer to the FAQ or appropriate documentation is more appropriate. Telling people they shouldn't have written about one bug will discourage them from writing about any bug.

No response (when assigned).

Hello? Is anyone watching this thing? Even "Bug in queue, will get to this" would be helpful. (I like the note in Mozilla's Bugzilla which says "This means the bug is awaiting triage..."). Getting no response may lead reporters to feel that their time is being wasted.

Helpful Responses

It's always appropriate to thank someone for taking the time to report a perceived problem, even if it turns out not to be a problem with the software they thought was the problem. Even a badly-written bug report can be helpful with a bit of work (in most cases). The reporter can always be given a link to a "How to report bugs well" FAQ or your project's bug guidelines. Politeness is good. Happy bug reporters help us troubleshoot our software. They are a valuable resource to the Open Source community. Pissing them off means that you don't get as much testing from them. A simple "thank you" and a kind attitude go a long way to make someone feel respected and happy.

I can't reproduce the problem, but here's something you can do to provide me with more information....

Letting people know what else they can do to clarify a bug or provide more troubleshooting information lets them know that their response is not wasted, that the developer cares enough about the problem to want more information and actually wants to get the bug fixed.

Bug confirmed, working on this...

You may not yet know the cause of the problem, and don't have time to write much. A simple note to say you've duplicated the issue and you're looking into it lets the users know their bug report has been received and something is being done. This improves their confidence that their reports mean something.

Suggestions

Better communication and more questions rather than snarky answers make for happier bug reporters and better bug troubleshooting. Here are a few other, general suggestions that go toward improving communication:

Have a written, easily findable bug submission procedure for your project.

People who report bugs may not know what information is helpful for the developers. Your bug submission guidelines will tell them what that information is. You can't guarantee that everyone will read it or follow it. You can guarantee that you will get less of what you need in terms of helpful bug reports if you don't have one.

Try to speak in terms the bug reporter can understand.

Perhaps the meaning of "just run lsmod" is obvious to you, but it may not be obvious to the bug reporters. This doesn't make the reporters bad, nor does it justify getting angry at them. No one is born knowing all computer commands. Not everyone has the same level of expertise in the same areas as a developer. Communicating with the reporters in ways they understand means you will get more helpful answers from them. Sometimes, they can run a command they didn't know before if only you tell them how to do it or point them at the appropriate FAQ.

Don't respond in anger, respond when you are calm.

People are responding to your request to submit bug reports, and they deserve to be treated with a basic amount of respect. Responding in anger will increase the likelihood that you will say something inappropriate or something that you may regret. Wait until you have a cool head to respond to comments.

Respond with common courtesy, don't put people down.

Again, if you're asking people to submit bugs, putting them down when they do is counter-productive. It will only make you and your project look bad. Treating people respectfully increases their willingness to help you get your bugs solved and your programs running more stably. This shouldn't have to be said, but there it is.

There are many things we can do to improve communication in bug reporting. This article provides a few which can be used in most situations. By following practices of courtesy and good feedback, we can improve the rate at which bugs get fixed and encourage the volunteers waiting to help us in that process. The Open Source community as a whole can benefit.


This article is licensed under the Creative Commons Attribution-ShareAlike License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/1.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.


Author's bio:

Tracey Clark can be reached at grrliegeek@elenari.net.

Troubleshooting Tips

The purpose of this page is to give you some ideas to cope with a variety of problems that will occur when using Unix. To use Unix effectively, you need to not just know the syntax and features of the operating system, but you must develop an attitude of coping with problems and understanding a bit of the worldview that might help you use Unix better. Some of this advice may seem odd or humorous, but it all has the point of conveying some kinds of coping mechanisms that go beyond just knowing the syntax of the commands.

  1. Remain calm.
    Panic will cloud your ability to think through the problem and to come up with solutions. Slow down and calm down. Many times I see that problems arise when students try to type too quickly. Become familiar with your keyboard and how it works; type slowly if you have to. Remember that in Unix, you must type things exactly.
  2. Know when to quit.
    As you type a Unix command at the shell prompt, you will type the wrong symbol. You might try the backspace or delete keys. These may or may not work--the way the backspace and delete keys are mapped to their functions are not always done correctly. This is particularly true when using telnet. If you get some funny characters or strange characters, cancel the command line. Do this by holding down the control key (usually at the lower left-hand corner of a keyboard) and the C key at the same time. That cancels the command. If you don't do this, you may create some strange file or have some strange effect. (Strange characters = possible strange effects.) Be particularly vigilant when you are creating a file name.
  3. Seek clarity.
    If your terminal acts "funny" or your vi editor session is "strange," try this:
    $ set term=vt100
    $ clear
    

    The first command tells your telnet client that it is an old standard type of terminal (vt100); this often clears up strange control characters or if the computer output is not scrolling up on the screen. Then used with the clear command, you get added refreshment--this clears the screen of previous commands and output. This can then help you focus on a new task or way of approaching a problem.

  4. Don't flirt with deadlines.
    In the real world, real deadlines mean either money lost or money gained. In the real world, if you miss a deadline, you may lose your company money and lose your job. If you meet a deadline, you may help your company succeed. If you start your work close to the deadline, you may run into trouble that you might not be able to resolve in time.
     
  5. Understand that Unix was written for humans and by humans and thus is a language, full of ambiguity, inconsistencies, history, and culture.
    Computers don't need an operating system--you do. Electronic computers just care about high and low voltages. Operating systems like Unix were written by humans for humans to make use of the resources of the computer. Humans are full of all kinds of interesting ideas and these are reflected in the Unix operating system and its flavors. Not all the sequences of commands and options are entirely consistent. There are inconsistencies in syntax from command to command. There are cultural artifacts throughout the operating system that came out of the "geek" culture that gave rise to it-- who else would come up with the "finger" command?
     
  6. Understand that Unix and computers are a mystery to be lived, not a problem to be solved.
    There will be errors, mistakes, funny things happen. You could spend the rest of your life analyzing exactly what gave rise to a particular error--or you could:
    • Take a deep breath and try it again
    • Log off and log back in
    • Try a different computer
    • Get a night's sleep and try tomorrow (but not if your deadline is tonight)

    The combination of hardware, networks, operating systems, and software gives rise to a high level of complexity. When problems arise, I have found it is best to try some troubleshooting techniques, then try something else, rather than trying to figure out exactly what went wrong (however, I do read error messages and look for any clues on the screen). Due to the nature of Unix systems, by the time you have found out what went wrong, the system (its hardware or software) will have been changed or "upgraded" (introducing new problems). This is particularly true, I have found, in academic computing systems.
     

  7. Speak in a soothing, kind voice to the computer.
    This is more for you than for the computer. If you get frustrated and type haphazardly at the keyboard, you are not going to get work done. If you don't read the screen and any error messages, you are going to keep repeating the same mistakes over and over. Thanking the computer for what it does helps you focus on the give-and-take interaction you have with the computer. The soothing voice calms you down also.
     
  8. Realize that there are many paths to getting things done.
    There are usually many ways to accomplish a task. Don't get too dogmatic about finding the one and only one way to do it, nor get too over-involved in figuring out every way to do something. Most Unix users develop a particular set of habits for using the commands that match their way of thinking. Don't be too concerned if you see others use a different style of Unix interaction--however, you might learn some new things from them. Don't be too insistent on continually pointing out, "you could also do that by..." (particularly if you