Systemy wbudowane. Rysunek 1: Ilustracja procesu kompilacji oprogramowania



Podobne dokumenty
Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych.

Procesy pojęcia podstawowe. 1.1 Jak kod źródłowy przekształca się w proces

Programowanie Systemów Wbudowanych

Tworzenie oprogramowania

1.Wstęp. 2.Generowanie systemu w EDK

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

Technika mikroprocesorowa. Struktura programu użytkownika w systemie mikroprocesorowym

Laboratorium Informatyka (I) AiR Ćwiczenia z debugowania

Zadania: 1. Funkcja przeliczająca F na C: float FtoC(float f){ return (f 32.0) * 5.0 / 9.0; }

Wstęp do programowania

Grzegorz Cygan. Wstęp do programowania mikrosterowników w języku C

Wstęp do programowania. Wykład 1

Sposoby wykrywania i usuwania błędów. Tomasz Borzyszkowski

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 8. Karol Tarnowski A-1 p.

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ),

Programowanie w języku Python. Grażyna Koba

Podstawy programowania

Programowanie w języku C++ Grażyna Koba

Kompilacja i scalanie programów w linii poleceń gcc i make

Wykład 4. Środowisko programistyczne

Programowanie obiektowe zastosowanie języka Java SE

Smarty PHP. Leksykon kieszonkowy

Fragment wykładu z języka C ( )

Zasady programowania Dokumentacja

Programowanie w C++ Wykład 1. Katarzyna Grzelak. 26 luty K.Grzelak (Wykład 1) Programowanie w C++ 1 / 28

Środowisko Keil. Spis treści. Krzysztof Świentek. Systemy wbudowane. 1 Trochę teorii. 2 Keil

Podstawy programowania skrót z wykładów:

