Debugga C kod med emacs och gdb: Difference between revisions

From Peters wiki
Jump to navigation Jump to search
m Gör version 4210 av Peter (diskussion) ogjord
mNo edit summary
 
(3 intermediate revisions by the same user not shown)
Line 7: Line 7:
Följande kod används i denna guide:
Följande kod används i denna guide:


{{Box Kod|main.c|
{{hc|main.c|
<pre>
<nowiki>#include <stdio.h>
#include <stdio.h>


int main(void)
int main(void)
Line 21: Line 20:
   return 0;
   return 0;
}
}</nowiki>
</pre>
}}
}}


=== Kompilera koden med debuggstöd ===
=== Kompilera koden med debuggstöd ===
Kompilera koden med debuggstöd:
Kompilera koden med debuggstöd:
{{Box Kommando|gcc -o calcsum -g main.c|}}
{{Cmd|gcc -o calcsum -g main.c}}


=== Start gdb i emacs ===
=== Start gdb i emacs ===
Börja med att starta igång emacs i samma katalog som koden och ditt kompilerade program:
Börja med att starta igång emacs i samma katalog som koden och ditt kompilerade program:
{{Box Kommando|emacs &|}}
{{Cmd|emacs &}}
 
Starta sedan gdb i emacs genom att trycka på M+x (Meta fås genom att trycka på Alt-knappen) och skriva kommandot gdb. Emacs kommer sedan att fråga:


Starta sedan gdb i emacs genom att trycka på M+x (Meta fås genom att trycka på Alt-knappen) och skriva kommandot gdb. Emacs kommer sedan att fråga: ''Run gdb (like this): gdb --annotate=3 calcsum''. Tryck bara på Enter för att acceptera kommandot.
Run gdb (like this): gdb --annotate=3 calcsum
 
Tryck bara på Enter för att acceptera kommandot.
Börja sedan med att sätta en brytpunkt på funktionen main():
Börja sedan med att sätta en brytpunkt på funktionen main():
{{Box Kommando|(gdb) break main|Breakpoint 1 at 0x400480: file main.c, line 8.}}
{{Cmd|(gdb) break main|output=Breakpoint 1 at 0x400480: file main.c, line 8.}}
Kör sedan programmet fram till denna brytpunkt genom att köra kommandot run eller r:
Kör sedan programmet fram till denna brytpunkt genom att köra kommandot run eller r:
{{Box Kommando|(gdb) r|
{{Cmd|(gdb) r|output=Starting program: /home/peter/tmp/gdb/calcsum<br>
Starting program: /home/peter/tmp/gdb/calcsum  
Breakpoint 1, main () at main.c:8
 
}}
Breakpoint 1, main () at main.c:8}}
Ett fönster med koden ska nu öppnas i ett emacs fönster:
Ett fönster med koden ska nu öppnas i ett emacs fönster:


Line 47: Line 50:


Öppna ett fönster i emacs som visar alla lokala variabler i nuvarande funktion genom menyn Gud => GDB-Windows => Locals. Exekvera sedan rader rader genom att köra kommandot next eller n. Antingen kan man köra kommadot next två gånger eller så anger man hur många rader man vill köra efter kommandot:
Öppna ett fönster i emacs som visar alla lokala variabler i nuvarande funktion genom menyn Gud => GDB-Windows => Locals. Exekvera sedan rader rader genom att köra kommandot next eller n. Antingen kan man köra kommadot next två gånger eller så anger man hur många rader man vill köra efter kommandot:
{{Box Kommando|(gdb) n 2|}}
{{Cmd|(gdb) n 2}}
Man kan nu se i locals fönstret att i och sum har blivit uppdaterade till 100 resp. 4950:
Man kan nu se i locals fönstret att i och sum har blivit uppdaterade till 100 resp. 4950:


[[Image:gdb_in_emacs_2.png]]
[[Image:gdb_in_emacs_2.png]]


== Skillnaden mellan step och next ==


== Skillnaden mellan step och next ==
Anta att vi lägger till en funktion som sköter om utskriften av summan:
Anta att vi lägger till en funktion som sköter om utskriften av summan:


{{Box Kod|main.c|
{{hc|main.c|
<pre>
<nowiki>#include <stdio.h>
#include <stdio.h>


static void printsum(const int sum);
static void printsum(const int sum);
Line 77: Line 79:
   return 0;
   return 0;
}
}</nowiki>
</pre>
}}
}}


Line 84: Line 85:


== Databrytpunkt ==
== Databrytpunkt ==
Anta att vi är intresserade att stanna exekveringen när en variabel ändrar värde, men inte vet var i koden den ändras. Då är en databrytpunkt perfekt. Anta följande kod:
Anta att vi är intresserade att stanna exekveringen när en variabel ändrar värde, men inte vet var i koden den ändras. Då är en databrytpunkt perfekt. Anta följande kod:
{{Box Kod|main.c|
{{hc|main.c|
<pre>
<nowiki>int a = 0;
int a = 0;


void foo(void);
void foo(void);
Line 104: Line 105:
    
    
   return 0;
   return 0;
}
}</nowiki>
</pre>
}}
}}


