CptS 360 (System Programming) Unit 4: Debugging

Similar documents
valgrind overview: runtime memory checker and a bit more What can we do with it?

CS2141 Software Development using C/C++ Debugging

Valgrind. Philip Blakely. Laboratory for Scientific Computing, University of Cambridge. Philip Blakely (LSC) Valgrind 1 / 21

The Valgrind Memory Checker. (i.e., Your best friend.)

DEBUGGING: DYNAMIC PROGRAM ANALYSIS

The Valgrind Memory Checker. (i.e., Your best friend.)

CS61, Fall 2012 Section 2 Notes

Data and File Structures Laboratory

Praktische Aspekte der Informatik

CS 31: Intro to Systems Pointers and Memory. Martin Gagne Swarthmore College February 16, 2016

Use Dynamic Analysis Tools on Linux

CSCI-243 Exam 1 Review February 22, 2015 Presented by the RIT Computer Science Community

Computer Labs: Debugging

Debugging and Profiling

Memory Analysis tools

CSci 4061 Introduction to Operating Systems. Programs in C/Unix

COSC Software Engineering. Lecture 16: Managing Memory Managers

Memory Allocation in C C Programming and Software Tools. N.C. State Department of Computer Science

Recitation: Cache Lab & C

6.S096: Introduction to C/C++

Debugging with gdb and valgrind

Profilers and Debuggers. Introductory Material. One-Slide Summary

Agenda. Peer Instruction Question 1. Peer Instruction Answer 1. Peer Instruction Question 2 6/22/2011

Debugging (Part 2) 1

Embedded Software TI2726 B. 3. C tools. Koen Langendoen. Embedded Software Group

High-performance computing and programming Intro to C on Unix/Linux. Uppsala universitet

Software Analysis Tools

Computer Labs: Debugging

Understanding the Program Run

Massif-Visualizer. Memory Profiling UI. Milian Wolff Desktop Summit

Lecture 14 Notes. Brent Edmunds

CS 137 Part 5. Pointers, Arrays, Malloc, Variable Sized Arrays, Vectors. October 25th, 2017

CMPSC 311- Introduction to Systems Programming Module: Debugging

Hacking in C. Memory layout. Radboud University, Nijmegen, The Netherlands. Spring 2018

Class Information ANNOUCEMENTS

Princeton University Computer Science 217: Introduction to Programming Systems. Data Structures

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

CSE 160 Discussion Section. Winter 2017 Week 3

CS 31: Intro to Systems Pointers and Memory. Kevin Webb Swarthmore College October 2, 2018

Scientific Programming in C IX. Debugging

When you add a number to a pointer, that number is added, but first it is multiplied by the sizeof the type the pointer points to.

CSE 333 Midterm Exam Sample Solution 7/28/14

Outline. Lecture 1 C primer What we will cover. If-statements and blocks in Python and C. Operators in Python and C

From Java to C. Thanks to Randal E. Bryant and David R. O'Hallaron (Carnegie-Mellon University) for providing the basis for these slides

CMPSC 311- Introduction to Systems Programming Module: Debugging

Debugging. Marcelo Ponce SciNet HPC Consortium University of Toronto. July 15, /41 Ontario HPC Summerschool 2016 Central Edition: Toronto

Kurt Schmidt. October 30, 2018

TI2725-C, C programming lab, course

System Assertions. Andreas Zeller

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

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

ICHEC. Using Valgrind. Using Valgrind :: detecting memory errors. Introduction. Program Compilation TECHNICAL REPORT

Intermediate Programming, Spring 2017*

PRINCIPLES OF OPERATING SYSTEMS

Testing and Debugging C Programming and Software Tools. N.C. State Department of Computer Science

Figure 1: 128-bit registers introduced by SSE. 128 bits. xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7

In Java we have the keyword null, which is the value of an uninitialized reference type

A Novel Approach to Explain the Detection of Memory Errors and Execution on Different Application Using Dr Memory.

Exception Namespaces C Interoperability Templates. More C++ David Chisnall. March 17, 2011

Processes. Johan Montelius KTH

A process. the stack

Array Initialization

Systems software design. Software build configurations; Debugging, profiling & Quality Assurance tools

Lecture 07 Debugging Programs with GDB

just a ((somewhat) safer) dialect.

o Code, executable, and process o Main memory vs. virtual memory

Pointers. Héctor Menéndez 1. November 28, AIDA Research Group Computer Science Department Universidad Autónoma de Madrid.

Understanding Pointers

Debugging. Erwan Demairy Dream

CS 326 Operating Systems C Programming. Greg Benson Department of Computer Science University of San Francisco

Memory and C/C++ modules

CS201: Lab #4 Writing a Dynamic Storage Allocator

Computer Systems and Networks

