Good C debugger ?

I'm a C newbie using gcc. I wrote a program but a part of it outputs gibberish onto the terminal. Its weird because identical parts of the program work correctly in another program I wrote :confused:. My program uses c99 + some POSIX headers. It compiles with no errors/warnings even though I have included all the flags I could get hold of.

I do not understand how to use -g so can anybody recommend a C debugger (that speaks english, lol)? At this point I am even willing to switch to Windows...

Can anybody at least add other useful flags ?

Have you heard of man gdb ("linux") - The GNU Debugger ?

If you've can, install DDD, which is a graphical frontend to gdb (and a few others). Then, compile your program using

gcc -Wall -ggdb -o programname programname.c

Don't enable any optimization settings, as that will make debugging all the harder. Same goes for inlineing, ...

Start it using

ddd ./progname

, and start debugging.

See also: ddd(1) [linux man page]

Yes, I have heard and used it before with no success. I'm trying to debug a CGI program written in C. It seems to segfault when using getenv. I tried running the program with Firefox and using sleep(30) to make time to attach PID but it still segfaults on this line.

Any ideas ?

char DOCUMENTROOT[128] = "";
strcat(DOCUMENTROOT, getenv("DOCUMENT_ROOT")); // This line is ok, right ? I mean it is far less than 128 chars long.

Do you call any other environmental var C routines?

Are you sure your CGI has permissions to call these routines?

---------- Post updated at 16:15 ---------- Previous update was at 16:12 ----------

Also, I've not programmed in C for a very long time.... so maybe this is a dumb suggestion, sorry:

getenv() returns a pointer to a char.

You defined

char DOCUMENTROOT[128] = "";

Does this work?

char *DOCUMENTROOT[128] = "";

Actually, the problem is using "DOCUMENT_ROOT" because it is apache specific. Using "PATH" works.

So how could I debug my CGI program using apache and using GDB ??? (Like I said, running my CGI w/ Firefox and attaching its PID to GDB does not solve the problem.)

Seems I will have to temporarily substitute the getenv's with strings. :mad:

Good idea.

Environmental vars often cause problems in CGI.

Sorry, I can't help with C CGI debugging. I focus on PHP for web programming.

On the other hand, I have always found that print statements work well when debugging, even if it is so crude, it works well.

Maybe you can simply print to a string and pass it to your HTML when debugging. That is what I do, which does sound a bit primitive, I know.

Again, sorry, I use PHP on the server side for most web programming.

You can usually debug a CGI application like any other. The only differences are:

  • You'll have to set the CGI environment variables yourself. A script is best for that.
  • GET parameters are sent to the program using the QUERY_STRING environment variable. POST parameters are read from stdin.

This will crash if then environment variable DOCUMENT_ROOT is not set. This may crash if DOCUMENT_ROOT is longer than 128 chars.

Cheers,
Lo�c.

In bash I can set DOCUMENT_ROOT like this:

DOCUMENT_ROOT='/path-to-folder'; export DOCUMENT_ROOT

But how can I set stdin ?

You don't set stdin, you read from it (aka "The Keyboard" or "A Pipe")

How? The following will not work:

echo "field=value" | gdb myprogram

AFAIK, you can't directly pipe to a program being debugged. So Option 1 is to just paste the input with the mouse, if available. Option 2 uses a FIFO, description can be found here

IMHO, you will get your results faster if you debug with print statements.

it is possible for getenv() to return null! Test for that case or strcat will crash in it!

Writing CGI scripts in C is kind of clumsy. You can artificially create the environment your application expects when running it in GDB.

Create the environment variables for the application that apache would usually set up. You would only need to create the environment variables that your application requires. Thus, when you run GDB make an environment variable to simulate apache.

$ export DOCUMENT_ROOT="foo"
$ gdb myscript.cgi

The output will be ugly because it will be spitting out HTML.

Indeed. You should do as Corona688 has said.

char *p;
if( !( p = getenv( "DOCUMENT_ROOT" ) ) ) {
  // Do something
}
else
  strcat(DOCUMENTROOT, p);

You should also make sure p is not larger than DOCUMENTROOT or you shall cause a buffer overflow.