Kompilera koden och starta upp debuggningen i emacs. Gå till main() rutinen. Kör sedan kommandot:
Kompilera koden och starta upp debuggningen i emacs. Gå till main() rutinen. Kör sedan kommandot:
{{Box Kommando|watch a|}}
{{Cmd|watch a}}
För att sätta en brytpunkt då a ändras. Fortsätt sedan exekveringen genom att köra kommandot:
För att sätta en brytpunkt då a ändras. Fortsätt sedan exekveringen genom att köra kommandot:
{{Box Kommando|c|}}
{{Cmd|c}}
som är en förkortning för kommandot <tt>continue</tt>.
som är en förkortning för kommandot {{ic|continue}}.


[[Image:gdb_in_emacs_3.png]]
[[Image:gdb_in_emacs_3.png]]
Line 118: Line 118:
Exekveringen ska stanna i funktionen foo(), eftersom där räknas a upp med ett.
Exekveringen ska stanna i funktionen foo(), eftersom där räknas a upp med ett.


[[Category:Gentoo Linux]]
[[Category:Guide]]

Latest revision as of 11:58, 21 April 2013

Denna guide visar hur man kommer igång med att debugga C kod med gdb. gdb startas i emacs för att kunna på ett enklare sätt sätta brytpunkter, titta på variabler, titta på koden m.m. Program som måste vara installerade:

  • gcc
  • gdb
  • emacs

Ett första exempel

Följande kod används i denna guide:

main.c
#include <stdio.h>

int main(void)
{
  int i;
  int sum;

  sum = 0;
  for (i = 0; i < 100; i++) sum += i;
  printf("sum = %d\n", sum);
	
  return 0;
}

Kompilera koden med debuggstöd

Kompilera koden med debuggstöd:

user $ gcc -o calcsum -g main.c

Start gdb i emacs

Börja med att starta igång emacs i samma katalog som koden och ditt kompilerade program:

user $ emacs &

Starta sedan gdb i emacs genom att trycka på M+x (Meta fås genom att trycka på Alt-knappen) och skriva kommandot gdb. Emacs kommer sedan att fråga:

Run gdb (like this): gdb --annotate=3 calcsum

Tryck bara på Enter för att acceptera kommandot. Börja sedan med att sätta en brytpunkt på funktionen main():

user $ (gdb) break main
Breakpoint 1 at 0x400480: file main.c, line 8.

Kör sedan programmet fram till denna brytpunkt genom att köra kommandot run eller r:

user $ (gdb) r
Starting program: /home/peter/tmp/gdb/calcsum
Breakpoint 1, main () at main.c:8

Ett fönster med koden ska nu öppnas i ett emacs fönster:


Öppna ett fönster i emacs som visar alla lokala variabler i nuvarande funktion genom menyn Gud => GDB-Windows => Locals. Exekvera sedan rader rader genom att köra kommandot next eller n. Antingen kan man köra kommadot next två gånger eller så anger man hur många rader man vill köra efter kommandot:

user $ (gdb) n 2

Man kan nu se i locals fönstret att i och sum har blivit uppdaterade till 100 resp. 4950:

Skillnaden mellan step och next

Anta att vi lägger till en funktion som sköter om utskriften av summan:

main.c
#include <stdio.h>

static void printsum(const int sum);

static void printsum(const int sum)
{
  printf("sum = %d\n", sum);
}

int main(void)
{
  int i;
  int sum;

  sum = 0;
  for (i = 0; i < 100; i++) sum += i;
  printsum(sum);
	
  return 0;
}

Om vi nu kompilerar om koden och laddar in den i gdb och kör next kommandot, så kommer vi märka att debuggern inte går in i funktionen printsum(). För att gå in i funktioner ska man använda kommandot step eller s i gdb. Starta om exekveringen med run eller r och prova med s istället när gdb kommer till printsum() raden. Nu kommer gdb hoppa in i funktionen printsum(). Om du har fönstret med lokala variabler öppet (locals) så kommer du också märka att det automatiskt uppdateras när du kliver in i printsum(). Variablerna i och sum försvinner, då dessa inte är synliga i funktionen printsum().

Databrytpunkt

Anta att vi är intresserade att stanna exekveringen när en variabel ändrar värde, men inte vet var i koden den ändras. Då är en databrytpunkt perfekt. Anta följande kod:

main.c
int a = 0;

void foo(void);

void foo(void)
{
  a++;
}

int main(void)
{
  int i;

  for (i = 0; i < 100; i++)
    if (i == 57) foo();
  
  return 0;
}

Kompilera koden och starta upp debuggningen i emacs. Gå till main() rutinen. Kör sedan kommandot:

user $ watch a

För att sätta en brytpunkt då a ändras. Fortsätt sedan exekveringen genom att köra kommandot:

user $ c

som är en förkortning för kommandot continue.

Exekveringen ska stanna i funktionen foo(), eftersom där räknas a upp med ett.