CS/COE 0449 term 2174 Lab 5: gdb

Similar documents
1. Allowed you to see the value of one or more variables, or 2. Indicated where you were in the execution of a program

CSE 410: Systems Programming

CS354 gdb Tutorial Written by Chris Feilbach

ECE/ME/EMA/CS 759 High Performance Computing for Engineering Applications

GDB Tutorial. A Walkthrough with Examples. CMSC Spring Last modified March 22, GDB Tutorial

CSE 351. GDB Introduction

Programming Tips for CS758/858

CMPSC 311- Introduction to Systems Programming Module: Debugging

Reviewing gcc, make, gdb, and Linux Editors 1

CMPSC 311- Introduction to Systems Programming Module: Debugging

CSE 351 Section 4 GDB and x86-64 Assembly Hi there! Welcome back to section, we re happy that you re here

Exercise Session 6 Computer Architecture and Systems Programming

Scientific Programming in C IX. Debugging

Using a debugger. Segmentation fault? GDB to the rescue!

Laboratory 1 Semester 1 11/12

CSE 374 Programming Concepts & Tools. Brandon Myers Winter 2015 Lecture 11 gdb and Debugging (Thanks to Hal Perkins)

mp2 Warmup Instructions (Updated 1/25/2016 by Ron Cheung for using VMs)

18-600: Recitation #3

The Dynamic Debugger gdb

CNIT 127: Exploit Development. Ch 2: Stack Overflows in Linux

Programming Studio #9 ECE 190

The First Real Bug. gdb. Computer Organization I McQuain

CSE 374 Programming Concepts & Tools

Recitation: Bomb Lab. September 17 th 2018

ECE 3210 Laboratory 1: Develop an Assembly Program

Basic functions of a debugger

CMSC Lecture 03. UMBC, CMSC313, Richard Chang

CS 270 Systems Programming. Debugging Tools. CS 270: Systems Programming. Instructor: Raphael Finkel

Using gdb to find the point of failure

We first learn one useful option of gcc. Copy the following C source file to your

Code Review and Debugging (Lab 05)

CSCI0330 Intro Computer Systems Doeppner. Lab 02 - Tools Lab. Due: Sunday, September 23, 2018 at 6:00 PM. 1 Introduction 0.

Lab 8. Follow along with your TA as they demo GDB. Make sure you understand all of the commands, how and when to use them.

Source level debugging. October 18, 2016

Princeton University COS 217: Introduction to Programming Systems GDB Tutorial and Reference for x86-64 Assembly Language

Debug for GDB Users. Action Description Debug GDB $debug <program> <args> >create <program> <args>

LAB #8. Last Survey, I promise!!! Please fill out this really quick survey about paired programming and information about your declared major and CS.

Program Design: Using the Debugger

Jackson State University Department of Computer Science CSC / Advanced Information Security Spring 2013 Lab Project # 5

LAB #8. GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:

Binghamton University. CS-220 Spring C Debugging Basics. No relevant text

The NetBeans IDE is a big file --- a minimum of around 30 MB. After you have downloaded the file, simply execute the file to install the software.

Binghamton University. CS-220 Spring X86 Debug. Computer Systems Section 3.11

Princeton University COS 217: Introduction to Programming Systems GDB Tutorial and Reference

Outline. Computer programming. Debugging. What is it. Debugging. Hints. Debugging

GDB Linux GNU Linux Distribution. gdb gcc g++ -g gdb EB_01.cpp

GDB Tutorial. Young W. Lim Tue. Young W. Lim GDB Tutorial Tue 1 / 32

PROGRAMMAZIONE I A.A. 2017/2018

CS 105 Lab 2: Debugger Playing with X86-64 Assembly

Digital Design and Computer Architecture Harris and Harris, J. Spjut Elsevier, 2007

Data and File Structures Laboratory

Blue Gene/Q User Workshop. Debugging

Chapter 1 Getting Started

CS 161 Computer Security. Week of January 22, 2018: GDB and x86 assembly

Problem Set 1: Unix Commands 1

Buffer-Overflow Attacks on the Stack

