Skip to playerSkip to main contentSkip to footer
  • 2 days ago
Hey everybody! Ready to crush those pesky bugs in your C++ and assembly programs? In this video, we?re diving deep into the GNU Debugger (GDB) ? the ultimate tool for tracking down crashes, inspecting variables, and mastering your code. From setting up debug symbols to navigating call stacks, setting breakpoints, and even debugging assembly registers, this fun and relatable guide has you covered. Whether you?re a beginner coder or a seasoned dev, you?ll learn practical tips to level up your debugging game. We?ll also tackle null pointers, create GDB scripts, and explore why your program might be misbehaving. Stick around for a few laughs and some serious skills! Don?t forget to subscribe, hit that like button, and check out my website for more coding tutorials. Let?s debug like pros together!

Introduction to GNU Debugger 00:00:00
What is a Debugger 00:00:20
Debug Symbols Explanation 00:02:08
Compiling with Debug Symbols 00:03:13
File Size Comparison 00:05:30
Installing and Launching GDB 00:06:21
GDB Console Basics 00:06:55
Attaching GDB to Program 00:08:12
Running Program in GDB 00:09:09
Handling Program Crash 00:13:02
Understanding Call Stack 00:14:05
Navigating Call Stack 00:18:13
Inspecting Variables 00:19:08
Null Pointer Issues 00:21:25
Using GDB Script 00:25:10
Setting Breakpoints 00:27:04
Managing Breakpoints 00:28:37
Continuing Execution 00:30:41
Debugging Assembly 00:33:24
Global Variables in Assembly 00:35:43
Advanced GDB Commands 00:38:31
Conclusion and Call to Action 00:40:22

Thanks for watching!

Find us on other social media here:
- https://www.NeuralLantern.com/social

Please help support us!

