Thread: Can mere mortals understand GDB? :D

  1. #1
    Registered User
    Join Date
    Mar 2022
    Posts
    7

    Unhappy Can mere mortals understand GDB? :D

    Seriously. Sometimes, C does things that make absolutely no sense. Dereferencing a NULL pointer is one thing. CHECKING if something is NULL causing crashes is... janky to say the last. Nearest I can figure, if there's a full moon on Pi day (3/14 at 1:59 AM) and the planets are aligned just right, the gremlins come out to play.

    These logic-defying bugs are hidden behind the most obscenely cryptic pile of mumbo-McJumbo I've ever heard. "Segmentation fault (core dumped)." Okay, what's segmented and/or faulty? My system has 4 cores. Why you dumping on my cores, dude? It's like the system was only ever intended to be used by the people who built it. I tried looking it up on YouTube, and got a lot of people whose English was practically incomprehensible (maybe I should try typing my search keywords in Spanish? lol I speak Spanish so maybe) and all kinds of way-over-my-head stuff about looking at the underlying Assembly (and the only Assembly language I know is 6502) and all kinds of... just... nonsense... lol sorry, one of those exasperatingly long nights. Can't sleep, can't think straight, but would love to unlock the buried treasure that must be behind that fateful message.

    Does anyone know of a really good, clear-cut, straightforward tutorial, or collection of tutorials, for cracking the cipher behind this thing? Right now the error may as well be "Deep Magic from the Dawn of Time" (lol a nod to my fellow Narnia fans before I make like my program and crash).

  2. #2
    Registered User
    Join Date
    Feb 2022
    Location
    Canada, PEI
    Posts
    103
    Segmentation fault is caused when you try to deference invalid memory in your program.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    
    int main(int argc, char ** argv) {
      char * str = NULL;
      str[0] = 'G';//This will cause a seg fault because str isn't a valid memory address
      char *str2 = (char*)(intptr_t)104567;
      str2[0] = '4';//This will probably cause a seg fault because I guessed at a valid memory address
      return EXIT_SUCCESS;
    }
    Last edited by G4143; 03-21-2022 at 10:59 PM.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > "Segmentation fault (core dumped)." Okay, what's segmented and/or faulty?
    The OS sees your program as logically separate entities (like code and data), and these are the segments.
    A fault is doing something (a memory access) which isn't inside one of the known segments of memory.

    > My system has 4 cores. Why you dumping on my cores, dude?
    core in this sense of the word refers to core memory (you have to go back to the 1960's to understand this one).
    It's just the memory near to the processor in which your program was running.

    The core dump is a file (usually called core) which is a copy of that memory at the point the program crashed.
    The idea being you can then use a debugger to do a post-mortem analysis and figure out what went wrong.
    Whether you actually get a core file depends on your system admin (read about 'ulimit -c').

    The way to practice GDB is start with really simple programs with known obvious faults.
    Code:
    $ cat foo.c
    #include <stdio.h>
    void foo ( int *p ) {
        *p = 42;
    }
    int main ( ) {
        int p;
        foo(&p);
        foo(0);
    }
    $ gcc foo.c
    $ ./a.out 
    Segmentation fault (core dumped)
    OK, that didn't work, I wonder why


    Compile with debug information, then use gdb
    Code:
    $ gcc -g foo.c
    $ gdb -q ./a.out
    Reading symbols from ./a.out...
    (gdb) run
    Starting program: a.out 
    
    Program received signal SIGSEGV, Segmentation fault.
    0x0000555555555159 in foo (p=0x0) at foo.c:3
    3	    *p = 42;
    (gdb) bt
    #0  0x0000555555555159 in foo (p=0x0) at foo.c:3
    #1  0x0000555555555193 in main () at foo.c:8
    (gdb) up
    #1  0x0000555555555193 in main () at foo.c:8
    8	    foo(0);
    (gdb)
    Commands 'bt' (for backtrace) 'up' and 'down' allow you to see how you arrived at this particular state.


    A slightly longer example.
    Code:
    $ gdb -q ./a.out
    Reading symbols from ./a.out...
    (gdb) b foo
    Breakpoint 1 at 0x1149: file foo.c, line 2.
    (gdb) run
    Starting program: a.out 
    
    Breakpoint 1, foo (p=0x5555555551b0 <__libc_csu_init>) at foo.c:2
    2	void foo ( int *p ) {
    (gdb) n
    3	    *p = 42;
    (gdb) 
    4	}
    (gdb) 
    main () at foo.c:8
    8	    foo(0);
    (gdb) list
    3	    *p = 42;
    4	}
    5	int main ( ) {
    6	    int p;
    7	    foo(&p);
    8	    foo(0);
    9	}
    (gdb) print p
    $1 = 42
    (gdb) c
    Continuing.
    
    Breakpoint 1, foo (p=0x7fffffffde64) at foo.c:2
    2	void foo ( int *p ) {
    (gdb) c
    Continuing.
    
    Program received signal SIGSEGV, Segmentation fault.
    0x0000555555555159 in foo (p=0x0) at foo.c:3
    3	    *p = 42;
    (gdb) bt
    #0  0x0000555555555159 in foo (p=0x0) at foo.c:3
    #1  0x0000555555555193 in main () at foo.c:8
    (gdb)
    Start with a 'b' (breakpoint) on the suspect function, then run the program.
    Execute the next line using 'n' (next)
    Continue the program using 'c' (continue), which runs the program until the next breakpoint, fault, or normal program exit (whichever comes first).
    You can print variables using the 'p' (print) command.

    With just those few commands, you can figure out a lot of stuff about how your program is behaving.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Apr 2017
    Location
    Iran
    Posts
    138
    At times , I use "KDbg" which is a GUI for GDB.

  5. #5
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    Quote Originally Posted by ordak View Post
    At times , I use "KDbg" which is a GUI for GDB.
    kdbg is not available in all distros. It was removed from Debian. Can't speak for any other Distros.

    There are other frontends to gdb, or editors, and IDE's that can integrate gdb. Learning to use gdb on the command line is the best solution.

  6. #6
    Registered User
    Join Date
    Mar 2022
    Posts
    7

    Red face Thank you!

    Quote Originally Posted by Salem View Post
    > "Segmentation fault (core dumped)." Okay, what's segmented and/or faulty?
    The OS sees your program as logically separate entities (like code and data), and these are the segments.
    A fault is doing something (a memory access) which isn't inside one of the known segments of memory.

    > My system has 4 cores. Why you dumping on my cores, dude?
    core in this sense of the word refers to core memory (you have to go back to the 1960's to understand this one).
    It's just the memory near to the processor in which your program was running.

    The core dump is a file (usually called core) which is a copy of that memory at the point the program crashed.
    The idea being you can then use a debugger to do a post-mortem analysis and figure out what went wrong.
    Whether you actually get a core file depends on your system admin (read about 'ulimit -c').

    The way to practice GDB is start with really simple programs with known obvious faults.
    Code:
    $ cat foo.c
    #include <stdio.h>
    void foo ( int *p ) {
        *p = 42;
    }
    int main ( ) {
        int p;
        foo(&p);
        foo(0);
    }
    $ gcc foo.c
    $ ./a.out 
    Segmentation fault (core dumped)
    OK, that didn't work, I wonder why


    Compile with debug information, then use gdb
    Code:
    $ gcc -g foo.c
    $ gdb -q ./a.out
    Reading symbols from ./a.out...
    (gdb) run
    Starting program: a.out 
    
    Program received signal SIGSEGV, Segmentation fault.
    0x0000555555555159 in foo (p=0x0) at foo.c:3
    3        *p = 42;
    (gdb) bt
    #0  0x0000555555555159 in foo (p=0x0) at foo.c:3
    #1  0x0000555555555193 in main () at foo.c:8
    (gdb) up
    #1  0x0000555555555193 in main () at foo.c:8
    8        foo(0);
    (gdb)
    Commands 'bt' (for backtrace) 'up' and 'down' allow you to see how you arrived at this particular state.


    A slightly longer example.
    Code:
    $ gdb -q ./a.out
    Reading symbols from ./a.out...
    (gdb) b foo
    Breakpoint 1 at 0x1149: file foo.c, line 2.
    (gdb) run
    Starting program: a.out 
    
    Breakpoint 1, foo (p=0x5555555551b0 <__libc_csu_init>) at foo.c:2
    2    void foo ( int *p ) {
    (gdb) n
    3        *p = 42;
    (gdb) 
    4    }
    (gdb) 
    main () at foo.c:8
    8        foo(0);
    (gdb) list
    3        *p = 42;
    4    }
    5    int main ( ) {
    6        int p;
    7        foo(&p);
    8        foo(0);
    9    }
    (gdb) print p
    $1 = 42
    (gdb) c
    Continuing.
    
    Breakpoint 1, foo (p=0x7fffffffde64) at foo.c:2
    2    void foo ( int *p ) {
    (gdb) c
    Continuing.
    
    Program received signal SIGSEGV, Segmentation fault.
    0x0000555555555159 in foo (p=0x0) at foo.c:3
    3        *p = 42;
    (gdb) bt
    #0  0x0000555555555159 in foo (p=0x0) at foo.c:3
    #1  0x0000555555555193 in main () at foo.c:8
    (gdb)
    Start with a 'b' (breakpoint) on the suspect function, then run the program.
    Execute the next line using 'n' (next)
    Continue the program using 'c' (continue), which runs the program until the next breakpoint, fault, or normal program exit (whichever comes first).
    You can print variables using the 'p' (print) command.

    With just those few commands, you can figure out a lot of stuff about how your program is behaving.
    Wow, I asked for a tutorial and you wrote one on the spot! Thank you so much!

    Seriously tho, what you describe here sounds much, much simpler than pretty much any other explanation of segfaults I've ever read. I can't wait to get out of work and practice this (and to read that interesting reference to 60s tech - I know 8-bit stuff well but I thought the 60s they were still doing punch cards lol).

    btw, Thanks also to the other person, who responded with the GUI idea. Once I get used to the command-line version (which is probably what I'll end up using most of the time) I'll probably end up using the GUI for the project that's crashing - it uses ncurses, which I imagine doesn't play nice with another command-line app like GDB (lol). I usually prefer command-line over GUI but I think it might be better to use that KGdb thing on this one.

  7. #7
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    " I thought the 60s they were still doing punch cards lol" The university where I was teaching was using IBM punch cards for registrations into the 90's! ;^)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to understand '|=' and '<<'
    By xnigel in forum C Programming
    Replies: 6
    Last Post: 12-11-2014, 09:21 AM
  2. I don't understand this
    By Dontgiveup in forum C++ Programming
    Replies: 14
    Last Post: 03-28-2009, 07:04 PM
  3. Don't Understand
    By Trckst3 in forum C++ Programming
    Replies: 9
    Last Post: 04-04-2008, 11:58 PM
  4. help me understand this
    By dra in forum C++ Programming
    Replies: 6
    Last Post: 06-01-2005, 05:49 PM
  5. Can't understand FAQ
    By Vorkosigan in forum C++ Programming
    Replies: 3
    Last Post: 03-03-2004, 03:37 AM

Tags for this Thread