strlen returns incorrect value when called in gdb

5,516

Solution 1

The library is working just fine. The program reports the correct value even when run under gdb. The bug seems to be in the way that gdb is evaluating the expression and forcing the target program to call the function. I'm seeing this same behavior on 10.04 as well. Strangely p printf("foo\n") correctly prints 4.

It seems that gdb is confused because strlen is a builtin. If you do this:

int (*len)(char *) = strlen;

And then have gdb print len("foo") you get the correct result.

Solution 2

It's a late update, but...

Use printf function can get this work around e.g. instead of p strlen(var) use p printf(var) it will print the length of the string var

Solution 3

This is a known bug in eglibc apparently. See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=594740

Share:
5,516

Related videos on Youtube

alesplin
Author by

alesplin

Graduated in Computer Science from BYU Software Engineer at Cluster Resources/Adaptive Computing 2008-2011 Software Engineer at Apple 2012-2019

Updated on September 17, 2022

Comments

  • alesplin
    alesplin over 1 year

    So I'm noticing some severely incorrect behavior from calls to standard library functions inside GDB. I have the following program to illustrate:

    #include <stdio.h> 
    #include <stdlib.h>
    #include <string.h> 
    
    int main(int argc, char *argv[]) {
      char *s1 = "test";
      char *s2 = calloc(strlen("test")+1,sizeof(char));
    
      snprintf(s2,strlen("test")+1,"test");
    
      printf("string constant: %lu\n", strlen(s1));
      printf("allocated string: %lu\n", strlen(s2));
    
      free(s2);
    
      return 0;
    }
    

    When run from the command-line, this program outputs just what you'd expect:

    string constant: 4
    allocated string: 4
    

    However, in GDB, I get the following, incorrect output from calls to strlen():

    (gdb) p strlen(s1)
    $1 = -938856896
    (gdb) p strlen(s2)
    $2 = -938856896
    

    I'm pretty sure this is a problem with glibc shipped with Ubuntu (I'm using 10.10), but this is a serious problem for those of us who spend lots of time in GDB.

    1. Is anyone else experiencing this kind of error?

    2. What's the best way to fix it? Build glibc from source? (I'm already running a version of GDB built from source)

  • alesplin
    alesplin about 13 years
    When did strlen become a builtin in gdb? And why does it only fail on Debian/Ubuntu systems?
  • psusi
    psusi about 13 years
    @alesplin it is a built in in gcc, not gdb.
  • alesplin
    alesplin about 13 years
    Right. Had me worried there for a minute. The problem is other library functions (or "builtins") work when called directly from GDB. I rely on this quite heavily, but since I got a new work computer running Ubuntu, I can't use strlen, strcmp, etc because they are broken. Your proposal of declaring a function pointer to strlen did work, but is not really feasible for our environment.
  • psusi
    psusi about 13 years
    @alesplin builtin means it is built into the compiler, not a library function. Only certain library functions are built in. This means that the compiler directly generates the code to implement them in the place where they are used, rather than calling an actual library function.
  • alesplin
    alesplin about 13 years
    This is even more problematic then, as other functions declared by the gcc documentation to be builtins (atoi,isdigit,isupper) work as expected. So if it's not libc, and all builtins aren't broken, does that mean Ubuntu ships a wonky gcc? I've tried this with Ubuntu's gdb (7.2), and my own (6.7.1 built from source).
  • psusi
    psusi about 13 years
    @alesplin interesting. Maybe it doesn't have anything to do with being a builtin then. You didn't mention if the other version of gdb you tried worked or not. When I check the symbols of libc with nm, I do notice that most functions are T type but strlen is i type. Not sure what that means, but maybe that is what is confusing gdb.
  • alesplin
    alesplin about 13 years
    I've seen this, and it's somewhat disturbing to me that such a glaring problem upstream can remain unsolved for so long.
  • karlphillip
    karlphillip about 13 years
    OMG, still not solved.
  • karlphillip
    karlphillip about 13 years
    From this int (*len)(char *) = strlen;, GDB screams Ambiguous command "int (*len)(char *) = strlen;": internals, interpreter-exec, interrupt. What can I do?
  • psusi
    psusi about 13 years
    @karlphillip you can't ask gdb to define a variable; that code needs to be compiled.
  • karlphillip
    karlphillip about 13 years
    Indeed. This post is related to this very same issue: stackoverflow.com/questions/5507255/…