CSE2301. Introduction

Core dumped - on debuggers and other tools

ANITA S SUPER AWESOME RECITATION SLIDES

Programming Tips for CS758/858

CMSC 341 Lecture 2 Dynamic Memory and Pointers

Language Translation. Compilation vs. interpretation. Compilation diagram. Step 1: compile. Step 2: run. compiler. Compiled program. program.

Dynamic memory allocation (malloc)

CS 11 C track: lecture 5

CS C Primer. Tyler Szepesi. January 16, 2013

Cache Profiling with Callgrind

Lecture 8 Dynamic Memory Allocation

HW1 due Monday by 9:30am Assignment online, submission details to come

PROJECT 2 - MEMORY ALLOCATOR Computer Systems Principles. October 1, 2010

0/41. Isolating Infections. Andreas Zeller. Lehrstuhl Softwaretechnik Universität des Saarlandes, Saarbrücken

Creating a String Data Type in C

Two s Complement Review. Two s Complement Review. Agenda. Agenda 6/21/2011

Debugging with GDB and DDT

Performance Measurement

C Review. MaxMSP Developers Workshop Summer 2009 CNMAT

Final CSE 131B Spring 2004

Program Debugging. David Newman (from Tom Logan Slides from Ed Kornkven)

Using the Debugger. Michael Jantz Dr. Prasad Kulkarni

Memory management. Johan Montelius KTH

Programming in C First meeting

MPATE-GE 2618: C Programming for Music Technology. Unit 4.1

System Assertions. Your Submissions. Oral Exams FEBRUARY FEBRUARY FEBRUARY

Last week. Data on the stack is allocated automatically when we do a function call, and removed when we return

Transcription:

CptS 360 (System Programming) Unit 4: Debugging Bob Lewis School of Engineering and Applied Sciences Washington State University Spring, 2018

Motivation You re probably going to spend most of your code development time debugging. You need to know several different strategies to debug code. Debugging is part art, part detective work.

Reference $ info gdb (Be sure the gdb-doc package is installed.) $ info ddd (Be sure the ddd-doc package is installed.)

Phases of Debugging testing Does a bug exist? stabilization Is the bugs consistently repeatable? localization What component (executable - module - function - line) is causing the bug? correction What are the possible fixes for the bug? Which one is best? verification Did the fix really work? retrospective Is there any other part of this program where I might have made the same mistake?

Design for Debugging Getting a core dump Be sure to set $ ulimit -c unlimited so you can get a core dump. ^\ will force a core dump from a program, if core dumping is enabled. $ gcore <pid>, where <pid> is a process id, will get a core dump of that process. Use file(1) to identify core files.

Dealing with Errors Name some errors that your program can detect.

How should your code indicate an error? Alternatives: 1. Do nothing. What will this lead to? 2. Print an error message (where?) and call exit(3). (With what argument?) 3. Print an error message and call abort(3). (With no argument.) 4. Return an error code to its caller... 4.1 As the function return. 4.2 In a global variable. 4.3 In a pointed-at argument. 5. Raise an exception (in C? maybe...).

Assertions #include <assert.h>... assert(n > 0); study header to see clever example of cpp(1) use stops program and dumps core (for perusal by gdb(1)). disabled by -DNDEBUG.

Simple Debugging Approaches Inspection: Look at the code Easy, when it works. Instrumentation printf() is crude, but effective especially when used with...

Scaffolding Traditional: #ifdef NDEBUG... // ignored if -DNDEBUG is on make command line #endif assert() invocations are also ignored for -DNDEBUG. I like this better: #if 0 // set to 1 to revert to old code... // old code #else... // old code with debugging *or* new, improved code #endif Note how you can enable/disable whole blocks of code by changing one character, or use a #define to group blocks. These are better (and more couth) than commenting out code, as comments are unnestable. They re also easy to remove.

gdb(1): The GNU Debugger How does it work? GUI wrappers: ddd(1) data display debugger kdbg(1) KDE version (others, including many IDEs) demo

gdb Commands help info run backtrace (or where) print expression display list line function break line function [condition] continue tbreak line function [condition] display expression Command can be abbreviated to shortest unique prefix ( b, tb, co, di, p, etc.)

Profiling Compile with -pg. Run program (producing gmon.out file). Use gprof(1). Excellent measurement of where your program is spending time on a function-by-function basis. There are other tools (e.g. coverage tests).

Tracing library calls strace(1) system call tracing ltrace(1) library call tracing demo

Memory Debugging different from a program debugger idea is to detect logical, but non-fatal errors: array bounds errors accessing freed heap memory memory leaks : allocated memory that nothing points to allocating memory (stack or heap) that is never used

