Seriously struggling with C

C

Chris Dollin

Richard said:

Formal specification and proof.
Code reviews.
Pair programming.
Test-driven development.

That last is the one I use nowadays. But even in my sloppy youth,
using a debugger - watchpoints and breakpoints and manual stepping
and all - didn't seem to be helpful to me.

But, because I haven't had a proper C project for a while, I can't
speak to developing C using TDD - I expect that to change this year,
depending on how much home-time I can free up.
 
R

Richard G. Riley

I guess you've never tried TDD?


Tell me, when something DOES go wrong : how do you find that elusive
bug?

The sense isn't false if the tests are good and written first. In my
opinion, test added after the code is written are second rate.

I would agree here.
 
R

Richard G. Riley

Formal specification and proof.
Code reviews.
Pair programming.
Test-driven development.

All part of a proper cycle. And no where do I disagree. Was your
snipping a little selective?

None of the above help you locate a bug when the bug exists in some
elusive code deepin a complex system.
That last is the one I use nowadays. But even in my sloppy youth,
using a debugger - watchpoints and breakpoints and manual stepping
and all - didn't seem to be helpful to me.

It must be a personal thing. I find them invaluable. I have programmed
some pretty big system with a lot of inetrfacing to legacy systems. I
coudl not image trying to tackle these monsters without a good
debugger. No amount of testing automative frameworks can help locate a
bug in such a system. They can help bring up a bug ; but that is
detect as opposed to fix.
 
I

Ian Collins

Chris said:
Richard G. Riley wrote:




Formal specification and proof.
Code reviews.
Pair programming.
Test-driven development.

That last is the one I use nowadays. But even in my sloppy youth,
using a debugger - watchpoints and breakpoints and manual stepping
and all - didn't seem to be helpful to me.

But, because I haven't had a proper C project for a while, I can't
speak to developing C using TDD - I expect that to change this year,
depending on how much home-time I can free up.
It does work well. You have to bend a few rules, but I've run a couple
of successful TDD C projects.
 
I

Ian Collins

Richard said:
Tell me, when something DOES go wrong : how do you find that elusive
bug?
Resort to the debugger :)

But I find I do this way less with decent tests.
 
I

Ian Collins

Richard said:
It must be a personal thing. I find them invaluable. I have programmed
some pretty big system with a lot of inetrfacing to legacy systems. I
coudl not image trying to tackle these monsters without a good
debugger. No amount of testing automative frameworks can help locate a
bug in such a system. They can help bring up a bug ; but that is
detect as opposed to fix.
Agreed, legacy systems are a PITA and the debugger, plus some code
analysis tools are a big help working out how the system works.
 
R

Richard G. Riley

Resort to the debugger :)

But I find I do this way less with decent tests.

Agreed.

Thats said, I still stick my old age habit of always stepping though my code
though for reasons hilited before. maybe it was because I grew up on
68000 and z80 - the later without an assembler. When I got a half
decent system debugger it was heaven - and it was a habit which never
left me.
 
R

RSoIsCaIrLiIoA

Purely as an observation, I find that the gcc x86 code generator
tends to partially unroll while loops. i.e.:

while (NUM != x) {
dothings();
}

tends to become:

if (NUM != x)
do {
dothings()
} while (NUM != x);

for me tends to become:

goto la;
l0:;
dothings();
la:; if(NUM!=x) goto l0;
 
D

Dik T. Winter

> with the
>
> Find a good tutorial on using one. This is where debuggers can be
> invaluable.

I know how to use debuggers, thank you very much.
> second
>
> Debuggers are not there to find problems with "the language". They are
> there to find problems with data assignments, logic and program flow.
>
>
> And a good debugger would hilite this very quickly if you set the
> right watchpoints.

Oh, yeah. I have no idea where to set a watchpoint if the normal flow
of the program would require millions of calls to a routine, but in
this case (due to the logic error) it was quite a bit more.
>
> I would find a debugger useful here.

You think so? Even when the problem shows up only after many many
minutes of running?
>
> It can and it cant. It can show you where resulting cast/assign mismatches
> go wrong as you examine the data. In this case though, assuming you
> hadnt cast everythign to death, the compiler should have been a help.

No cast in sight. gcc does nog give warnings in this case.
 
D

Dik T. Winter

>
> This is simply not true. Since you must have some idea where the
> problem is to insert the "printf" then you have some idea where to set
> your breakpoint to detect "naughty data" : then you can do a stack
> trace to see where this data originated.

Also when the problem occurs on something like the millionth call to some
routine?
 
R

Richard G. Riley

Also when the problem occurs on something like the millionth call to some
routine?

Of course. Thats why breakpoints exist. I would do the following -

1) Isolate as close as possible to where/why bug is happening.
2) Possibly stick in special trap code (depends)
3) Use a HW breakpoint or if performance allows use a HW
watch break point to trap on a a matching expression.

Step through.

Easy, done many times and standard procedure.

Of course there can be times where this might not work, but its very
rare.

Whayt debuggers have you used? Maybe they were not suitable for the
job in hand?
 
R

Richard G. Riley

I know how to use debuggers, thank you very much.

Oh, ok. Sorry. I really didnt realise.
Oh, yeah. I have no idea where to set a watchpoint if the normal flow
of the program would require millions of calls to a routine, but in
this case (due to the logic error) it was quite a bit more.

If there are millions of flashy things causing a bug in some as yet
unlocated part of the code then I doubt very much that NOT using a
debugger is much of a help either.

Stepping though code INDICATES the logic errors : if by this you mean
falsely branching conditions. This can be hard or even impossible to
see through a code read because you dont have the data flwoing through
the veins of the program. Do you use something else?
You think so? Even when the problem shows up only after many many
minutes of running?