- Subscribing + Sharing on Social Media
- Leaving a comment or suggestion
- Subscribing to our Blog
- Watching the main "pinned" video of this channel for offers and extras
Transcript
00:00Hey everybody! In this video I'm going to show you how to use the GNU debugger to
00:04debug your C++ and assembly programs. You can also use it for C and some other
00:14stuff but we're just going to focus on C++ and assembly. What is the GNU
00:18debugger and what is a debugger in the first place? So for starters the GNU
00:22debugger it's like it's called GDB and the the DB you can imagine that stands
00:29for debugger something like that and the G stands for GNU. I personally don't
00:35know how to pronounce GNU so I just say GNU because it it feels more fun to do it
00:41that way it's more interesting I think probably some people just say new but I
00:45don't like that because the GDB debugger is really old and robust and powerful
00:49it's not a new tool it's it's an old-school tool and so if I said hey let's
00:55use the new debugger someone's always going to ask what was the old debugger
01:00and then I say this is the old debugger the new debugger is the old debugger
01:04anyway so we're going to use the GNU debugger if you haven't yet watched my
01:09video on caveman debugging you probably want to watch that first just for like
01:12some basics of you know why you might want to look at information in your
01:16program but for now we'll just assume that you already know what's going on
01:20with just like why you would want to debug if you don't know how to make make
01:24files see my other videos but here I just have a basic make make file all
01:29it's really going to do is just sort of compile a very simple program and add
01:33debug symbols into it so let's double check that I'm actually doing that here
01:37yeah there we go okay so the first thing that I should probably show you is we are
01:45compiling a C++ source module so I've got a variable in my make valve for that
01:50and we're not actually using C but I have that left over in there anyway and
01:54then we're assembling something in Yasm we're linking with G++ because we want
01:59to have a hybrid program and we've got all these flags here those are just
02:02variables and so so now before I can debug with GDB I've got to talk about
02:08something called debug symbols what are debug symbols imagine just a bunch of
02:13extra information explaining all of the design and variables and everything
02:18inside of your code just a bunch of extra information about your code stuffed
02:22directly into the executable so imagine you know when we when we compile a C++
02:28source module into an object file usually that's just you know assembly at that
02:33point but when we add debug symbols we'll have a bunch of information that
02:38can help the debugger figure out where we are in the program what the variables
02:41look like you know a bunch of extra information to help the debugger pretty
02:45much the assembler will put debug symbols into the object code that you
02:49generate the compilers will do that the linker will do that and so it's
02:53important to understand if you don't generate debug symbols when you're
02:56compiling and linking your code then your debugger won't actually be able to do
03:01anything it will understand what's going on you can debug it but like you're not
03:04going to see anything that's very that's useful so let me show you real fast I'm
03:09going to do make clean and then I'm going to say make build and let me just
03:14double check my command here that I do not have debug symbols all right okay if
03:19you don't know how to compile and link from the command line see my other videos
03:23but for now it looks like we're not generating debug symbols so if I list the
03:27contents of my directory here just note the size is real fast I have an
03:32assembly module here that I'm calling assi.asm assi for assembly and then we're
03:36assembling it down to an object file notice how it's just 656 bytes very
03:41small and then the C++ module that I'm creating here is compiling to an object
03:48file that is about four and a half kilobytes so you know not too big the
03:52final executable is called main and it's about 17 kilobytes so this is without
03:57debug symbols when you're compiling something on your own you need to add
04:01extra switches to enable debug symbols so you can see here in this make file that
04:05I've made and again if you don't know how to make a make file or compile or a
04:10link or anything see my other videos but for now I'm just going to assume you kind
04:13of know your way around to make file or at least you can kind of infer what's
04:16going on so I've commented out a different version of this variable for
04:21the flags of my C++ compiler if I uncomment this and then comment out the
04:28other one you'll notice the only real difference is this part right here
04:31dash g dwarf 2 usually in C++ compilation it'll just be dash g to generate debug
04:39symbols and then the symbol format will default to a format called dwarf 2 so I
04:44don't know for these tutorials I like to just specify the full format but you can
04:49just say dash g in your C++ compiler and linker we do the same thing for the
04:54linker down here so I'm going to uncomment this and comment that and the only
04:58difference is just g dwarf 2 so I'm just telling my linker that I also want debug
05:04symbols in there too then we do the same thing for the assembler so I'm going to
05:08uncomment that and comment this other one and the only difference is that in the
05:12assembler we kind of have to specify it a little bit differently instead of g dwarf
05:17dash 2 it's just g dwarf 2 with as just one string and I think with yasm you have
05:23to specify the debug symbol format so just keep that in mind so now I've turned on
05:28all the debug symbols I'm going to do real fast make clean and make build one
05:34more time and then if I list everything let me just double check that it's
05:37building the symbols now right okay good notice that the files are bigger so this
05:43a seo file is now 1.8 kilobytes instead of you know half a kilobyte the main dot o
05:52object file is now 36 kilobytes instead of only 4.5 and the executable main is 36
05:59kilobytes instead of just 17 so you can feel it already right like there's a bunch
06:04of extra information sitting inside the object files and the binary which allows
06:08us to debug our program okay so now that we've generated debug symbols in our
06:13program we can actually think about starting to use GDB so GDB is a program
06:18just GDB by the command line if you don't have it in your system already you
06:22can go sudo apt install GDB or depending on what system you're on maybe a or sudo
06:30DNF install GDB or whatever your package management program is but we just need
06:35to install GDB on Ubuntu and Debian I think there is a meta package called build
06:41essential which will give you a bunch of compilation tools and make file stuff and
06:48whatever so I'm just going to assume at this point you already have GDB on your
06:51system to launch GDB and go into its console just type GDB by itself so now
06:58we're inside of the GDB console or terminal we're no longer inside of a bash
07:03terminal we can't type normal commands let me show you real fast here's the
07:07first command you want to learn on GDB it's called quit never quit never surrender
07:12so you know normally if you're at the command line you can do something like
07:17cat etc OS release just to see what operating system you're using so you can
07:22see for this virtual machine that I'm using right now I've got like a boon 22 on
07:26there if we go inside of GDB we can't use regular bash commands anymore or regular
07:34operating system commands we can't say cats etc OS release because we can now only use
07:40GDB commands we're inside of GDB already notice how it says undefined catch
07:45command I don't know what you're talking about dude okay so remember we do a queue
07:51or quit to get out you can actually just type queue a lot of commands that I'm
07:56going to be talking about you can abbreviate them with one or two or three
07:59letters and it totally works just for speed so now that we know how to enter GDB
08:05and now that we also know that we have already compiled our program with debug
08:09symbols we can attach GDB to our program I mean what's the whole point of a
08:13debugger we most of the time we will just have our debugger attached to our
08:18program and launch it or I guess launch it while it's attached you can also
08:22attach to a running program already but we're gonna launch a program and stay
08:26attached to it and then we can sort of catch crashes and see what's going on or we
08:33could also tell the debugger to stop the program at certain points in time like
08:36when we hit a certain line number or when a variable changes or something like that
08:40and then we can look around we can look at all the variables look at the state of
08:43the program even change things if we wanted to we can look at all the
08:47registers if you're coding in assembly so it's pretty useful anyway I'm gonna go
08:52GDB and the next command we're gonna learn is file which just tells GDB to
08:57attach to a program so that we can run it so you know the name of our program here
09:03that we compiled is just called main and so if I type file main then GDB should
09:09load up that file and try to parse its debug symbols so it can begin debugging
09:14for you notice how it says reading symbols from main if we typed that wrong
09:19if we said you know if we did a typo or we had something with no debug symbols it
09:24will give us some sort of an error message so for now I'm just gonna quit and then
09:28go back in just to make sure that it's all clean and we're gonna do file main now
09:33it attaches once it's attached that's not I guess it's not technically attached
09:37because the program is not running but once it has loaded the debug symbols for
09:42that program we can run the program with the run command in GDB also kind of
09:47interesting if you have debug symbols that are generated separately from your
09:51executable you could tell GDB to load the symbols file and then run your program
09:56that happens a lot in Linux where people release the the non debug friendly
10:02version of a program and then they'll release the debug symbols separately if
10:05you're interested anyway so I'm gonna type run and it'll run the program notice
10:09how GDB kind of tells us that it's starting up now it's like starting the
10:14program and then here's like a thread debugger that's being enabled and it says
10:20we're using this library to do it and then it says hello you know here's the
10:24hello message so the program is actually running that's not my name I wish it was
10:27and then it prints the final result and then GDB says your program exited
10:31normally on newer versions of GDB there's a setting I think by default where it'll
10:35ask you if you want to start a debug daemon a debug info daemon or something
10:41yes or no you can usually just hit enter to skip that without actually having to
10:44type n it's a little bit faster so the whole program ran and finished if I type run
10:50again it does the same thing in GDB if you hit enter without typing anything it
10:55ends up repeating the previous command so I'm not going to type run if I just hit
10:58enter are you serious GDB made me into a liar well most of the commands will
11:04repeat if you hit enter I guess not the run command so I'll type run again and
11:09okay I mean the program is pretty good right so if you if you watch my it's not
11:13pretty good it's a nonsense program I mean it it doesn't crash is what I'm
11:16saying if you watch my previous video which you should on caveman debugging I
11:20had this you know nonsense portion of code that just sort of updated a
11:26variable and we pretended that we were confused and we didn't understand what
11:30was happening and we use GDB to debug it so what I'm gonna do right now is I'm
11:35going to first I'm gonna cause a crash either let's say we'll start off with
11:42throwing an exception and then we'll try to use a no pointer and then we'll see
11:46a crash and then after that I'm gonna start using breakpoints where we can
11:50stop automatically inside of our program to print the state of the program print
11:54the variables and I'm gonna do that first in C++ and then hopefully I'll
11:58remember to do that in assembly right after it's basically the same thing only
12:02with assembly you don't really have you know a bunch of variables everywhere you
12:06just kind of have registers and maybe some globals but it can be the same deal
12:10okay so let's pretend that we are gonna have a crash okay so this program just
12:16kind of runs later on we'll figure out why the result is wrong we'll just pretend
12:21that it's wrong but for now we'll just say how about we uncomment this line
12:25right here and what will happen is when we're running the main loop at some point
12:31in the loop we get F called with a value as an argument when F gets called the
12:38input will be looked at here and if the input is more than one which is
12:40definitely gonna happen like right away then we'll call on the G function then
12:46the G function will just throw an exception we'll just pretend that
12:49something really bad happened you crashed or you actually did throw and you
12:54didn't catch your throw or maybe the system through something at you or another
12:58library through something at you and you didn't catch it so just basically a
13:01program crash let me run this real fast I'm gonna go make run just to show you that
13:06the program crashes make run at this point is the same thing as just kind of
13:11executing the program but you can see that it says terminate called after
13:14throwing an instance of runtime error and then there's the message oh my gosh and
13:19then aborted core dumped that's not good so now let's try to understand why why did
13:26that crash pretend you don't know that it happened in G you know you're trying to
13:30investigate so we could type G to be and then we could type a file to load the
13:35debug symbols but it's a little bit faster just to type G to be main and just
13:40sort of name the file that you want to load right away so if I do that notice how
13:45it automatically tries to lead to load the debug symbols remain then I can just
13:50type run and then the program tries to run and notice how it actually catches the
13:55crash if you look down here terminate called after throwing an instance of
14:01runtime error so that's what the program thinks is going on but then the program
14:04is trying to terminate but then down here GDB is like wait wait wait I just
14:09caught you know a termination getting invoked here and you can see this is sort
14:14of system code like we did not create this source while key thread kill we
14:19didn't write that that's the standard library and there's a function here called
14:22p thread kill implementation with those you know fun C underscore prefixes
14:28everywhere and so this is like some sort of a C source file and we don't have
14:33that file on the system so we can't really debug that file lucky for you most
14:37of these standard libraries work all the time so you don't really need to debug
14:40them you need to debug your code instead of the standard library code so the
14:44question really is how did I get here how did I get to this crash so the next
14:48command we'll learn in GDB is just the where command the where command will give
14:53us an output of the current call stack I'm going to release a video in the
14:57future that kind of explains call stacks but basically imagine a abstract data
15:02type a data structure called a stack and every time you want to add data to the
15:08stack it just sort of stacks up on top of the last piece of data so like if I
15:11add something let's say I want to add the number five then I would just add the
15:15number five on top of the stack right if I wanted to add the number 11 then I
15:19would just add the number of 11 onto the stack and then later you can pop stuff
15:23off of the stack and the stack is a really good data structure to sort of give you
15:30a trail of breadcrumbs to know where you got where did you come from so we call
15:34this the call stack because what's happening is every single time you call a
15:38function then the new scope and then you know the new function that you're
15:42invoking it has something called a call frame full of information about what
15:48local variables it has and like what is return address is and all that stuff and
15:53we'll just call that chunk of data that belongs to one instance of a function
15:58call we'll just call that a call frame and so if you're stacking call frames one
16:02on top of the other then we call that whole entire thing the call stack and this is
16:07what allows us to use recursion and all these complicated call graphs and
16:10everything it's really simple but it's really powerful so you're looking at the
16:14call stack each one of these lines is the call frame or is a call frame and so
16:21for example if you just look at number zero here you're looking at call frame
16:25zero which is the closest frame to wherever the crash occurred which is if
16:29you look at it that's exactly what we were looking at when we saw that original
16:32message right call frame zero so that's not really useful you want to go down to
16:37higher numbered call frames or I guess physically lowered number call frames and
16:42just kind of scan it until you find some code that is actually yours so pthread kill
16:47no raise no abort no none of this stuff is ours live standard C++ no the first
16:54frame that contains code that is ours is call frame number nine or I guess like nine
16:59away from our current position so I guess find the physically highest call frame that
17:04is your code or the lowest numbered call frame that is your code and it's
17:08telling us right here all right we we actually seem to have crashed in our code
17:13at line 65 on main dot CPP so if I go to 65 right there it tells you exactly where
17:19the crash happened if you're still trying to figure out well how did I get to that
17:22crash I don't know how that actually happened just keep looking down further in
17:26the call frames the next one call frame 10 says well we were inside of function
17:30f with input equals 3 at main dot CPP line 46 so if I just go to 46 I can get
17:36another clue I can go all right so for some reason we called G imagine again this
17:41program is much more complicated and then if we're still confused we just look
17:45down at another one and it's like well this all this whole mess started at CPP
17:50main dot CPP line 28 so if we look at line 28 it's like well we were inside of
17:54this loop and we we call the F function and then the F function called the G
17:59function and then G just kind of did a throw so that gives us a lot of
18:04information all right next thing we can do is we can sort of move up and down the
18:08call stack because right now we're sitting at call frame 0 which is just the
18:13system code but maybe we don't understand why the throw actually happened
18:17at let's say line 65 right so we can use up to go up in the call stack
18:24to a different call frame so if I hit up notice how it mentions that we're now in
18:29frame number 1 instead of 0 and if I do up again we're now in frame 2 which is a
18:35little bit closer we can use the trick finally where we hit the enter key
18:38instead of repeating the commands I'm just gonna hit enter a couple times until
18:42we eventually get to our code which I think was supposed to be at frame 9 so I'm
18:46just gonna hit it a bunch of times till we get to frame 9 now we're looking sort of
18:50back in time at that point because all these other frames actually did get
18:54invoked but we don't really care about what was going on inside of them because
18:59they probably did their job correctly we're looking at our code so we're going
19:02back in time right when we were doing this throw oh no we threw why did we
19:07throw well there's another command in GDB called info locals
19:14okay the info locals there's there's really not much to this maybe maybe let
19:22me do this again a equals 5 and then I'll just say a plus plus just so that we
19:28have a local variable I forgot that GDB doesn't consider the incoming arguments as
19:33locals so there was nothing there let me do this one more time real fast
19:36achieving oh let's do make build and then GDB main and then run and then we have a throw and
19:47then I say where and then I go up up up up up to a frame you can also use the keyword down if you go
19:53too far if you want to go you know back down in the call stack but I'm just gonna use up okay so
19:59now we have it here now finally I think I can do info locals just to see the local variables notice
20:04how the a variable is there now because I just added a local variable a a moment ago you can
20:10also print things directly you can say print the input incoming variable if you're in assembly you
20:16can also print registers you can say info registers like that and you'll get a nice print out of all
20:21the registers you could print individual registers you can say let's print register r12 you can print
20:27register register r12 as binary by saying I think it's p slash t or or print slash t yeah we can
20:34probably just do print slash t also t stands for two because they're it's a base two number system
20:40does that mean there's a p slash h or a p slash f for 15 or 16 s for 16 I don't know I haven't tried that
20:50is it going to work hang on p slash s bar 12 it's not going to work nope didn't work I think it thinks
20:57it's a character point or something but anyway so we can print a lot of stuff and like I said before
21:02we can go up and down the call stack so I can go down a couple times and then go back up again
21:06and now we can assume that we've kind of debugged you know where the source of the error was
21:13so I'm going to comment that call out to g and run the program again one more time
21:17with a different error so I've commented this code out from before but just imagine now that we're going
21:23to use some pointers we're going to start off with a pointer called p we're going to set it to null
21:30at the beginning and then we're going to just kind of allocate it and then we're going to set
21:35you know a value and then we're going to dereference it and dereferencing a pointer just kind of sets the
21:39first value in an array you can do that and then we're going to deallocate the pointer and then how
21:46about right after that we do something really really naughty we say p at some index is equal
21:53to a five this should be this should be a program crash because we deallocated p already at that point
22:00we would be dealing with junk data if we tried to dereference p but to make it even more clear
22:05that it's naughty we'll set it to a null pointer and then we'll try to actually use it so let me let
22:12me just restart the program real fast i'm gonna do quit yes and then we'll do make a debug just so
22:19you know my make debug is just a shortcut for uh let's see where's that where's that where's that
22:25do i not have a debug shortcut yet oh dear i need to add that before this video is over you know what
22:31i'll add it right now we'll do this run and we'll say debug make debug and it needs to build first and
22:40then i'll say debugging uh the program and then we will do uh the gdb binary and give it an argument of
22:52the um executable and then later we can uh we can upgrade this to take a little script of commands
22:58because the commands are going to start getting out of control so now if i do make debug if i didn't
23:02screw it up now it at least goes in there and i'll do run and then we have a seg fault and notice how
23:08it tells us right away hey you have a seg fault right here you're accessing invalid memory let's
23:13do info locals just to see what's up oh the p is actually a zero that's a null pointer by print p
23:19again explicitly oh whoops you know oh what have i done but it's a really good idea to set your
23:24pointers to null after you deallocate because if you don't you might end up with undefined behavior
23:30where sometimes the program doesn't crash while you're overriding junk data or reading junk data
23:36but sometimes it does and you're not really sure like why is it work sometimes and why does it
23:40not work sometimes so let me comment this out and see if it'll crash uh let's just let's just double
23:47check this here make debug and then i'll do run and then if we do info locals oh yeah okay so this is uh
23:59it did seg fault so that's good uh if we were unlucky then the program wouldn't have crashed it would
24:04have just started behaving strangely and um when we print out the value of p notice how it looks like
24:11a pointer still like if we were to uh debug the program and print the pointer value before we
24:15deallocated then it doesn't really it looks the same it looks the same after we deallocated it right
24:21so that this is called a dangling pointer meaning you deallocated the pointer but you forgot to set it
24:26to null afterwards so then later when you're trying to debug the program it's a little confusing because
24:30you're like that looks like a regular pointer what did i do wrong so um it's really good practice to
24:36set your pointers to null right after you deallocate them that way when you're debugging later because
24:41something crashed instead of seeing a memory location on p you'll see something that looks
24:46definitely like a null pointer and um print p then it's way easier to realize oh whoops i was trying to
24:55use a dead pointer a pointer that id allocated hopefully that makes sense so far next thing i
25:01want to do is a small upgrade i can't remember if it's dash x or dash ex i think it's dash x but uh
25:09you can write a little script i have a little script here called good doggo you can just make any
25:14file name it anything you want i'm so i'm just naming it good doggo.txt because my dog's
25:19taking a little nap behind me as usual um but you could name this gdb.txt or whatever it is you want
25:27so you can put inside of this uh script file any command that you want gdb to execute uh when it
25:34launches so uh let's just comment this stuff out real fast and i'll do i'll just do run maybe for
25:41starters because whenever i've been launching for debug i launch with gdb and then i type run manually
25:49right so i want to save a little time so good doggo is the name of the script so when i invoke gdb
25:56i am going to where is it right there okay it's gdb and then i'm going to go dot i think it's x
26:04and then i'm going to say good doggo dot txt if it's not dash x then it's dash ex one of those executes
26:11the command that comes after and one of those executes the command script that comes after let
26:16me just double check that this actually is going to work so make debug all right okay so it was dash
26:22x dash x specifies a script that will be run dash ex just specifies a command that you can put right
26:29in there like i could have said dash ex run and it would have ran right away but the script is more
26:34convenient right because we can save typing so notice how it ran right away and then there's a seg fault
26:39okay so now let's go a little bit deeper let's change this to false again now that we understand
26:47like null pointers and all that stuff so we can just basically deal a little bit more with only
26:52what the main loop is doing suppose we just still don't really understand what the loop is doing
26:57why our answer is you know you know good or bad so maybe i want to do a break point at the top of
27:02that for loop every time the for loop gets to the top of its iteration i want the program to pause
27:08so i can look around so i'm going to set up a break point on line 22 and here's how you set up
27:13break points in gdb i'm going to go ahead and maybe do the terminal for now and then i'll stick that into
27:18the script next i will not remember that it's line 22 that's okay i'm going to do quit and i'm going to
27:25do make build then i'm going to go gdb main just to you know jump in there and then i'm going to say
27:32break or just the the letter b just to make a break point you type the name of the source code
27:38file that you want to uh break in and then a colon and then the line number where you want it to break
27:44so i think i think it actually was line 22 oh i can see it and then maybe i want to have it break at
27:51line i don't know maybe right here line 25 right before it increases a so i'll say let's break at line 25
28:00and then so i'm going to do an up arrow to just repeat the command so i can edit it real fast
28:06and then i'll break again at line 28 and then maybe 30 and then 32 so i'm going to go 28 30 and 32
28:1530 and i'm just making up break points i just want to inspect the program and then maybe i'll break at
28:20line 36 so i can see what the final answer is so i just have a bunch of break points set up
28:24remember when the program is running now under gdb every time it hits one of those lines
28:30the program will pause and i'll have a chance to look around at the variables and things so
28:35i'm not sure if i've set up the break points correctly i can say info break points
28:40and it'll show me all of my break points notice how you can enable them and disable them
28:45so let's say for the sake of argument i want to disable the break point at line 30 because maybe i don't
28:50really need that right now but i kind of want to keep it in the system for later or it's just it's
28:54just running too many times i can say disable four because it's number four it's break point number four
28:59so i can say disable four then if i do uh info break points again notice how there's a little
29:06n on there meaning break point four is disabled so i could re-enable it with a four
29:12and then go info break points again so now they're all enabled
29:14um i am going to maybe copy this into the script file real fast so i don't have to keep top typing
29:22this over and over and over again imagine if every single time you changed your program and recompiled
29:27it you had to type all of the break points from scratch that's why i want you to use this little
29:31breakpoint script so we're going to do b to break at main.cpp line 22 and 25 and 28 and 30 and 32
29:44should have copy pasted the three dang it 36 and after we're done setting up all the breakpoints
29:50then i want gdb to just show me the breakpoints just so i can have a visual reminder keep in mind
29:56if you change too much of your source code then you're probably going to have to update these lines
30:00and that's okay but uh it's a good idea to just at least you know kind of look at them a little bit
30:04so that's why i'm saying info breakpoints and so then remember again the make file all it's doing when
30:12i type uh make debug is it's just launching this command right here it's just saying gdb with the
30:17name of my executable and then dash x and then the name of my gdb script so let me quit to get out
30:25of this and then i'm going to say clear and make debug and notice how it did all that stuff for me it
30:33added the breakpoints it showed me the breakpoints and then it ran the program like i told it to and
30:39then it already broke on a breakpoint it already break it break breakened it's broken i don't know
30:46i don't think it's broken uh so we're on breakpoint number one on line 22 and here's the for loop i can
30:52type all of my inspection stuff i can say info locals i can say print i i can say print a i can print whatever
31:00i want uh and then when i'm done kind of looking around and inspecting things i want to continue the
31:07program i don't want to just stop it here so i'm just going to use the command continue
31:11and it goes right to the next breakpoint if i want to uh you know continue again i can hit c or i can
31:18just hit enter you know to just sort of keep continuing as i inspect and print things let's
31:24see when when can i get to breakpoint number one is that what's going on here hang on a second
31:32what is breakpoint number one oh i know what to do info breakpoints
31:37breakpoint number one is that main dot cpp line 22 is that actually going to get hit oh it's always
31:41on top that's what's happening having it having issues here with my gui okay line 22 okay so it's
31:50not really hitting that anymore um i guess it's not gonna think that it hits the top of the forelip
31:57okay so i guess breakpoint two is where we're always going to be hitting so let's just suppose
32:01that i'm continuing until i hit breakpoint number two suppose that the next 10 times i see breakpoint
32:07two i don't actually want to stop and break on it i just want to skip the next 10 iterations for some
32:12reason you can say continue 10 and it'll skip the next 10 times that it hits the number two notice how
32:19if i hit continue a bunch of times we're not really seeing the breakpoint number two anymore we're
32:24seeing other breakpoints and then eventually if i hit it enough times we'll probably see two again
32:31oh my god oh my god are we seeing it yet no
32:39okay wait are we seeing i'm freaking myself out okay so let's continue uh 10 times on breakpoint three
32:48then we'll only see breakpoint four i guess so we can do continue 10 times on breakpoint four
32:56what is going on here did i write this program in a weird way
33:03well trust me on this let's continue a hundred on breakpoint three and then continue a hundred on
33:08breakpoint four okay so now we're just done with the whole entire program i guess there must have been
33:15a two there that i missed so now we're finally on breakpoint six which is when everything is
33:20finished let me show you real fast that we can add more breakpoints in assembly just to prove that we
33:25can debug assembly real fast so if i want to debug assembly i just have to type the name of that source
33:31code file if it was nested in a folder like if you had like a complicated hierarchy of source code files
33:37you would just need to type the relative path but for now i'm just going to be able to type
33:40the name of the file so assi.asm and let's suppose that i want to uh break at line 16 just so i can
33:47see the registers that i set up so i'm going to do 16 and then i'm going to break at assi.asm
33:57line 16 and then i'm going to run and um that actually never gets called does it no no it gets
34:05called i think i have a call up here somewhere nope i don't have a call okay let's make a call
34:10this is going to throw off all of my c++ breakpoints so i'll just comment them all out right now
34:15comment them all out so i don't have to redo them and uh this is a hybrid program so i'm going to go
34:22uh extern what is it extern c make a block where i name the function the reason we do this is so that
34:29uh c++ does not expect name mangling uh so the assi uh symbol is going to show up as just its regular
34:39function name rather than a bunch of extra stuff indicating the prototype so that we can do
34:43overloading so we're just going to disable that and then at the very top of the program i'm just going
34:48to call it this should hopefully work let me just do a regular make run just to make sure the whole
34:55program compiles okay now let's do make debug and inside of the debug script we're going to break
35:02on line 16 which is going to be letting us see the registers okay so i'm going to go make debug
35:08notice how it hit the breakpoint in the assembly just the same as the c++ and we can print whatever
35:14we want now so i'm just going to say info registers and if we look carefully we can kind of see
35:19that we modified rex rex is 15 so that's expected rdi is 20 which is expected r12 should be a giant
35:30number where's r12 right there so you can see the state of your program at any point in time just by
35:35breaking on it on breaking on a certain line so this is tremendously useful for debugging not just for
35:41higher level languages but also assembly what else can i do oh let's put a global in the data section so
35:46i'm going to do i don't know my thing or something like that and we'll call it a byte array and i'll
35:53just go hello and then maybe i'll say we have a thing one and a thing two
36:00something like that and uh maybe thing two is a null terminated string whereas thing one is a
36:07regular thing we should be able to print those symbols if i if that's not true i'll come back at
36:12a later time and show you how to do it anyway so we'll do make debug to just kind of assemble everything
36:16again and we know how to do info registers we can print you know one register in particular
36:21print r12 if we wanted to history has not reached 12 oh i gotta put r12 yeah then we can get the wait
36:29a minute wait a minute oh i uh i threw off the line numbers because i added the variables up here so
36:36now we're going to break at 21 let me just fix that 21 we'll do a quit make debug again and now we're at
36:4621 if i say info registers we can see r12 is that big value but we can also print r12 directly
36:55and we should be able to print my thing one hopefully has an unknown type oh we have to cast it
37:04so we can do like basic casting in gdb so i'm going to say this is a character pointer
37:09remember all of the assembly symbols are basically pointers unless it's a eq eq variable in that case
37:16it's more of a define so i'm going to print character pointer my thing one and then it says error cannot
37:22access the memory add address what the heck did i do wrong how about that cannot access that all right
37:32i'll come back in another video because this wasn't something that i prepared for just to print strings
37:36in globals i'll come back at some later date in the future like five years from now and i'll just
37:41show you how to print globals but i hope if you're in assembly you probably don't need to worry about
37:46printing globals you just have globals but the real problem for you is going to be what's inside of
37:52your registers and and so forth we could also dereferent like ref i think let me see
38:01hmm
38:04now okay i'm going to move i'm going to move on from that so anyway we got a script
38:09and we got a lot of basic gdb commands is there anything else that i wanted to show you
38:13let me just look at my notes real fast here to make sure i'm not forgetting to say anything so we're
38:18going to do debug symbols console quit attach to binary launching the program uncaught exception
38:24breakpoints info delete enable disable run continue end times info registers printing oh we can print a
38:32register in binary forgot to show that so we are at a breakpoint i think and if we printed r12
38:39with the regular print we can also do p slash t to just sort of print it in binary
38:47if you want to i think i might have said that already either that or i said that like a couple
38:52days ago to someone and then we can do info locals and then print a variable and then we get the script
38:56file and then we can quit okay so i think this is pretty much everything that i wanted to show you
39:01you now have a basic idea of what we can do inside of gdb but keep in mind there is so much more you can
39:08do in gdb than i can fit in one video if you're interested you can type help and you can see a
39:13list of other major you know areas that gdb can handle you can do let's see i think it's help and then
39:23like we've got information on aliases breakpoints data you know whatever we can do i think help
39:28breakpoints to see more information on breakpoint commands yeah so all of the things you can do with
39:35breakpoints is like all of these commands here there are so many commands that they don't fit
39:39on one page we have to enter to see one more page or c to see all of the results without using paging
39:48anymore so i'm just hit c and so there's like you know we can save trace points we can try to catch
39:53exceptions we can enable disable breakpoints there's like unwinders which i've never even used
39:59we can bookmark things uh we can you know start tracing memory we can rethrow there's like so many
40:06things we can do manipulate variables uh so just keep in mind gdb is incredibly powerful this video
40:13barely scratches the surface but uh for a programmer who is new to debugging i think this will be very
40:19useful to you i hope it is anyway thanks for watching this video i hope you learned a little bit
40:24of stuff and had a little bit of fun um i will see you in the next video rest yourself and take a nap and
40:32have fun for a little while and and have a sandwich and hug your your loved ones
40:38okay i'm out see you later
40:50hey everybody thanks for watching this video again from the bottom of my heart i really appreciate it
40:55i do hope you did learn something and have some fun uh if you could do me a please a small little favor
41:00could you please subscribe and follow this channel or these videos or whatever it is you do on the current
41:07social media website that you're looking at right now it would really mean the world to me and it'll
41:11help make more videos and grow this community so we'll be able to do more videos longer videos better
41:17videos or just i'll be able to keep making videos in general so please do do me a kindness and uh and
41:24subscribe you know sometimes i'm sleeping in the middle of the night and i just wake up because i know
41:28somebody subscribed or followed it just wakes me up and i get filled with joy that's exactly what happens
41:33every single time so you could do it as a nice favor to me or you could you could troll me if you want
41:37to just wake me up in the middle of the night just subscribe and then i'll i'll just wake up i promise
41:42that's what will happen also uh if you look at the middle of the screen right now you should see a qr
41:47code which you can scan in order to go to the website which i think is also named somewhere at the
41:52bottom of this video and it'll take you to my main website where you can just kind of like see
41:57all the videos i published and the services and tutorials and things that i offer and all that good
42:01stuff and uh if you have a suggestion for uh uh clarifications or errata or just future videos
42:10that you want to see please leave a comment or if you just want to say hey what's up what's going on
42:15you know just send me a comment whatever i also wake up for those in the middle of the night i get
42:19i wake up in a cold sweat and i'm like it would really it really mean the world to me i would really
42:25appreciate it so again thank you so much for watching this video and um enjoy the cool music
42:32as as i fade into the darkness which is coming for us all
42:55so
43:02so
43:04so
43:08so

Recommended