Debugging. ICS312 Machine-Level and Systems Programming. Henri Casanova

Laboratory Assignment #4 Debugging in Eclipse CDT 1

EE 355 Lab 3 - Algorithms & Control Structures

Exploits and gdb. Tutorial 5

gdbtui - Linux Command

U Reverse Engineering

Mitchell Adair January, 2014

Binghamton University. CS-220 Spring X86 Debug. Computer Systems Section 3.11

Using the Debugger. Michael Jantz Dr. Prasad Kulkarni

Using the GNU Debugger

Lab 10: Introduction to x86 Assembly

Introduction to the Command line. Introduction to the command line. Introduction to the Command line. GNU/Linux at South Wales

CS2: Debugging in Java

a translator to convert your AST representation to a TAC intermediate representation; and

Lab 03 - x86-64: atoi

Using the GNU Debugger

1. A student is testing an implementation of a C function; when compiled with gcc, the following x86-32 assembly code is produced:

Practical Malware Analysis

1 Basic functions of a debugger

Under the Debug menu, there are two menu items for executing your code: the Start (F5) option and the

SGI Altix Getting Correct Code Reiner Vogelsang SGI GmbH

Learning Objectives. A Meta Comment. Exercise 1. Contents. From CS61Wiki

Debugging uclinux on Coldfire

Intro x86 Part 3: Linux Tools & Analysis

C++ for Everyone, 2e, Cay Horstmann, Copyright 2012 John Wiley and Sons, Inc. All rights reserved. Using a Debugger WE5.

SU 2017 May 18/23 LAB 3 Bitwise operations, Program structures, Functions (pass-by-value), local vs. global variables. Debuggers

General Debugging Strategies

Unix and C Program Development SEEM

Lecture 07 Debugging Programs with GDB

CS 105 Lab 2: Debugger Playing with X86-64 Assembly

Buffer-Overflow Attacks on the Stack

Reversing. Time to get with the program

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division. P. N. Hilfinger.

Lab 1 Introduction to UNIX and C

12. Debugging. Overview. COMP1917: Computing 1. Developing Programs. The Programming Cycle. Programming cycle. Do-it-yourself debugging

Software Development With Emacs: The Edit-Compile-Debug Cycle

Lab6 GDB debugging. Conventions. Department of Computer Science and Information Engineering National Taiwan University

CSE 351: Week 4. Tom Bergan, TA

Debugging. John Lockman Texas Advanced Computing Center

You can also start with both an executable program and a core file specified:

CS 261 Fall Machine and Assembly Code. Data Movement and Arithmetic. Mike Lam, Professor

buffer overflow exploitation

Section 2: Developer tools and you. Alex Mariakakis (staff-wide)

Putting the pieces together

Transcription:

CS/COE 0449 term 2174 Lab 5: gdb What is a debugger? A debugger is a program that helps you find logical mistakes in your programs by running them in a controlled way. Undoubtedly by this point in your programming life, you ve had a program or two that just didn t behave in the way you expected it to. Perhaps when this happened, you went and added some print statements to your program, recompiled it, and then ran it. Those print statements probably: 1. Allowed you to see the value of one or more variables, or 2. Indicated where you were in the execution of a program or possibly both. A debugger is a more sophisticated tool that helps you do both of these tasks without having to edit your source code and recompile. How does a debugger work? The most important operation that a debugger provides is the ability to insert a breakpoint into a program. A breakpoint is a special trigger that, when program execution reaches a specified point, allows the debugger to pause your program and to take control. With the program paused, you now can do various operations that query the state of the running program, such as print out the value of the variables or see a backtrace of the function calls that led to where the program paused. What debugger will we use? Many IDEs and programming environments provide some interface to a debugger, usually integrated with the code editor. On Linux however, we ll be using a command line debugger called gdb (the GNU debugger). How does gdb work? By default, the programs that we produce with gcc are not very conducive to being debugged. As part of the compilation process, things like most of our variable names, the name of the source file, and the line numbers therein are thrown away, since they serve no purpose to the CPU. To get around this problem, we can tell gcc to compile our program to better support being run under a debugger. We do this by specifying the -g option: gcc -g -o executable_name source_code.c Because of the extra information embedded into the program by gcc, most of the programs you will get from other people do not contain this extra debugging information. But as long as you have the source code, you can always produce a debug version yourself.

