Debuggers

J

jacob navia

1: Consider this code:

void dowork(char *buffer,size_t siz)
{
for (int i=0; i<siz;i++) {
buffer=0;
}
}

Not any amount of code review will catch the case where
siz is wrong because the calling procedure had a memory
overwrite. And standard C doesn't have ANY way of telling
if a pointer is OK or not.

2: Code review is an EXCELLENT technique for getting the
bugs out BEFORE they enter the code base. This, combined
with reflexion about the code when writing it, and when
testing it, is a VERY GOOD technique for *avoiding*
long debugging sessions.

3: Debugging is a different activity than code review/code reading
since it tries to catch the bugs when they ALREADY ARE INSIDE
the code base.

And here a debugger is essential.

----------------------------------------------------------------

Many people here argue that they have ported a lot of
software without debuggers, just with code review, etc.

This CAN be done, and it is STILL being done, but most of that
software is completely buggy but neither the customers nor the
developers *know* about it!


I remember when ANSI introduced prototypes into the C89/90 standard,
and HOW MANY BUGS WE CATCHED in the development team I worked at
that time. We just never knew about those bugs!!!
 
R

Richard

Nick Keighley said:
he's a computer programmer posting to a technical forum.

Can we assume from your lower case "h" in "he's" to mean that that was
not the start of your sentence and you accidentally dropped some other
pedantic rants?

For goodness sake grow up a little and show some common sense.
Perhaps he should learn to be more precise.

It was perfectly clear what he meant.

And I agree with him. I would never DREAM of trying to "debug" someone
else's code of 2000 or more lines by reading a printout or on screen
with no interaction unless the bug was very, very localised already - in
which case its pretty much already debugged.

And not only would I locate the bug in a debugger, I would then test it
in the debugger altering various values at run time to ensure my code
was robust.

Sod the political correctness - I seriously question the honesty and
motivations of anyone here who, as professional programmers, claim to
debug such code by reading such than just trapping the bug in a debugger
and examining the call stack to determine where the error lies.
 
R

Richard

jacob navia said:
1: Consider this code:

void dowork(char *buffer,size_t siz)
{
for (int i=0; i<siz;i++) {
buffer=0;
}
}

Not any amount of code review will catch the case where
siz is wrong because the calling procedure had a memory
overwrite. And standard C doesn't have ANY way of telling
if a pointer is OK or not.

2: Code review is an EXCELLENT technique for getting the
bugs out BEFORE they enter the code base. This, combined
with reflexion about the code when writing it, and when
testing it, is a VERY GOOD technique for *avoiding*
long debugging sessions.

3: Debugging is a different activity than code review/code reading
since it tries to catch the bugs when they ALREADY ARE INSIDE
the code base.

And here a debugger is essential.

----------------------------------------------------------------

Many people here argue that they have ported a lot of
software without debuggers, just with code review, etc.

This CAN be done, and it is STILL being done, but most of that
software is completely buggy but neither the customers nor the
developers *know* about it!


I remember when ANSI introduced prototypes into the C89/90 standard,
and HOW MANY BUGS WE CATCHED in the development team I worked at
that time. We just never knew about those bugs!!!


Jacob, no one here with half a brain and any real industry experience
would disagree with you in the great majority of cases. Ignore the
preening from the usual suspects - they're only out to show boat and
suggest that they "exceed mediocrity" or whatever that bullshit
Heathfield was waffling on about.
 
J

jacob navia

jacob said:
1: Consider this code:

void dowork(char *buffer,size_t siz)
{
for (int i=0; i<siz;i++) {
buffer=0;
}
}



And yes, code review can make bugs surface!

REPLACE

int i,
by

size_t i


(!!!!!!!!!!!!!!)
 
C

Chris Dollin

jacob said:
1: Consider this code:

void dowork(char *buffer,size_t siz)
{
for (int i=0; i<siz;i++) {
buffer=0;
}
}

Not any amount of code review will catch the case where
siz is wrong because the calling procedure had a memory
overwrite.


Not even code review that reviews the calling procedures?
 
C

Chris Dollin

Richard said:
And I agree with him. I would never DREAM of trying to "debug" someone
else's code of 2000 or more lines by reading a printout or on screen
with no interaction

/I'm/ certainly not claiming "no interaction" -- although I would
certainly start by reading the code to get some idea of its shape
(depends how much over 2000 lines we're talking about, of course).
And not only would I locate the bug in a debugger, I would then test it
in the debugger altering various values at run time to ensure my code
was robust.

Nowadays I'd write test cases for that. Tweaking in the debugger
doesn't leave a reusable trail. (I could be wrong about that -- does
it?)
Sod the political correctness - I seriously question the honesty and
motivations of anyone here who, as professional programmers, claim to
debug such code by reading such than just trapping the bug in a debugger
and examining the call stack to determine where the error lies.

