The best way to debug an error

J

jackassplus

I have a program that iterates through files in a directory parsing
them using regex.h
I compile it with
gcc -g -Wall -o parser.exe parser.c

in Windows (DJGPP), if I give it 8 files, it makes it through through
them fine, outputs what I expect and exits clean. If I give it 9
files, it silently dies towards the end of the ninth file before the
fclose() for that file.

in Linux, it segfaults after opening the first file.

What is the best way to debug it?

When I run it in gdb, it exits with status 02 earlier than if I run it
outside the debugger.

Where do I start?

This is by far my most ambitious program.
source is here: http://docs.google.com/Doc?id=ddbsfftc_9g2bndmhf

(hope its ugliness does not cause blindness)
feel free to email me directly if need be.
 
R

Richard

I have a program that iterates through files in a directory parsing
them using regex.h
I compile it with
gcc -g -Wall -o parser.exe parser.c

in Windows (DJGPP), if I give it 8 files, it makes it through through
them fine, outputs what I expect and exits clean. If I give it 9
files, it silently dies towards the end of the ninth file before the
fclose() for that file.

in Linux, it segfaults after opening the first file.

What is the best way to debug it?

When I run it in gdb, it exits with status 02 earlier than if I run it
outside the debugger.

Where do I start?

This is by far my most ambitious program.
source is here: http://docs.google.com/Doc?id=ddbsfftc_9g2bndmhf

(hope its ugliness does not cause blindness)
feel free to email me directly if need be.

It ran for me without a crash in gdb.

I ran with with about 15 files.
 
A

Antoninus Twink

What is the best way to debug it?

In this case, with valgrind.

The problem is that your program is leaking memory like a sieve, which
is a complete disaster since you're allocating the memory inside an
inner loop!

Look:

if ((status = regcomp(&re, pattern[1], REG_EXTENDED)) != 0) {
regerror(status, &re, buf, 120);
exit(2);
}
status = regexec(&re, ps, 1, pmatch, eflag);
if ((status == 0) && (found_file == 0)) {
/* [BIG SNIP] */
regfree(&re);
}

You need to move this regfree() to *after* the last brace above, so that
it gets freed unconditionally.

Similarly with the other two regfrees()... and as for the regcomp() in
the line after the comment "is it billable?", that NEVER gets
regfree()d!

In any case, it would be much better to restructure your code so that
you only compile each regex once rather than for each iteration of your
inner while loop.

I don't know exactly what logic your code is meant to be implementing,
but it would also be worth considering whether you might miss regex
matches if they occur across the boundary of two of the buffers read by
fgets().

Finally, there seems to be no reason to assume your card_data, file_data
and file_time arrays won't overflow their bounds: that's fine if you
control the contains of the working directory when the code is run, but
it's not good if this code might end up spreading beyond your personal
desktop.

PS. Why aren't you writing this in Perl? You could save yourself a *lot*
of headaches...
 
K

Keith Thompson

Missaka Wijekoon said:
P.S. It is possible that strcpy might be writing past the end of an
array. Try use strncpy instead.

strncpy is very rarely the right answer. If the target array is too
short to hold the source string, the target will be left with no '\0'
terminator. If it's longer, it will be padded with '\0' characters,
which is usually unnecessary.

Use strcpy or memcpy (if you use memcpy you may have to take care of
the trailing '\0' yourself), and make sure you don't write past the
end of the target array.
 
J

jackassplus

The problem is that your program is leaking memory like a sieve, which
is a complete disaster since you're allocating the memory inside an
inner loop!

moving the regfree() out of the loops and adding the last one seems to
have straightened things out.
In any case, it would be much better to restructure your code so that
you only compile each regex once rather than for each iteration of your
inner while loop.

I don't know exactly what logic your code is meant to be implementing,
but it would also be worth considering whether you might miss regex
matches if they occur across the boundary of two of the buffers read by
fgets().

Finally, there seems to be no reason to assume your card_data, file_data
and file_time arrays won't overflow their bounds: that's fine if you
control the contains of the working directory when the code is run, but
it's not good if this code might end up spreading beyond your personal
desktop.

Now that it actually does what I want it to do, that is next.
PS. Why aren't you writing this in Perl? You could save yourself a *lot*
of headaches...


I would have liked to use perl but the IT nazis at work won't allow
it. (or firefox, or a decent notepad, etc...)
thankfully, the data this is parsing is fairly well structured,
<generated xml>.
It works quite well now.

I'll see about redoing the regcomps so they only need go once per
pattern. (this is my first serious c program other than the little
ones for project euler).
 
G

Guest

On 10 Feb, 19:11, Missaka Wijekoon <missaka-dot-
(e-mail address removed)> wrote:

P.S. It is possible that strcpy might be writing past the end of an
array.  Try use strncpy instead

the semantics of strncpy() are non-intuitive (it's broken). So
generally
*don't* use strncpy.

/* what is wrong with this? */
char sbuff[4];
strncpy(sbuff, "bomb", 4);
printf ("%s\n", buff);

/* how many characters are written to bbuff? */
char bbuff [1000000];
strncpy(bbuff, "bomb", 1000000);

See FAQ 13.2 "Why does strncpy() not always place a '\0'
terminator in the destination string?
 

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,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top