To invoke gdb on our executable, we simply say: gdb executable_name and on thoth, we ll be greeted with a message and then a prompt to type a command: (37) thoth $ gdb executable_name GNU gdb (GDB) Red Hat Enterprise Linux (7.2-56.el6) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. (gdb) Commands in gdb Here are some commonly used commands in gdb. You can learn more about all of the commands by typing help, or on a specific command by typing help command_name. Command Shortcut Description help Get help on a command or topic set args Set command-line arguments run r Run (or restart) a program quit q Exit gdb break b Place a breakpoint at a given location continue c Continue running the program after hitting a breakpoint backtrace bt, back Show the function call stack where Same as backtrace next n Go to the next line of source code without entering a function call step s Go to the next line of source code, possibly entering a new function nexti ni Go to the next instruction without entering a function call stepi si Go to the next instruction, possibly entering a new function print Display the value of an expression written in C notation x Examine the contents of a memory location (pointer) list l List the source code of the program disassemble disas List the machine code of the program

Example Login to thoth.cs.pitt.edu via ssh or PuTTY. Change to your private directory and make a directory called gdb_lab. Go into that directory and issue the command: cp ~jfb42/public/gdbdemo.c. (That period at the end represents the current directory, i.e., the destination of the copy.) Take a look at the contents of gdbdemo.c using pico or your favorite text editor. You might notice that there are some errors in the program that wouldn t be caught using the compiler only. Compile it and run it to see the result: (23) thoth $ gcc -o gdbdemo gdbdemo.c (24) thoth $./gdbdemo Segmentation fault (core dumped) That means the program has crashed. Let s recompile with debugging support and see if gdb can help us: (25) thoth $ gcc -g -o gdbdemo gdbdemo.c (26) thoth $ gdb gdbdemo At the (gdb) prompt, we simply want to run the program, so type run or r then enter, and you ll be prompted to enter the number as if you had run the program normally. If you enter 3 as we did before, you ll see: (gdb) r Starting program: /afs/pitt.edu/home/j/f/jfb42/private/gdb_lab/gdbdemo Program received signal SIGSEGV, Segmentation fault. 0x0000003ec1d5080f in _IO_vfscanf_internal () from /lib64/tls/libc.so.6 Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6_5.3.x86_64 (You can ignore the "Missing separate debuginfos" message. It has to do with the fact that this program is using a shared library.) gdb is telling us where the program crashed, but it is an odd function name. We see the scanf part and might assume that it s a problem with our input, but to be sure, let s find out by asking for a backtrace: (gdb) back #0 0x0000003ec1d5080f in _IO_vfscanf_internal () from /lib64/tls/libc.so.6 #1 0x0000003ec1d5884a in scanf () from /lib64/tls/libc.so.6 #2 0x0000000000400521 in main () at gdbdemo.c:11 This is the equivalent of a stack dump when we get an exception in Java. It turns out we were right, it s from our call to scanf, which occurs in main() at line 11 of gdbdemo.c (the number after the colon is the line number). Let s find out what s at line 11 by using the list command:

(gdb) list gdbdemo.c:11 6 { 7 int x; 8 char c[30]; 9 10 printf("enter a number: "); 11 scanf("%d",x); 12 13 fun(); 14 15 return 0; Oh, how silly, I forgot the ampersand on the variable x. Quit gdb by issuing the quit command, edit the ampersand in (&x) and recompile the program. Run it. (gdb) quit The program is running. Exit anyway? (y or n) y (27) thoth $ pico gdbdemo.c (28) thoth $ gcc -g -o gdbdemo gdbdemo.c (29) thoth $./gdbdemo Floating point exception Uh oh, it crashed again. Let s run it through gdb and see what happens: (gdb) run Starting program: /afs/pitt.edu/home/j/f/jfb42/private/gdb_lab/gdbdemo Program received signal SIGFPE, Arithmetic exception. 0x000000000040055b in fun () at gdbdemo.c:25 25 c = a / b; Hmm, it seems that it is crashing at line 25, with the expression c=a/b. One thing the debugging info includes is the names of local variables. Let s print out the values of these three variables to see why: (gdb) print c $1 = 0 (gdb) print a $2 = 5 (gdb) print b $3 = 0 Oh, I m dividing by zero. I wonder how that is happening. I see that I m in the function fun() since gdb told me that when it crashed. (I could also discover it via the backtrace command). I now would like to trace through the function to see how b gets set to zero. I can do this by placing a breakpoint at the function fun() so that execution stops whenever the function is called. I do this with the break or b command:

(gdb) break fun Breakpoint 1 at 0x40053b: file gdbdemo.c, line 20. I can also specify specific line numbers to stop at such as gdbdemo.c:20. We should restart the program by typing run again and enter our input when prompted: (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /afs/pitt.edu/home/j/f/jfb42/private/gdb_lab/gdbdemo Breakpoint 1, fun () at gdbdemo.c:20 20 int a = 5; Our program has now paused before the statement at line 20 as displayed here. Let s type n to go to the next line: (gdb) n 21 int b = 0; And there, we find the culprit, a simple initialization statement. We can allow the program to resume with the c command (short for continue) and as we expect, it crashes: (gdb) c Continuing. Program received signal SIGFPE, Arithmetic exception. 0x000000000040055b in fun () at gdbdemo.c:25 25 c = a / b; If we d like, we now know where to fix our program to avoid this crash. Recap When we find a program with a bug, we can interactively debug it using a program like gdb. We needed to compile it specially with the -g option to get the extra debug information included in the executable. Once we did that, we could run the program through gdb. gdb provides a variety of commands to help us determine the value of variables and the flow of execution. We examined only a few of the essential commands such as print, break, run, next, and continue.

Looking under the hood If you weren't around in class on Thursday, follow these steps: 1. Open a file in pico like so: pico ~/.gdbinit (the ~ is shorthand for your home directory.) 2. In the file, type this: set disassembly-flavor intel 3. Save the file and exit. This will use the far more readable Intel disassembly syntax in gdb. (Unless you prefer the AT&T syntax. In which case I ask: what is wrong with you?) To get more comfortable with the way the program looks in machine code, try compiling it with the options: gcc -g -m32 -o gdbdemo gdbdemo.c The -m32 option will compile it as a 32-bit x86 executable. If you forget that, it'll make a 64-bit executable, and when you disassemble you'll see all kinds of weird registers like rax and xmm0 and who knows what. Set breakpoints on main and fun, and when the breakpoint is hit, use disas /m (there's a space between disas and /m) to see what the disassembly looks like. Notice what the division in fun turns into kinda weird, right? It's because the idiv instruction operates implicitly on registers eax and edx: edx is treated as the high 32 bits of the number to be divided, and eax as the low 32 bits. These two registers are treated as a 64-bit pair called edx:eax. The stuff with mov edx, eax and sar edx, 0x1f is actually sign-extending the divisor into the upper 32 bits of that 64-bit pair. Finally, idiv divides that 64-bit number by its single operand. Very weird. Lots of x86 instructions operate on registers implicitly like this. It's best to have a good instruction reference on hand, like this official Intel document. Chapter 3 has a listing of all the hundreds of instructions in IA-32. You can ignore any references to AX or "segment selectors" or anything like that. Just focus on the stuff that talks about EAX and such. For further study In the class textbook available in PDF form online, there are two appendices. Appendix A goes into some more detail about x86. Appendix B is devoted to giving you a better understanding of what gdb provides for us. Additionally, in the references, there is a link to the gdb manual. Be aware your new project will focus heavily on using gdb and that for all future problems that your programs have, we expect you to have spent some time and effort to debug them yourselves before you email or stop by office hours. We re still happy to help you if you don t understand what gdb is telling you. What to turn in Nnnnnnnnothing! Go work on project 2.