/I/ have /repeatedly/ said that I /have/ used a debugger to provide me
with a stacktrace, ie, to find out the point of failure and the call
context.

Of course, you're assuming that it's feasible to use a debugger on
the live code. That seems just as much a variable of the situation as
all the other conditions you impose.
 
R

Richard

Chris Dollin said:
jacob said:
1: Consider this code:

void dowork(char *buffer,size_t siz)
{
for (int i=0; i<siz;i++) {
buffer=0;
}
}

Not any amount of code review will catch the case where
siz is wrong because the calling procedure had a memory
overwrite.


Not even code review that reviews the calling procedures?


Not if the code is out there - probably not. The more you stare at
something the more the little things can be missed.

We are talking existing code. Not module for module acceptance by peer
review at system implementation time. Even then bugs get in and must be
found at a later date. You propose peer review of every single function
in a 30,000 line code base in order to find out why function printMe()
crashes 4 hours into a run by a program that was released 12 years ago?
 
R

Richard

Chris Dollin said:
/I'm/ certainly not claiming "no interaction" -- although I would
certainly start by reading the code to get some idea of its shape
(depends how much over 2000 lines we're talking about, of course).

So would I. Generally by setting a breakpoint on main() and running it
in a debugger :-; Of *course* a printout has its place as is reading the
code in a good editor with tags/cscope. I mix the two by running code
in gdb in emacs with tags/cscope.
Nowadays I'd write test cases for that. Tweaking in the debugger
doesn't leave a reusable trail. (I could be wrong about that -- does
it?)

Why would I? Its for me to be sure before I check in and document the
fix. Call it "feel good" if you like. eg set "v" to an illegal operation
before calling printMe(v). Does printme() return the correct error
code. It takes 2 seconds to check. No mistake reading the code and
mistaking printme for printMe for example.
/I/ have /repeatedly/ said that I /have/ used a debugger to provide me
with a stacktrace, ie, to find out the point of failure and the call
context.

I am not questioning you personally.
Of course, you're assuming that it's feasible to use a debugger on
the live code. That seems just as much a variable of the situation as
all the other conditions you impose.

There are some cases where you can not. No question. I would like to
think we are discussing the more general case where a debugger can
indeed run. Or the discussion is a waste of time.
 
C

Chris Dollin

Richard said:
We are talking existing code. Not module for module acceptance by peer
review at system implementation time. Even then bugs get in and must be
found at a later date. You propose peer review of every single function
in a 30,000 line code base in order to find out why function printMe()
crashes 4 hours into a run by a program that was released 12 years ago?

If you put words into my mouth /one more time/ in this conversation, I'll
know to give it up.

You're coming over to me as scrambling to justify your claims of the
necessity of the use of debuggers by making every debugging situation
the most complicated you can: "every single function", 30000 lines,
4 hours, and 12 years are all /your/ inventions. I presume you're not
actually trying to do this.

I've developed code. I've hardly used a debugger. I haven't felt the
need to use one more than I did, and as far as I can tell I did OK.
I'm not claiming that using a debugger is wrong, and I don't doubt
that there are circumstances -- /some/ circumstances, whose frequency
is currently unspecified -- where vigorous use of a debugger is
helpful or indeed necessary. (I /do/ happen to believe that every
occasion it /is/ needed is an opportunity to consider how that
need might be eliminated.)

I note also that I believe that Jacob and yourself have distinct
views, and that a response of mine to what Jacob says is not
necessarily a response to what you say and vice-versa; of course
there's bound to be some common aspects to my replies since, at
present, I am possessed of but a single personality. Don't confuse
them.
 
C

Chris Dollin

Richard said:
Why would I? Its for me to be sure before I check in and document the
fix. Call it "feel good" if you like. eg set "v" to an illegal operation
before calling printMe(v). Does printme() return the correct error
code. It takes 2 seconds to check. No mistake reading the code and
mistaking printme for printMe for example.