Laboratorium 1. I. Zainstaluj program Eclipse (wersja C/C++ w odpowiednim systemie operacyjnym

4 Literatura. c Dr inż. Ignacy Pardyka (Inf.UJK) ASK MP.01 Rok akad. 2011/ / 24

Utworzenie pliku. Dowiesz się:

C++ - [1-3] Debugowanie w Qt Creator

MentorGraphics ModelSim

Java jako język programowania

Podstawy Informatyki Wprowadzenie do języka C dr inż. Jarosław Bułat

Wprowadzenie do środowiska Qt Creator

Szkolenia specjalistyczne

Język ludzki kod maszynowy

Programowanie w C++ Wykład 1. Katarzyna Grzelak. 25 luty K.Grzelak (Wykład 1) Programowanie w C++ 1 / 38

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Programowanie w C. dr inż. Stanisław Wszelak

Programowanie komputerów

Systemy wbudowane. Wprowadzenie. Struktura. Mikrokontrolery AVR. Wprowadzenie do programowania w C

Algorytm. a programowanie -

Programowanie I. O czym będziemy mówili. Plan wykładu nieco dokładniej. Plan wykładu z lotu ptaka. Podstawy programowania w językach. Uwaga!

Metody i algorytmy pomiarów przedmiotów metodami optycznymi.

Niech wynik od 0 do 200F wyświetla w trzech kolumnach: F = (wartość) C = (wyliczona wartość) K = (wyliczona wartość)

Programowanie mikrokontrolerów AVR

Programowanie niskopoziomowe

Przedmiot : Programowanie w języku wewnętrznym. Ćwiczenie nr 4

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Systemy Operacyjne - Operacje na plikach

Programowanie niskopoziomowe. dr inż. Paweł Pełczyński

Programowanie niskopoziomowe

Sprzęt komputera - zespół układów wykonujących programy wprowadzone do pamięci komputera (ang. hardware) Oprogramowanie komputera - zespół programów

trainxx tramxx

Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami:

Instrukcje instalacji pakietu IBM SPSS Data Access Pack dla systemu Linux

Podstawy Informatyki Języki programowania c.d.

Architektury Usług Internetowych. Laboratorium 2. Usługi sieciowe

IBM SPSS Statistics Wersja 22. Linux - Instrukcja instalacji (licencja wielokrotna)

Programowanie Niskopoziomowe

WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM. NetBeans. Wykonał: Jacek Ventzke informatyka sem.

Programowanie C++ Wykład 1 - Aplikacje konsowlowe w środowisku QT. dr inż. Jakub Możaryn. Warszawa, Instytut Automatyki i Robotyki

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania

Instrukcje instalacji pakietu IBM SPSS Data Access Pack dla systemu Windows

Historia modeli programowania

Informator techniczny

1 Zapoznanie się ze środowiskiem Xenomai.

WYKŁAD 1 - KONSPEKT. Program wykładu:

Wykład. Materiały bazują częściowo na slajdach Marata Dukhana

Tom 6 Opis oprogramowania Część 8 Narzędzie do kontroli danych elementarnych, danych wynikowych oraz kontroli obmiaru do celów fakturowania

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Implementacja aplikacji sieciowych z wykorzystaniem środowiska Qt

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL III TI 4 godziny tygodniowo (4x30 tygodni =120 godzin ),

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

Praca w środowisku Visual Studio 2008, Visual C

Warsztaty AVR. Instalacja i konfiguracja środowiska Eclipse dla mikrokontrolerów AVR. Dariusz Wika

1. Opis. 2. Wymagania sprzętowe:

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Podstawy programowania. Wykład 1 Wstęp. Krzysztof Banaś Podstawy programowania 1

Tworzenie nowego projektu w asemblerze dla mikroprocesora z rodziny 8051

Politechnika Białostocka Wydział Elektryczny Katedra Automatyki i Elektroniki

Java EE produkcja oprogramowania

GNU GProf i GCov. przygotował: Krzysztof Jurczuk Politechnika Białostocka Wydział Informatyki Katedra Oprogramowania ul. Wiejska 45A Białystok

Zajęcia nr 1 Podstawy programowania. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Programowanie w asemblerze Linkowanie

Metody Kompilacji Wykład 1 Wstęp

Mikroprocesor Operacje wejścia / wyjścia

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Programowanie proceduralne w języku C++ Podstawy

Rys. 1. Główne okno programu QT Creator. Na rysunku 2 oznaczone zostały cztery przyciski, odpowiadają kolejno następującym funkcjom:

Spis treści JĘZYK C - ŚLEDZENIE WYKONANIA PROGRAMU, DEBUGGER. Informatyka 1. Instrukcja do pracowni specjalistycznej z przedmiotu

HELIOS pomoc społeczna

Tango-RedPitaya. Tango device server for RedPitaya multi-instrument board. Grzegorz Kowalski 31 sierpnia 2015

KONSTRUKCJA KOMPILATORÓW

ICD Wprowadzenie. Wprowadzenie. Czym jest In-Circuit Debugger? 2. O poradniku 3. Gdzie szukać dodatkowych informacji? 4

Programowanie procesora Microblaze w środowisku SDK

Transkrypt:

Rozdział 1 PROCES KOMPILACJI I KONSOLIDACJI 1.1. WSTĘP Przed wgraniem do pamięci urządzenia wbudowanego program zapisany w formie pliku lub zbioru plików tekstowych stanowiących tzw. kod źródłowy musi zostać przetłumaczony na postać binarną odpowiednią dla docelowej architektury. Mimo, że proces przekształcania kodu źródłowego potocznie nazywany jest kompilacją to składa się on z dwóch odrębnych etapów kompilacji oraz konsolidacji. Kompilacja to proces podczas którego kod źródłowy programu jest automatycznie analizowany i przekształcany na postać kodu maszynowego. Należy zaznaczyć, że proces kompilacji jest zależny od docelowej architektury co oznacza, że program skompilowany dla procesora typu ARM nie będzie działał na systemie z procesorem z rodziny x86. Schemat blokowy procesu kompilacji zilustrowany jest na rysunku 1. Rysunek 1: Ilustracja procesu kompilacji oprogramowania Pliki tekstowe z kodem źródłowym programu mogą zostać utworzone za pomocą dowolnego edytora tekstowego. Każdy z plików jest oddzielnie analizowany przez kompilator i tworzone są pliki obiektowe zawierające wstępnie przetworzone fragmenty program w formie tak zwanej reprezentacji pośredniej. Następnie, na etapie konsolidacji wszystkie pliki obiektowe łączone są razem i powstaje jeden plik wykonywalny. Dodawane są również pliki bibliotek użytkownika stanowiące zbiory skompilowanych funkcji wielokrotnego użytku oraz biblioteki systemowe dostarczane wraz z kompilatorem umożliwiają miedzy innymi pobieranie danych od użytkownika czy wyświetlanie informacji na domyślnym terminalu. W przypadku kompilacji z wykorzystaniem tzw. GNU Toolchain (czyli narzędzi takich jak kompilator gcc, asembler 1 as oraz linker ld) proces ten przebiega w następujących krokach: kompilator danego 1 W języku polskim zarówno język asemblera (ang. assembly language) jak i program przeprowadzający asemblację (ang. assembler) nazywane są potocznie asemblerem. 1

języka programowania (np. cc1 dla języka C) przetwarza pliki źródłowe do postaci plików pośrednich zawierających instrukcji asemblera dla danej architektury. Następnie program zwany asemblerem (np. as) przetwarza pliki asemblera do postaci plików pośrednich zapisanych w formacie ELF [1] (ang. Executable and Linkable Format). Podczas kolejnego kroku konsolidator łączy wszystkie pliki pośrednie oraz biblioteki statyczne w jeden plik wykonywalny. Ostatnim, opcjonalnym etapem jest przetworzenie pliku zapisanego w postaci ELF do postaci akceptowalnej przez programator wykorzystywany przez dany system mikroprocesorowy, np. Intel HEX lub format binarny. 1.2. RODZAJE KOMPILACJI Biorąc pod uwagę rodzaj architektury na której będzie działał kompilator oraz rodzaj architektury dla której kompilator będzie generował programy wyróżnić możemy trzy rodzaje kompilacji: kompilacja natywna, kompilacja kanadyjska oraz cross kompilacja. W przypadku GNU Toolchain podczas kompilowania środowiska programistycznego trzy zmienne środowiskowe określają rodzaj wspieranego typu kompilacji: target (określa rodzaj architektury dla której kompilator będzie generował programy), host (określa rodzaj architektury na której kompilator będzie uruchamiany) oraz build (określa rodzaj architektury na której będziemy kompilowali kompilator). kompilacja natywna kompilator generuje kod wykonywalny dla tej samej architekturze na której pracuje. Jest to najprostszy i jednocześnie najczęściej spotykany przypadek. W przypadku GNU Toolchain zmienne target, host, build określają tą samą architekturę, np.: x86. kompilacja kanadyjska specjalny przypadek umożliwiający skompilowanie środowiska programistycznego na jednej architekturze, działającego na innej i generującego programy dla jeszcze innej np.: kompilacja kanadyjska umożliwia skompilowanie na architekturze x86 kompilatora pracującego na architekturze ARM i generującego programy dla architektury PowerPC. W przypadku GNU Toolchain zmienne target, host, build będą ustawione odpowiednio PowerPC, ARM oraz x86. cross kompilacja kompilator generuje kod wykonywalny dla innej architektury niż ten na której sam pracuje. Cross kompilacja najczęściej wykorzystywana jest w przypadku systemów wbudowanych takich jak np. kuchenki mikrofalowe, pralki automatyczne czy telefony komórkowe posiadające znacznie ograniczone zasoby co uniemożliwia lub znacznie utrudnia uruchomienie środowiska do kompilacji natywnej. Cross kompilacja wymaga aby wszystkie narzędzia wchodzące w skład środowiska programistycznego były odpowiednio skonfigurowane tzn. muszą być przystosowane do pracy uwzględniającej odpowiednią architekturę docelową kompilator musi generować odpowiedni kod asemblera, asembler, konsolidator oraz biblioteka standardowa muszą wspierać architekturę docelową. W przypadku GNU Toolchain, konfigurowania kompilatora dla architektury ARM działającego na procesorze x86 zmienna 2

target będzie ustawiona na ARM natomiast host oraz build będą ustawione na x86. 1.3. ŚRODOWISKO PROGRAMISTYCZNE GNU TOOLCHAIN GNU Toolchain to zestaw narzędzi programistycznych przeznaczonych do tworzenia aplikacji. W skład GNU Toolchain wchodzą miedzy innymi: GNU make 2 narzędzie przeznaczone do automatycznego kompilowania programów i bibliotek z kodów źródłowych. Jego działanie opera się na interpretacji pliku konfiguracyjnego o nazwie makefile opisującego poszczególne kroki procesu kompilacji. GNU Compiler Collection 3 zestaw kompilatorów języków programowania takich jak C, C++, Objective C, FORTRAN. Asembler oraz konsolidator nie są częścią tego projektu. GNU Binutils 4 zestaw narzędzi do przeprowadzania operacji na plikach obiektowych 5 w skład którego wchodzą: konsolidator (ld), asembler (as), narzędzie do wyświetlania zawartości plików obiektowych (objdump), narzędzie do modyfikacji struktury plików obiektowych (objcopy), narzędzie do wyświetlania szczegółowych informacji na temat plików w formacie ELF (readelf). GNU Debugger 6 narzędzie służące do dynamicznej analizy innych programów w celu odnalezienia i identyfikacji zawartych w nich błędów. Debugger pozwala na uruchomienie programu w tak zwanym trybie krokowym co umożliwia na przeanalizowanie wartości przechowywanych w poszczególnych zmiennych wykorzystywanych w programie przed i po wykonaniu poszczególnych linii kodu. GNU Autotools zestaw narzędzi umożliwiających kompilowanie kodu źródłowego i budowanie przenośnych pakietów oprogramowania dla różnych systemów operacyjnych. W skład zestawu wchodzą miedzy innymi następujące narzędzia: autoconf 7, automake 8, autoconf 9, libtool 10 2 więcej informacji: www.gnu.org/software/make/ 3 więcej informacji: gcc.gnu.org 4 więcej informacji: http://www.gnu.org/software/binutils/ 5 nazwa pliki obiektowe w kontekście procesu kompilacji odnosi się do plików binarnych zawierających reprezentację pośrednią danego programu zazwyczaj zapisaną w formacie ELF (Linux) lub PE (Windows) i nie ma nic wspólnego z obiektowym paradygmatem programowania. 6 więcej informacji: http://www.gnu.org/software/gdb/ 7 więcej informacji: http://www.gnu.org/software/autoconf/ 8 więcej informacji: http://www.gnu.org/software/automake/ 9 więcej informacji: http://www.gnu.org/software/autoconf/ 10 więcej informacji: http://www.gnu.org/software/libtool/ 3

1.4. SKRYPTY KONSOLIDATORA Konsolidator (ang. linker) to program który w trakcie procesu konsolidacji łączy podane pliki obiektowe i biblioteki statyczne tworząc plik wykonywalny. Pracą konsolidatora steruje plik konfiguracyjny zwany skryptem konsolidatora. Określa on w których obszarach pamięci umieszczone mają być poszczególne fragmenty programy zwane sekcjami. W większości plików w formacie ELF znajdują się następujące sekcje:.tekst zawierająca binarny kod programu,.data zawierająca zainicjalizowane zmienne globalne oraz.bss zawierająca niezainicjalizowane zmienne lokalne. Informacje na temat sekcji występujących w danym pliku można uzyskać korzystając z narzędzia objdump pochodzącego z pakietu GNU Binutils. Znaczenie poszczególnych kolumn jest następujące: indeks, nazwa sekcji, rozmiar sekcji, Virtual Memory Address (adres w pamięci pod który sekcja musi zostać załadowana aby program działał poprawnie), Load Memory Address (adres w pamięci pod którym sekcja będzie załadowana do pamięci), położenie sekcji wyrażone jako przesunięcie od początku pliku ELF oraz wyrównanie danej sekcji w pamięci. Wyróżnienie adresów LMA oraz VMA pozwala miedzy innymi na umieszczenie sekcji.data w pamięci ROM znajdującej się pod adresem LMA i przeniesienie jej do pamięci VMA podczas startu systemu. gdb-test@dmcslab1:~/gdb-test-example$ objdump -h wynik.elf wynik.elf: file format elf32-little Sections: Idx Name Size VMA LMA File off Algn 0.text 00000988 20000000 20000000 00000080 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 1.data 00000068 00300000 20000988 00000a08 2**2 CONTENTS, ALLOC, LOAD, DATA 2.bss 000000a8 00300068 200009f0 00000a70 2**2 ALLOC Powyższy przykład należy interpretować w następujący sposób: 1. sekcja.text o rozmiarze 2440 bajtów (988 h ) będzie załadowana do pamięci pod adres 20000000 h (kolumna VMA). Jednocześnie sekcja ta będzie przechowywana w pamięci przed uruchomieniem programu pod adresem 20000000 h (kolumna LMA). 2. sekcja.data o rozmiarze 104 bajtów (68 h ) podczas uruchamiania programu musi zostać załadowana do pamięci pod adres 00300000 h (kolumna VMA). Jednocześnie sekcja ta będzie przechowywana w pamięci przed uruchomieniem programu pod adresem 20000988 h (kolumna LMA). Kopiowaniem danych spod adresów LMA do VMA zajmują się biblioteki startowe systemu. 3. sekcja.bss o rozmiarze 168 bajtów (A8 h ) musi zostać załadowana do pamięci pod adres 00300068 h (kolumna VMA). Jednocześnie sekcja ta będzie przechowywana w pamięci przed uruchomieniem programu pod adresem 200009f0 h (kolumna LMA). 4

Poniższy rysunek przedstawia skrypt konsolidatora użyty do wygenerowania pliku użytego w powyższym przykładzie. Określa rodzajpliku wynikowego domyslnie elf32-littlearm ale użytkownik za pomocą odpowiedniego parametru może określić który format z poniższe listy będzie użyty OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") Określa rodzaj architektury sprzętowej na którą generowany będzie kod OUTPUT_ARCH(arm) Określa nazwę pierwszej funkcji programu ENTRY(reset_handler) Definicje sekcji występujących w pliku ELF SECTIONS { Sekcja.text w pliku wyjściowym będzie składała się z połączonych sekcji.text oraz.rodata pobranych ze wszystkich plików wejściowych. Dodatkowo adresy VMA początku oraz końca sekcji zostaną umieszczone w zmiennych _stext oraz _etest..text : { _stext =.; *(.text) *(.rodata) /* read-only data (constants) */ *(.rodata*). = ALIGN(4); _etext =. ; Sekcja.data w pliku wyjściowym będzie składała się z połączonych sekcji.vectors oraz.data pobranych ze wszystkich plików wejściowych. Dodatkowo adresy VMA początku oraz końca sekcji zostaną umieszczone w zmiennych _sdata oraz _edata. Adres LMA sekcji został ustawiony na adres bezpośrednio po sekcji.text..data : AT ( ADDR (.text) + SIZEOF (.text) ) { _sdata =.; *(.vectors) *(.data) _edata =.; Sekcja.bss w pliku wyjściowym będzie składała się z połączonych sekcji.bss pobranych ze wszystkich plików wejściowych. Dodatkowo adresy VMA początku oraz końca sekcji zostaną umieszczone w zmiennych _sbss oraz _ebss..bss (NOLOAD) : {. = ALIGN(4); _sbss =.; *(.bss) _ebss =.; end =.; Początkowy adres VMA sekcji.text oraz.data nie zostały bezpośrednio umieszczone w skrypcie konsolidatora. Ich wartości ustawiane są za pomocą parametrów przekazanych do wywołania konsolidatora (-Ttext 0x20000000 -Tdata 0x300000) znajdującym się w pliku makefile. 5

Rozdział 2 DEBUGGER GDB 2.1. WSTĘP GNU Debugger jest narzędziem umożliwiającym śledzenie wykonania programu w trybie krokowym co pozwala na łatwe i szybkie wykrywanie oraz usuwanie błędów znajdujących się w kodzie programu. Jest to narzędzie pracujące w trybie tekstowym co umożliwia pracę na zdalnych komputerach nie wspierających graficznego interfejsu użytkownika. Program wchodzi w skład środowiska programistycznego GNU Toolchain i wspiera wszystkie architektury docelowe obsługiwane przez to środowisko. 2.2. PODSTAWY OBSŁUGI APLIKACJI GDB PRZYGOTOWANIE PLIKU BINARNEGO Każdy program może zostać uruchomiony w trybie krokowym z wykorzystaniem debuggera gdb jednakże odpowiednie przygotowanie pliku wynikowego na etapie kompilacji znacznie ułatwia proces analizy. Aplikacja powinna być skompilowana z dodatkowym parametrem (w przypadku kompilatora z pakietu GNU Toolchain jest to parametr g) dołączającym dodatkowe informacje wykorzystywane przez debugger takie jak nazwy zmiennych czy funkcji. Brak tych informacji powoduje, że aplikacja nie jest w stanie poprawnie interpretować danych zawartych w pliku obiektowym i analiza programu jest możliwa tylko na poziomie kodu asemblera. Dodatkowo, należy pamiętać, że użycie optymalizacji na etapie kompilacji może spowodować usunięcie niektórych zmiennych, rozwinięcie funkcji w miejscu wywołania oraz zmianę kolejności wykonywanych instrukcji. Tego typu operacje powodują rozsynchronizowanie kodu źródłowego aplikacji i zawartości pliku obiektowego co prowadzi do dziwnych zachowań debuggera takich jak próby wizualizacji wykonania nieistniejących linii kodu czy wywołań nieistniejących funkcji. ANALIZOWANIE APLIKACJI Z WYKORZYSTANIEM PROGRAMU GDB W celu rozpoczęcia sesji debuggera należy uruchomić program gdb podając jako parametr nazwę pliku wykonywalnego. Jeżeli aplikacja oczekuje parametrów wejściowych z linii poleceń podaje się je po uruchomieniu środowiska za pomocą polecenia set args. Sesję debuggera kończy się za pomocą polecenia quit [q]. Dodatkowo, za pomocą polecenia help możliwe jest uzyskanie szczegółowych informacji na temat poszczególnych komend np.: help break. Możliwe jest uruchomienie aplikacji w trybie ciągłym lub krokowym. Tryb ciągły powoduje wykonanie programu do momentu poprawnego zakończenia aplikacji, wystąpienia błędu krytycznego lub natrafienia na punkt przerwania (ang. breakpoint). Punkt przerwania to 6

miejsce w którym ciągłe wykonanie programu zostaje zakończone a debugger przechodzi do trybu krokowego. W trybie krokowym debugger wykonuje pojedyncze instrukcje na żądanie użytkownika. Tryb ciągły może zostać uruchomiony za pomocą polecenia run [r] lub start przy czym start powoduje automatyczne wstawienie punktu przerwania w pierwszej funkcji programu. Przejście z powrotem z trybu krokowego do ciągłego możliwe jest za pomocą komendy continua [c]. Punkty przerwań można umieszczać w programie za pomocą polecenia break po którym podaje się numer linii w aktualnym pliku, nazwę pliku i numer linii lub nazwę funkcji w programie. Możliwe jest również wstawienie warunkowego punktu przerwań który zostanie aktywowany tylko jeżeli podany warunek jest spełniony np.: break example.cpp:77 if a == 1. Informacje na temat aktualnie ustawionych punktów przerwań można uzyskać za pomocą polecenia info break [i b]. Punkty przerwań można usunąć z programu za pomocą polecenia delete [d] nr_punktu_przerwania. W trybie krokowym dostępne są następujące komendy: next powoduje wykonanie kolejnej instrukcji w programie. Napotkanie instrukcji wywołania funkcji powoduje wykonanie całej funkcji bez zatrzymywania się w jej wnętrzu. step powoduje wykonanie kolejnej instrukcji w programie. Napotkanie instrukcji wywołania funkcji powoduje wejście do jej wnętrza i zatrzymanie programu na pierwszej instrukcji. finish powoduje ciągłe wykonanie programu do momentu natrafienia na instrukcję powrotu z funkcji. nexti powoduje wykonanie jednej instrukcji maszynowej programu. Napotkanie instrukcji wywołania funkcji powoduje wykonanie całej funkcji bez zatrzymywania się w jej wnętrzu. stepi powoduje wykonanie jednej instrukcji maszynowej programu. Napotkanie instrukcji wywołania funkcji powoduje wejście do jej wnętrza i zatrzymanie programu na pierwszej instrukcji. Jeżeli debugger pracuje w trybie krokowym możliwe jest odczytanie wartości poszczególnych zmiennych. Służy do tego polecenie print [p] wyświetlające jednorazowo wartość zmiennej lub display [disp] wyświetlające wartość zmiennej po każdym kroku wykonywanego programu. Uzyskanie informacji na temat listy wyświetlanych zmiennych możliwe jest za pomocą polecenia info display [i disp]. Usunięcie elementu z listy zmiennych wyświetlanych przy każdym kroku programu możliwe jest za pomocą polecenia undisplay nr_zmiennej. Odczytanie zawartości określonej komórki pamięci możliwe jest za pomocą polecenia examine [x]. PODSUMOWANIE KOMEND PROGRAMU GDB Komenda run [r] Opis uruchamia analizowany program w trybie ciągłym 7

start [sta] continue [c] break lokacja [b] delete nr [d nr] next [n] nexti [ni] step [s] stepi [si] finish [fin] print zmienna [p] display zmienna [disp] examine adres [x] list [l] info break [i b] info display [i disp] info register [i r] set args argumenty uruchamia analizowany program w trybie ciągłym automatycznie wstawiając punkt przerwania na początku pierwszej funkcji programu przechodzi z trybu krokowego do ciągłego (wznawia wykonanie programu) wstawia punkt przerwania w określone miejsce programu usuwa punkt przerwania o numerze nr wykonuje kolejną linię kodu programu nie wchodzi do wnętrza funkcji wykonuje kolejną instrukcję maszynową programu nie wchodzi do wnętrza funkcji wykonuje kolejną linię kodu programu wchodzi do wnętrza funkcji wykonuje kolejną instrukcję maszynową programu wchodzi do wnętrza funkcji wykonuje program w trybie ciągłym do momentu osiągnięcia instrukcji powrotu z funkcji wyświetla wartość podanej zmiennej dodaje zmienną do listy elementów których wartości są wyświetlane przy każdym kroku wykonywanego programu wyświetla zawartość komórki pamięci o podanym adresie wyświetl kod źródłowy programu począwszy od aktualnego miejsca zatrzymania wyświetla listę punktów przerwania umieszczonych w programie wyświetla listę zmiennych wyświetlanych przy każdy kroku wykonywanego programu wyświetla informacje o rejestrach mikroprocesora ustaw argumenty linii poleceń PRZEKŁAD WYSZUKIWANIA BŁĘDÓW W PROGRAMIE Poniższy program po skompilowaniu i uruchomieniu wyświetla komunikat Floating point exception i kończy działanie. Program został skompilowany za pomocą poniższego polecenia: g++ -Wall g gdb-example-1.cpp o test #include <iostream> int div(int a1) { int w,c, tab[10] = {0; for (c = sizeof(tab)/sizeof(tab[0]); c >= 0; c--){ tab[c] = a1/c; w += tab[c]; return w; int main() { int ival1; ival1 = div(100); return ival1; 8

PRZEKŁAD SESJI DEBUGGERA gdb-test@dmcslab1:~/gdb-test-example$ gdb./test GNU gdb 6.8-debian Copyright (C) 2008 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-linux-gnu"... Debugger oczekuje na polecenia od użytkownika. Program zostaje uruchomiony w trybie ciągłym za pomocą polecenia run [r]. r Starting program: /home/gdb-test/gdb-test-example/test Program received signal SIGFPE, Arithmetic exception. 0x00000000004006e5 in div (a1=100) at main.cpp:7 7 tab[c] = a1/c; Uruchomienie program w trybie ciagłym skutkuje zakończeniem działania z powodu natrafienia na błąd krytyczny. Wyświetlona została dodatkowa informacja o lokalizacji instrukcji powodującej błąd plik main.cpp linia 7. Polecenie list [l] umożliwia wyświetlenie kodu źródłowego programu. l 2 3 int div(int a1) 4 { 5 int w,c, tab[10] = {0; 6 for (c = sizeof(tab)/sizeof(tab[0]); c >= 0; c--){ 7 tab[c] = a1/c; 8 w += tab[c]; 9 10 return w; 11 Za pomocą polecenia break [b] main.cpp:7 if c == 0 umieszczany jest punkt przerwania w linii generującej błąd. Następnie program jest uruchamiany od początku za pomocą polecenia run [r] b main.cpp:7 if c ==0 Breakpoint 1 at 0x4006d4: file main.cpp, line 7. r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: home/gdb-test/gdb-test-example/test Breakpoint 1, div (a1=100) at main.cpp:7 7 tab[c] = a1/c; Teraz możliwe jest przeanalizowanie stanu poszczególnych zmiennych za pomocą polecenia print [p] i zlokalizowanie źródła błędu. p c $3 = 0 p a1 $4 = 100 p w $5 = 301 9

PRZYKŁAD SESJI DEBUGGERA Z ODCZYTEM ZMIENNYCH LOKALNYCH gdb-test@dmcslab1:~/gdb-test-example$ gdb./test b div Breakpoint 1 at 0x4006a3: file main.cpp, line 5. r Starting program: /home/apiotro/tmp/test Breakpoint 1, div (a1=100) at main.cpp:5 5 int w,c, tab[10] = {0; n 6 for (c = sizeof(tab)/sizeof(tab[0]); c >= 0; c--){ 7 tab[c] = a1/c; p c $1 = 10 disp c 1: c = 10 disp a1 2: a1 = 100 n 8 w += tab[c]; 2: a1 = 100 1: c = 10 6 for (c = sizeof(tab)/sizeof(tab[0]); c >= 0; c--){ 2: a1 = 100 1: c = 10 n 7 tab[c] = a1/c; 2: a1 = 100 1: c = 9 p c $2 = 9 p &c $3 = (int *) 0x7fffa9f195fc x &c 0x7fffa9f195fc: 0x00000009 x 0x7fffa9f195fc 0x7fffa9f195fc: 0x00000009 p *0x7fffa9f195fc $4 = 9 OGRANICZENIA ANALIZY APLIKACJI Z UŻYCIEM DEBUGGERA Należy pamiętać, że debugger jest narzędziem ingerującym w przebieg wykonania programu dlatego następujące elementy muszą być wzięte pod uwagę podczas analizy zachowania aplikacji: debugger przejmuje kontrolę nad wykonywaną aplikacją co znacząco wpływa na szybkość działającego programu dlatego wykonanie analizy efektywności aplikacji jest praktycznie niemożliwe, testowanie poprawności działania programu skompilowanego z użyciem optymalizacji oferowanych przez kompilator jest możliwa tylko na poziomie języka asemblera, 10

Rozdział 3 LITERATURA [1] Levine, John R., Linkers and Loaders, 1999, ISBN 1558604960, Morgan Kaufmann Publishers Inc., San Francisco, CA, USA 11