Thread: learning gdb

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    35

    learning gdb

    Here's the code I am studying from "modern day c programming"

    Code:
    #include <string.h>
    
    #define MAX_REMIND 50
    #define MSG_LEN 60
    
    int read_line(char str[], int n);
    
    main()
    {
        char reminders[MAX_REMIND][MSG_LEN+3];
        char day_str[3], msg_str[MSG_LEN+1];
        int day, i, j, num_remind = 0;
    
        for (;;) {
            if ( num_remind == MAX_REMIND) {
                   printf("-- No space left --\n");
                   break;
            }
    
            printf("Enter day and reminder: ");
    
            scanf("%2d", &day);
            if ( day == 0 )
                 break;
            sprintf(day_str, "%2d", day);
            read_line(msg_str, MSG_LEN);
    
            for (i = 0; i < num_remind; i++ )
                if ( strcmp(day_str, reminders[i]) < 0 )
                       break;
            for (j = num_remind; j > i; j-- )
                strcpy(reminders[j], reminders[j-1]);
    
            strcpy(reminders[i], day_str);
            strcat(reminders[i], msg_str);
    
            num_remind++;
        }
    
        printf("\nDay Reminders\n");
        for ( i = 0; i < num_remind; i++ )
           printf(" %s\n", reminders[i]);
    
        return 0;
    }
    
    int read_line(char str[], int n )
    {
        char ch;
        int i = 0;
    
        while (  (ch = getchar() ) != '\n' )
              if ( i < n )
                   str[i++] = ch;
    
              str[i] = '\0';
              return i;
    
    }
    ~
    And here's gdb session I am doing:

    Two question,
    1)why can't I print out value of MAX_REMIND
    2)why can't I print out the value of msg_str


    Code:
    GNU gdb Red Hat Linux (6.3.0.0-1.162.el4rh)
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
    
    (gdb) b main
    Breakpoint 1 at 0x80484bf: file big_to_small.c, line 13.
    (gdb) r
    Starting program: /root/pro/c/big_to_small 
    
    Breakpoint 1, main () at big_to_small.c:13
    13          int day, i, j, num_remind = 0;
    (gdb) s
    16              if ( num_remind == MAX_REMIND) {
    (gdb) disp num_remind
    1: num_remind = 0
    (gdb) disp MAX_REMIND
    No symbol "MAX_REMIND" in current context.
    (gdb) s
    21              printf("Enter day and reminder: ");
    1: num_remind = 0
    (gdb) 
    23              scanf("%2d", &day);
    1: num_remind = 0
    (gdb) 
    Enter day and reminder: 1^H1^H^H^H
    24              if ( day == 0 )
    1: num_remind = 0
    (gdb) k
    Kill the program being debugged? (y or n) y
    (gdb) b main
    Note: breakpoint 1 also set at pc 0x80484bf.
    Breakpoint 2 at 0x80484bf: file big_to_small.c, line 13.
    (gdb) r
    Starting program: /root/pro/c/big_to_small 
    
    Breakpoint 1, main () at big_to_small.c:13
    13          int day, i, j, num_remind = 0;
    1: num_remind = 0
    (gdb) s
    16              if ( num_remind == MAX_REMIND) {
    1: num_remind = 0
    (gdb) 
    21              printf("Enter day and reminder: ");
    1: num_remind = 0
    (gdb) 
    23              scanf("%2d", &day);
    1: num_remind = 0
    (gdb) 
    Enter day and reminder: 16 birthday
    24              if ( day == 0 )
    1: num_remind = 0
    (gdb) s
    26              sprintf(day_str, "%2d", day);
    1: num_remind = 0
    (gdb) 
    27              read_line(msg_str, MSG_LEN);
    1: num_remind = 0
    (gdb) disp msg_str
    2: msg_str = '\0' <repeats 60 times>
    (gdb) disp MSG_LEN
    No symbol "MSG_LEN" in current context.
    (gdb) print msg_str
    $1 = '\0' <repeats 60 times>
    (gdb)

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by convenientstore View Post
    1)why can't I print out value of MAX_REMIND
    MAX_REMIND is a pre-processor symbol (#define). Before compilation even starts, the preprocessor does a string replace and everywhere it sees MAX_REMIND it replaces it with 50, thus, when your code is compiled, it's as if you typed in 50 everywhere instead of MAX_REMIND. Two options:
    1. Make it a const int MAX_REMIND = 50;
    2. Compile with -ggdb3, which should put pre-processor symbols in your executable. Note that this can increase the size of your executable significantly.

    2)why can't I print out the value of msg_str
    You can and you did:

    Code:
    (gdb) print msg_str
    $1 = '\0' <repeats 60 times>
    It just happens that message string is full of 60 null characters ('\0'), so GDB saves space by saying you have a '\0' byte, and it repeats 60 times, instead of showing you the whole array/string.

    EDIT: You can adjust this with 'set print repeats' in GDB. Type 'help set print repeats' for more info.
    Last edited by anduril462; 05-26-2011 at 09:47 AM.

  3. #3
    Registered User
    Join Date
    Feb 2009
    Posts
    35
    @anduril462,

    Thank you for your explanation. Very detailed. I understood perfectly.

  4. #4
    Registered User
    Join Date
    Feb 2009
    Posts
    35
    Just one more question, I am failing to see where the value 'i' (for which is being return) is being used for.. ?

    Code:
    int read_line(char str[], int n )
    {
        char ch;
        int i = 0;
    
        while (  (ch = getchar() ) != '\n' )
              if ( i < n )
                   str[i++] = ch;
    
              str[i] = '\0';
              return i;

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by convenientstore View Post
    Just one more question, I am failing to see where the value 'i' (for which is being return) is being used for.. ?

    Code:
    int read_line(char str[], int n )
    {
        char ch;
        int i = 0;
    
        while (  (ch = getchar() ) != '\n' )
              if ( i < n )
                   str[i++] = ch;
    
              str[i] = '\0';
              return i;
    It looks like it's returning a count of the characters entered... i.e. the length of the string.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Code:
    str[i++] = ch;
    I gets incremented every time this line is executed.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    And as a note about that function: you have most of the indentation right, but that function threw you, it looks like; the last two statements (str[i] = '\0' and return i) are not part of the loop.

  8. #8
    Registered User
    Join Date
    Feb 2009
    Posts
    35
    Thank you again for all kind response.
    My question is, yes I see that i is being incremented and points to last point position when it reads all input, so at the end, it's pointing to last position of the character.
    Question is, or rather my assumption of this point is to when
    Code:
     strcat(reminders[i], msg_str)
    gets copied to reminders, it knows how much it needs to copied to.
    Is this right assumption?

    Code:
            read_line(msg_str, MSG_LEN);
    
            for (i = 0; i < num_remind; i++ )
                if ( strcmp(day_str, reminders[i]) < 0 )
                       break;
            for (j = num_remind; j > i; j-- )
                strcpy(reminders[j], reminders[j-1]);
    
            strcpy(reminders[i], day_str);
            strcat(reminders[i], msg_str);
    
            num_remind++;

  9. #9
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Prefer enum over const especially if it is for array size. If you use const, you are using VLA. C99 feature..

  10. #10
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by tabstop View Post
    And as a note about that function: you have most of the indentation right, but that function threw you, it looks like; the last two statements (str[i] = '\0' and return i) are not part of the loop.
    In this case, I don't think they're supposed to be... that's null terminating the string and returning it's length.

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Bayint Naung View Post
    Prefer enum over const especially if it is for array size. If you use const, you are using VLA. C99 feature..
    Good call with the enum, slipped my mind. I didn't think that a using a const would be considered VLA's, since the value is known at compile time...good to know though.

  12. #12
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    The code

    Code:
    const int N = 10;
    int a[N];
    won't compile in C89. C++ will compile.

    Code:
    $ cat foo.c
    #include <stdio.h>
    
    const int N = 10;
    
    int main(void)
    {
      int a[N];
      printf("%p\n",a);
    return 0;
    }
    
    $ gcc -Wall -pedantic-errors -std=c89 foo.c
    foo.c: In function 'main':
    foo.c:7: error: ISO C90 forbids variable-size array 'a'
    foo.c:8: warning: format '%p' expects type 'void *', but argument 2 has type 'in
    t *'
    Last edited by Bayint Naung; 05-26-2011 at 08:51 PM.

  13. #13
    Registered User
    Join Date
    Feb 2009
    Posts
    35
    Another weird thing. Why is J's value 1 instead of 0 here??

    Code:
    (gdb) b main
    Breakpoint 1 at 0x100000ad4: file month_reminder.c, line 11.
    (gdb) r
    Starting program: /Users/javaxtra/Desktop/MY/c programs/pra/month_reminder_minus_return 
    Reading symbols for shared libraries +. done
    
    Breakpoint 1, main () at month_reminder.c:11
    warning: Source file is more recent than executable.
    11      {
    (gdb) s
    16          int day, i, j, num_remind = 0;
    (gdb) disp i
    1: i = 0
    (gdb) disp j
    2: j = 1
    (gdb) disp num_remind
    3: num_remind = 0
    (gdb) disp day
    4: day = 1
    (gdb)

  14. #14
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Uninitialized variables can be any value.

    Tim S.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. learning this.
    By S_R_S5 in forum Windows Programming
    Replies: 2
    Last Post: 03-26-2008, 12:01 AM
  2. learning c++
    By AquaFight in forum C++ Programming
    Replies: 11
    Last Post: 01-07-2008, 05:55 PM
  3. Learning Dos and learning Windows
    By blankstare77 in forum C++ Programming
    Replies: 8
    Last Post: 07-31-2005, 03:48 PM
  4. Learning C or C++ ?
    By Xoid in forum A Brief History of Cprogramming.com
    Replies: 23
    Last Post: 04-04-2003, 11:33 AM