#1Profilers and DebuggersProfilers and Debuggers#2Introductory Material•First, who doesn’t know assembly language?–You’ll get to answer all the assembly questions. Yes, really. •Lecture Style:–“Sit on the table” and pose questions. So, wake up!•Lecture Goal: –After the lecture you’ll think, “Wow, that was all really obvious. I could have done that.”#3One-Slide Summary•A debugger helps to detect the source of a program error by single-stepping through the program and inspecting variable values. •Breakpoints are the fundamental building block of debuggers. Breakpoints can be implemented with signals and special OS support. •A profiler is a performance analysis tool that measures the frequency and duration of function calls as a program runs. •Profilers can be event- or sampling-based.#4Lecture Outline•Debugging–Signals–How Debuggers Works–Breakpoints–Advanced Tools•Profiling–Event-based–Statistical#5What is a Debugger?“A software tool that is used to detect the source of program or script errors, by performing step-by-step execution of application code and viewing the content of code variables.”-MSDN#6Machine-Language Debugger•Only concerned with assembly code•Show instructions via disassembly•Inspect the values of registers, memory•Key Features (we’ll explain all of them)–Attach to process–Single-stepping–Breakpoints–Conditional Breakpoints–Watchpoints#7Signals•A signal is an asynchronous notification sent to a process about an event:–User pressed Ctrl-C (or did kill %pid)–Exceptions (divide by zero, null pointer)–From the OS (SIGPIPE)•You can install a signal handler – a procedure that will be executed when the signal occurs. –Signal handlers are vulnerable to race conditions. Why?#8Signal Example#include <stdio.h>#include <signal.h>int global = 11; int my_handler() { printf("In signal handler, global = %d\n", global); exit(1); } void main() { int * pointer = NULL; signal(SIGSEGV, my_handler) ; global = 33; * pointer = 0; global = 55; printf("Outside, global = %d\n", global); } •What does this program print?#9Attaching A Debugger•Requires operating system support•There is a special system call that allows one process to act as a debugger for a target–What are the security concerns?•Once this is done, the debugger can basically “catch signals” delivered to the target–This isn’t really what happens, but it’s a good explanation …#10Building a Debugger#include <stdio.h>#include <signal.h>#define BREAKPOINT *(0)=0int global = 11; int debugger_signal_handler() { printf(“debugger prompt: \n”); // debugger code goes here!} void main() { signal(SIGSEGV, debugger_signal_handler) ; global = 33; BREAKPOINT; global = 55; printf("Outside, global = %d\n", global); } •We can then get breakpoints and interactive debugging–Attach to target–Set up signal handler–Add in exception-causing instructions –Inspect globals, etc.#11Reality•We’re not really changing the source code•Instead, we modify the assembly•We can’t insert instructions–Because labels are already set at known constant offsets•Instead we change them .file "example.c".globl _global .data .align 4_global: .long 11 .def ___main .section .rdata,"dr"LC0: .ascii "Outside, global = %d\12\0" .text.globl _main .def _main _main: pushl %ebp movl %esp, %ebp subl $24, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax movl %eax, -4(%ebp) movl -4(%ebp), %eax call __alloca call ___main movl $33, _global movl $55, _global movl _global, %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf leave ret .def _printf#12Adding A Breakpoint•Add a breakpoint just after “global = 33;” .file "example.c".globl _global .data .align 4_global: .long 11 .def ___main .section .rdata,"dr"LC0: .ascii "Outside, global = %d\12\0" .text.globl _main .def _main _main: pushl %ebp movl %esp, %ebp subl $24, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax movl %eax, -4(%ebp) movl -4(%ebp), %eax call __alloca call ___main movl $33, _global movl $55, _global movl _global, %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf leave ret .def _printf .file "example.c".globl _global .data .align 4_global: .long 11 .def ___main .section .rdata,"dr"LC0: .ascii "Outside, global = %d\12\0" .text.globl _main .def _main _main: pushl %ebp movl %esp, %ebp subl $24, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax movl %eax, -4(%ebp) movl -4(%ebp), %eax call __alloca call ___main movl $33, _global movl $0, 0 movl _global, %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf leave ret .def _printf Storage Cell:movl $55, _global_main + 15#13Software Breakpoint Recipe•Debugger has already attached and set up its signal handler•User wants a breakpoint at instruction X•Store (X, old_instruction_at_X)•Replace instruction at X with “*0=0”–Pick something illegal that’s 1-byte long•Signal handler replaces instruction at X with stored old_instruction_at_X•Give user interactive debugging prompt#14Advanced Breakpoints•Get register and local values by walking the stack•Optimization: hardware breakpoints–Special register: if PC value = HBP register value, signal an exception–Faster than software, works on ROMs, only limited number of breakpoints, etc. •Feature: condition breakpoint: “break at instruction X if some_variable = some_value”•As before, but signal handler checks to see if some_variable = some_value–If so, present interactive debugging
View Full Document