Memory Debugging Tools Some choices: Electric Fence open source (package is electric-fence ) uses memory management utilities to bound malloc(3)ated blocks of memory. easy to use: just put -lefence on link line. worth understanding how it works an early work of Bruce Perens, major open source proponent UNICOM Rational PurifyPlus commercial product Pure Atria Rational IBM UNICOM Purify is nice if you can afford it. If you can t...

valgrind(1) http://valgrind.org pronunciation: val (as in value ) - grind (as in grinned ) In Norse mythology, Valgrind was the main entrance to Valhalla. Only those deemed worthy by the guards to the entrance are permitted to enter. Based on software emulator of: X86, AMD64, ARM, ARM64, PPC32, PPC64, S390X, or MIPS32 hardware for Linux, Android, or Darwin OSes. (Not available for Windows, but can be used with Wine.) Works like an interpreter (e.g. Java, Python), but interprets object code, not bytecode.

valgrind Syntax $ valgrind --tool=toolname program args where toolnname is: memcheck a heavy-weight memory checker (the default) cachegrind a cache usage profiler callgrind is cachegrind with call graph checking helgrind a data race detector (works with threads, as do the rest) massif a heap profiler lackey a sample you can look at to build own tools yourself that interact with valgrind data.

valgrind Advantages and Disadvantages advantages: checks memory usage (at bit level!) performs detailed profiling (including cache usage) has been used on systems with 25 million lines of code (!) works in the presence of threads works with compiled code (even if it s not optimized) works with any language (geared towards C/C++, though) disadvantage: programs are 5-100 times slower (so don t use it all the time on long programs!)

When Should You Use valgrind For Error Detection? all the time for short programs in automatic testing especially as part of regression testing after big changes when a bug has been detected after a bug has been fixed when a bug is suspected before a release

When Can You Use valgrind? $ valgrind ls -al Notes: works on a binary no source required report written to standard error

valgrind demo 07 valgrind mem leak.c #include <stdlib.h> #include <stdio.h> void get_mem() { char *ptr; ptr = (char *) malloc (10); /* memory not freed */ } int main(void) { char *ptr1, *ptr2; int i; ptr1 = (char *) malloc(512); ptr2 = (char *) malloc(512); ptr2 = ptr1; /* causes the memory leak of ptr1 */ free(ptr2); free(ptr1); for ( i = 0; i < 512; i++) { get_mem(); } }

Running 07 valgrind mem leak.c compile as usual $ valgrind -v --leak-check=yes 07_valgrind_mem_leak (Try it with and without the leak-check options.) The leak checker searches for leaks when the program exits.

valgrind demo 08 valgrind inv rw.c #include <stdlib.h> #include <stdio.h> int main(void) { char *buf0; char *buf1; int i; } buf0 = (char *) malloc(512 * sizeof(char)); buf1 = (char *) malloc(512 * sizeof(char)); for (i = 0; i <= 512; i++) { buf0[i] =? ; /* error when i = 512 invalid write */ buf1[i] = buf0[i]; /* error when i = 512 invalid read and write */ } free(buf1); free(buf0);

valgrind demo 09 valgrind uninit.c #include <stdio.h> int main(int argc, char *argv[]) { int whatisit; } printf("whatisit = %d\n", whatisit);

How Does valgrind Work? As above, valgrind contains a simulated processor. For each byte of data (including registers), valgrind adds 9 additional bits of information: 8 V ( valid ) bits for each bit in the byte. 1 A bit indicating that the address of the byte is valid. V-bits are checked when: data is used for address generation a control-flow decision is to be made (see below) A-bits are: set when memory is allocated cleared when memory is freed

Example: valgrind Looks at Uninitialized Values for (i = 0; i < 10; i++) j += a[i]; if (j == 42) printf("got the answer!\n"); valgrind does not complain at the j increment, since the undefinedness is not observable it won t affect your program output but it will complain at the if statement. This is why you get those uninitialized variable used in conditional messages from within system I/O or string calls instead of your own code. To see why...

Why not Check Uninitialized Assignments? Consider this code: struct S { int i; char c; } s[2];... s[0].i = 42; s[0].c = x ; s[1] = s[0]; With 32-bit ints and 8-bit chars, S structs could occupy as little as (how many?) bytes, but compilers make structs word-aligned (see why?), so they pad them to 8 bytes. At run time, this padding intent has been lost. The assignment s[1] = s[0]; will then copy uninitialized bytes, but it s okay because those bytes probably won t be used in s2 (or s1). If, by some hack, they are used (in a conditional), they ll be detected.

cachegrind: Cache Optimization basic idea: On x86 s there are actually two (or three) levels of cache: L1 (fastest) instructions data L2 (next fastest) unified (both instructions and data) cachegrind uses the same simulator as valgrind to find out the rates of cache hits and misses. It can annotate your code with them line-by-line.