I would have said that was a prime candidate for a unit test case.
(It's certainly the sort of thing I routinely put in the Java code
I've been writing.)
 
S

santosh

Chris Dollin wrote:

I'm not claiming that using a debugger is wrong, and I don't doubt
that there are circumstances -- /some/ circumstances, whose frequency
is currently unspecified -- where vigorous use of a debugger is
helpful or indeed necessary. (I /do/ happen to believe that every
occasion it /is/ needed is an opportunity to consider how that
need might be eliminated.)

That's interesting. Can you explain that last parenthesised sentence?
Are you talking about eliminating bugs or eliminating the need of a
debugger as a principle?
 
R

Richard

Chris Dollin said:
I would have said that was a prime candidate for a unit test case.
(It's certainly the sort of thing I routinely put in the Java code
I've been writing.)

I'm not disagreeing. I am talking about doing things there and then
while in the debugger "to be sure". It's something I have routinely done
that pays dividends in the long run.

Another thing about using a debugger is that its more "interactive". You
really do study the code more when you manually step line by line and
watch the locals pane change.
 
R

Richard

Chris Dollin said:
If you put words into my mouth /one more time/ in this conversation, I'll
know to give it up.

You mentioned peer reviews.
You're coming over to me as scrambling to justify your claims of the
necessity of the use of debuggers by making every debugging situation
the most complicated you can: "every single function", 30000 lines,

When looking for a bug in a foreign system then you would have to find
which function to "peer review" and then its calling function and then
... etc.
4 hours, and 12 years are all /your/ inventions. I presume you're not
actually trying to do this.

No. I never mentioned peer reviews. You did here:

,----
| > jacob navia wrote:
| >
| >> 1: Consider this code:
| >>
| >> void dowork(char *buffer,size_t siz)
| >> {
| >> for (int i=0; i<siz;i++) {
| >> buffer=0;
| >> }
| >> }
| >>
| >> Not any amount of code review will catch the case where
| >> siz is wrong because the calling procedure had a memory
| >> overwrite.
| >
| > Not even code review that reviews the calling procedures?
`----

Peer review is not done to debug released code as far as my experience
goes.

FWIW, I don't think we are poles apart here. You use a debugger but not
as much as I would.

I would still recommend anyone to pick up a debugger and just check the
features just in case it can do more than one first
suspected. Invariably they can. They do a lot more for a good programmer
than just provide a stack trace at a crash point.

*important*

Once thing that some people seem to ignore is that MANY (or most) bugs
do not actually crash the program. The program just gives erroneous
results. There is no stack trace until you use a HW break point to catch
the offending run time state.
 
R

Richard

santosh said:
Chris Dollin wrote:



That's interesting. Can you explain that last parenthesised sentence?
Are you talking about eliminating bugs or eliminating the need of a
debugger as a principle?

Eliminating bugs one would hope as I see no positive motive for wanting
to eliminate such a useful utility as a debugger. Especially since that
debugger just provided the situation to consider eliminating something
.......
 
E

Eric Sosman

jacob said:
1: Consider this code:

void dowork(char *buffer,size_t siz)
{
for (int i=0; i<siz;i++) {
buffer=0;
}
}

Not any amount of code review will catch the case where
siz is wrong because the calling procedure had a memory
overwrite.


And no amount of interactive debugging will reveal
the other lurking error in this code until *after* it
has risen up and bit your bum. Reading, however, reveals
the potential infinite loop right away. Reading also
reveals that this code is a clumsy attempt to duplicate
a Standard library function and thus should never have
been written in the first place, which is another thing
no debugger would have told you.
And standard C doesn't have ANY way of telling
if a pointer is OK or not.

True, but debuggers are only a little bit better. They
can (usually) tell you whether a pointer aims "at something"
or "at nothing," but that's a far cry from telling you
whether the pointer "is OK."

char buffer[SIZE];
char *p = buffer + SIZE;

It's quite likely that p points "at something," but that
doesn't mean it would be a good idea to dereference it.

double p[100];
double *q = malloc(100 * sizeof *q);

Unless q is NULL, both p and q point "at something," but
that doesn't mean it would be a good idea to subtract them.
2: Code review is an EXCELLENT technique for getting the
bugs out BEFORE they enter the code base. This, combined
with reflexion about the code when writing it, and when
testing it, is a VERY GOOD technique for *avoiding*
long debugging sessions.

3: Debugging is a different activity than code review/code reading
since it tries to catch the bugs when they ALREADY ARE INSIDE
the code base.

And here a debugger is essential.

No, a debugger is just another tool. And code reading
need not be limited to just one stage in the code's lifetime.

Here's a real-life example (not a made-up strawman like
the dowork() function above), taken from my own code. It's
a bug that I wrote myself, and that I discovered purely by
re-reading the code. The micro-task was a simple one: I had
a pointer p to the final node of a linked list, and a pointer
q to a new node. I wanted to add the new node to the end of
the list and update p so it would still be pointing at the
list's final node, so I wrote this howler:

p = p->next = q;

I've never encountered a debugger that could have diagnosed
this problem until and unless the code found its way onto a
system where it happened to make trouble. Nor can I imagine
how printf debugging or tracing or watchpoints or any such
run-it-and-see-what-happens machinery could have caught the
problem prior to getting it on to such a system. But my eye
spotted the problem, and my hands fixed it (after giving myself
a dope slap, of course). The bug was fixed *before* it made
trouble; a debugger would have been no help at all until
*after* trouble occurred.
Many people here argue that they have ported a lot of
software without debuggers, just with code review, etc.

This CAN be done, and it is STILL being done, but most of that
software is completely buggy but neither the customers nor the
developers *know* about it!

Everyone agrees that software has bugs; this is not news.
But you offer no evidence to support your assertion that code-
reviewed software is "completely buggy" because of code review,
nor your implication that firing up a debugger automatically
leads to bug removal.
I remember when ANSI introduced prototypes into the C89/90 standard,
and HOW MANY BUGS WE CATCHED in the development team I worked at
that time. We just never knew about those bugs!!!

What has that to do with debuggers? Nothing that I can see.
 
M

Morris Dovey

jacob said:
jacob said:
1: Consider this code:

void dowork(char *buffer,size_t siz)
{
for (int i=0; i<siz;i++) {
buffer=0;
}
}


And yes, code review can make bugs surface!

REPLACE

int i,
by

size_t i

(!!!!!!!!!!!!!!)


ROFL (Good catch!)
 
G

George Peter Staplin

jacob said:
1: Consider this code:

void dowork(char *buffer,size_t siz)
{
for (int i=0; i<siz;i++) {
buffer=0;
}
}

Not any amount of code review will catch the case where
siz is wrong because the calling procedure had a memory
overwrite. And standard C doesn't have ANY way of telling
if a pointer is OK or not.

2: Code review is an EXCELLENT technique for getting the
bugs out BEFORE they enter the code base. This, combined
with reflexion about the code when writing it, and when
testing it, is a VERY GOOD technique for *avoiding*
long debugging sessions.

3: Debugging is a different activity than code review/code reading
since it tries to catch the bugs when they ALREADY ARE INSIDE
the code base.

And here a debugger is essential.


There's also an alternative, that I've used when the debugger seems
to be useless because some state gets overwritten. I often proactively
use it as well.

void dowork(char *buffer, char *bufferLimit, size_t siz) {
int i;
for (i = 0; i < siz; ++i) {
assert((buffer + i) < bufferLimit);
buffer = 0;
}
}

You could also make it more abstract and rather than passing around 2
pointers, pass around a struct.

struct bounded_buffer {
char *buffer;
char *limit;
};

void dowork(struct bounded_buffer *buffer, size_t siz);


I've used this assert-based method repeatedly in graphics code, and it
has been quite useful. Sometimes validation of the pointers will
require 2 assertions like:

assert(ptr >= baseAllocation);
assert(ptr < baseLimit);

This will also catch some bugs that you simply may not run into very
often, that don't result in faults generally.

If you want performance you can still use -DNDEBUG to disable
assertions.
----------------------------------------------------------------

Many people here argue that they have ported a lot of
software without debuggers, just with code review, etc.

This CAN be done, and it is STILL being done, but most of that
software is completely buggy but neither the customers nor the
developers *know* about it!

That's probably true.
I remember when ANSI introduced prototypes into the C89/90 standard,
and HOW MANY BUGS WE CATCHED in the development team I worked at
that time. We just never knew about those bugs!!!

Interesting.


George
 
R

Richard Heathfield

Richard said:

*important*

Once thing that some people seem to ignore is that MANY (or most) bugs
do not actually crash the program. The program just gives erroneous
results. There is no stack trace until you use a HW break point to catch
the offending run time state.

Absolutely right. In my case, however, it is the bugs that /do/ crash the
program that give me the most reason to use the debugger (to get a
backtrace). If the program is just giving wrong results, I generally find
that my time is better spent finding the bug some other way - stepping
through the code is something I prefer to avoid, because it's so
time-consuming. (I reiterate that, nevertheless, there are times when I
think stepping through the code in a debugger /is/ useful. It just doesn't
happen very often, that's all.)

I continue to find it strange that you are putting your view forward in
such a hostile and divisive manner. Is it not reasonable to let people
debug in the way that seems most appropriate to them? What's so hard to
believe about the possibility that other people may think differently to
you and work differently to you?
 
C

CBFalconer

Chris said:
If you put words into my mouth /one more time/ in this
conversation, I'll know to give it up.

Bear in mind that that Richard is a troll. Best PLONKED.
 
C

Chris Dollin

santosh said:
Chris Dollin wrote:



That's interesting. Can you explain that last parenthesised sentence?
Are you talking about eliminating bugs or eliminating the need of a
debugger as a principle?

The latter, although of course eliminating bugs is one way to reduce
the need for a debugger.

And I expect there's the usual terminology wars subtext -- "that's a
debugger!" "T'aint! That's just incremental compilation!", etc -- making
things more complex.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top