Of course. Thats when I would reach for the debugger. And set a
breakpoint based on a call counter or somesuch to get nearer to the
true problem.
No cast in sight. gcc does nog give warnings in this case.

The debugger would format the data as it was declared : it would be
fairly obvious to anyone stepping the code that a DOUBLE was being
forced into an INT for example.

If you can develop without using one then fine. But questioning the
usability of one for a large system running millions of calls is dubious.
 
C

Chris Hills

Also when the problem occurs on something like the millionth call to some
routine?

This is where and ICE is essential Let it run the system using filters
and watch points Also most good ones will let you out timing constraints
and bands on Also conditional break points with actions etc It's
virtually the only way to find this sort of problem (assuming you have
used static analysis to get rid of the silly stuff first)

However printf is just about the worst thing you can use in this case as
it changes the memory map and the timing
 
C

Chris Hills

I know how to use debuggers, thank you very much.

It appears not.
You think so? Even when the problem shows up only after many many
minutes of running?

That is why I use an ICE. Especially where it is something like a
certain combination of interrupts causing a problem in timing every now
and again. Watch points, filters, filtered trace etc along with a script
will let the system run overnight and narrow down the problem area.

The ICE should be part of the unit and system test system. When things
go wrong then it becomes the debugger.
No cast in sight. gcc does nog give warnings in this case.

Then don't use GCC.

However an ICE will let you see EXACTLY how the memory is used.
 
C

Chris Hills

Rod Pemberton <do_not_have said:
I wrote my first program in 1981 (or was it '79?). Anyway, in all that time
through maybe fourteen languages, I've only had to use a debugger twice.
Once for a compiler issue and the other to track data between multiple
processes. Printf's or it's equivalent is sufficient.

Wow! As printf change both the memory map and the timing they are
usually outlawed for debugging on most developments I have worked on.
It's like opening the fridge door to see if the light is on. Also there
is no way of knowing if they are telling the truth.

Since I've
essentially never needed it, I have no choice but to consider the use of a
debugger to be a serious indicator that you're doing something wrong.
Perhaps, you need to develop a set of coding rules or a style guide to help
correct the errors your encountering?

We usually take it that some one who does not use a debugger/ICE but
uses printf is not safe to be let loose unattended. But then most of my
work is high integrity embedded stuff.
 
B

Ben Pfaff

Richard G. Riley said:
Tell me : when any code of any reasonable level of complexity (maybe
long code, maybe lots of calls, maybe clever optimized bit
manipulations, maybe clever equations for image manipulation, maybe
calls to less robust areas of legacs system, goes wrong, what do you
do?

I doubt that anyone here is trying to say that a debugger cannot
be useful for finding bugs. I personally would take the position
that a debugger is a tool that *can* be used for finding bugs.
It is more of a personal preference whether the debugger *should*
be the first avenue of attack for hunting a bug. For me,
personally, it isn't; for you, I can see that it is.
 
R

Richard G. Riley

I doubt that anyone here is trying to say that a debugger cannot
be useful for finding bugs. I personally would take the position
that a debugger is a tool that *can* be used for finding bugs.
It is more of a personal preference whether the debugger *should*
be the first avenue of attack for hunting a bug. For me,
personally, it isn't; for you, I can see that it is.

No, funny enough they were. And this is what kicked off this
"debate". At least two regular contributors expressed derision that
anyone would ever need a debugger because "printf" was sufficient : a
debuger is, apparently, especially useless in millions of lines of
code or millions of calls into the code. My ability to think and
design was questioned since I felt the need to use a debugger at any
stage in my products' development : apparently good logic and a keen
eye should iron out all bugs without needing to resort to manual
register/variable inspection.
 
C

Chris Dollin

Richard said:
No, funny enough they were.

Not my reading, guv.
And this is what kicked off this
"debate". At least two regular contributors expressed derision that
anyone would ever need a debugger because "printf" was sufficient :

If you think one of them was me, then I haven't been clear enough.

I haven't said, and don't claim, that no-one should /ever/ need a
debugger [where by "debugger" I mean a manually-operated code-tracing
and breakpointing and watchpointing tool].

It was, if I recall, /you/ who were astonished that some of us don't
make - or need - routine use of a debugger, and that on the occasions
where we want code to report what it's doing, we have the code report
what it's doing using printf (or moral equivalents like logging).
I routinely don't use a debugger, because I routinely don't hit
situations where I need one.

/Personally/, I think routine use of a debugger -- eg, to walk through
new code to see what it's doing -- is a complete waste of my time.
If it works for you, well, ok, it works for you -- but you seem
as unwilling to accept my lack-of-need-for as I am to accept your
need-for ... "at least there is symmetry".
My ability to think and
design was questioned since I felt the need to use a debugger at any
stage in my products' development

No more than other's ability was questioned because they didn't
routinely deploy debuggers.
: apparently good logic and a keen
eye should iron out all bugs without needing to resort to manual
register/variable inspection.

/All/ is an over-statement. /Most/ is fine. And it's not "good logic
and a keen eye": it's good logic, a keen eye, constructive formatting
options, incremental development, test suites, simple design, coverage
tools, etc. Don't make the differences in our positions to be more,
and more absolute, than they are.
 
M

Micah Cowan

Ian Collins said:
It does work well. You have to bend a few rules, but I've run a couple
of successful TDD C projects.

I've only recently started using this model as much as possible, and
it has turned out to be quite helpful for me.

However, I personally still use a debugger quite a lot. If for no
other reason, I frequently like to reassure my paranoid self that the
unit-test itself is actually testing what I think it is. As a
side-benefit, stepping through the code this way (which doesn't
technically require the aid of a debugger) can sometimes reveal
further unit tests that I have neglected to write.

-Micah
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top