Question

Sorry I can't be specific with code, but the problems I am seeing are anomalous. Character string values seem to be getting changed depending on other, unrelated code. For example, the value of the argument that is passed around below will change merely depending on if I comment out one or two of the fprintf() calls! By the last fprintf() the value is typically completely empty (and no, I have checked to make sure I am not modifying the argument directly... all I have to do is comment out a fprintf() or add another fprintf() and the value of the string will change at certain points!):

static process_args(char *arg) {
    /* debug */
    fprintf(stderr, "Function arg is %s\n", arg);

    ...do a bunch of stuff including call another function that uses alloc()...

    /* debug */
    fprintf(stderr, "Function arg is now %s\n", arg);    
}

int main(int argc, char *argv[]) {
    char *my_arg;

    ... do a bunch of stuff ...

    /* just to show you it's nothing to do with the argv array */
    my_string = strdup(argv[1]);

    /* debug */
    fprintf(stderr, "Argument 1 is %s\n", my_string);

    process_args(my_string);
}

There's more code all around, so I can't ask for someone to debug my program -- what I want to know is HOW can I debug why character strings like this are getting their memory changed or overwritten based on unrelated code. Is my memory limited? My stack too small? How do I tell? What else can I do to track down the issue? My program isn't huge, it's like a thousand lines of code give or take and a couple dynamically linked external libs, but nothing out of the ordinary.

HELP! TIA!

Was it helpful?

Solution

Simple:

  1. Learn to use Valgrind, specifically memcheck
  2. Learn to use GDB including break points and variable inspection
  3. Practice makes perfect.

That should sort it. Make sure you compile any libraries with the -g option on GCC, which keeps debugging symbols so your debugging output makes more sense.

OTHER TIPS

There are two cases to consider:

  1. The arg variable changes value between the start and finish of process_args.
  2. The arg stays the same, but the string it points to is changed.

Your description and your code doesn't differentiate between the two, but it's important to know which of the two is actually happening.

This will reveal the answer:

fprintf(stderr, "Function arg is %s (%p)\n", arg, (void *)arg);
... do bunch of stuff ...
fprintf(stderr, "Function arg is now %s (%p)\n", arg, (void *)arg);

Most often arg is not changing (i.e. you have case 2). If so, something is corrupting the string you've allocated. Valgrind, suggested already, but available only on Linux, AIX and MacOSX, has only a 50:50 chance of finding the problem. What you really want is a GDB watchpoint: set breakpoint at the start of process_args, once hit, do (gdb) watch *(long*)arg and continue. GDB will stop when something writes to *arg (it will actually stop on the next instruction). Then use (gdb) where command to figure out what's happening.

If you actually have arg changing its value (case 1), that may be harder to debug, and indicates stack corruption of some sort, or a violation of procedure calling conventions for your platform. Valgrind will likely not help at all with that. This is more consistent with the behavior you described: commenting out unrelated code causes the bug to shift.

I can't give any further advice on debugging case 1 though, since you haven't revealed what your actual platform is.

If you are writing user-level applications, Valgrind is a good choice to detect memory problems such as memory leaks, buffer overflow, etc. Here is a quick start guide: http://valgrind.org/docs/manual/QuickStart.html

You don't give your dev tools, but if you're like 90% of coders you're already using an IDE with a debugger which can handle this, no new tools required. Set a watch on the chunk of memory holding your strings, then step through your code and see when the strings get changed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top