2017-11-09 1 views
1

Auf einigen meiner Systeme verhält sich GDB, während ich sehr einfachen Code debugge, anders als erwartet. Auf manchen Systemen "guckt" gdb bei Standard-Bibliotheksaufrufen "über". Auf anderen Systemen geht 'Schritt' in die Maschinensprache jedes Bibliotheksaufrufs über.Warum wechselt GDB "Schritt" in die Maschinensprache des Standardbibliotheksaufrufs?

Zunächst wird ein Beispiel für das Verhalten ich von GDB gewohnt bin:

$ gdb ./testapp 
GNU gdb (GDB) CentOS (7.0.1-45.el5.centos) 
(...) 
(gdb) break main 
Breakpoint 1 at 0x80483b6: file testapp.c, line 6. 
(gdb) run 
Starting program: ./testapp 

Breakpoint 1, main() at testapp.c:6 
6    char str[] = {"Test string"}; 
(gdb) step 
8    printf("String: %s\n", str); 
(gdb) 
String: Test string 
9    printf("Len: %zu\n", strlen(str)); 
(gdb) 
Len: 11 
10    return 0; 
(gdb) 

Hier ist ein Beispiel von GDB tritt in die printf() an die Maschinensprache Schritte. Hier

$ gdb ./testapp 
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-92.el6) 
(...) 
(gdb) break main 
Breakpoint 1 at 0x40050c: file testapp.c, line 6. 
(gdb) run 
Starting program: ./testapp 

Breakpoint 1, main() at testapp.c:6 
6    char str[] = {"Test string"}; 
(gdb) step 
8    printf("String: %s\n", str); 
(gdb) 
__printf (format=0x400668 "String: %s\n") at printf.c:30 
30  { 
(gdb) 
34  va_start (arg, format); 
(gdb) 
35  done = vfprintf (stdout, format, arg); 
(gdb) 
_IO_vfprintf_internal (s=0x383958f040, format=0x400668 "String: %s\n", ap=0x7fffffffe330) at vfprintf.c:236 
236  int save_errno = errno; 
(gdb) 
201  { 
(gdb) 
236  int save_errno = errno; 
(gdb) 
1283  ORIENT; 
(gdb) 
1287  ARGCHECK (s, format); 
(gdb) 
1298  if (UNBUFFERED_P (s)) 
(gdb) 
1309  __va_copy (ap_save, ap); 
(gdb) 
1320  f = lead_str_end = __find_specmb ((const UCHAR_T *) format); 
(gdb) 
__find_specmb (s=0x383958f040, format=0x400668 "String: %s\n", ap=0x7fffffffe330) at printf-parse.h:109 
109  return (const unsigned char *) __strchrnul ((const char *) format, '%'); 
(gdb) 
_IO_vfprintf_internal (s=0x383958f040, format=0x400668 "String: %s\n", ap=0x7fffffffe330) at vfprintf.c:1309 
1309  __va_copy (ap_save, ap); 
(gdb) 
1320  f = lead_str_end = __find_specmb ((const UCHAR_T *) format); 
(gdb) 
__find_specmb (s=0x383958f040, format=0x400668 "String: %s\n", ap=0x7fffffffe330) at printf-parse.h:109 
109  return (const unsigned char *) __strchrnul ((const char *) format, '%'); 
(gdb) 
strchrnul() at ../sysdeps/x86_64/strchrnul.S:27 
27    movd %esi, %xmm1 
(gdb) 
28    movq %rdi, %rcx 
(gdb) 
29    punpcklbw %xmm1, %xmm1 
(gdb) 

ist die Quelle für "testapp.c":

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

int main(){ 
     char str[] = {"Test string"}; 

     printf("String: %s\n", str); 
     printf("Len: %zu\n", strlen(str)); 
     return 0; 
} 

Das Programm kompiliert wurde, in beiden Umgebungen, wie folgt:

cc -g -o testapp testapp.c 

Dies ist meine erste Frage auf Paketüberfluss! Jede Hilfe würde sehr geschätzt werden! Vielen Dank!

+0

Auf RedHat-Familiensystemen wie CentOS werden Debugging-Symbole in separate Pakete von der Hauptanwendung oder der Hauptbibliothek getrennt. Für die 'printf()' -Funktion und andere aus der C-Standard-Bibliothek, das Hauptpaket heißt "glibc", und die Debug-Symbole sind in "glibc-debuginfo". Die erstere wird immer installiert sein, aber die letztere ist möglicherweise nicht auf einigen Systemen. –

+0

John! Du bist mein Held! Ich habe die Pakete gefunden, auf die Sie verwiesen haben, und habe sie folgendermaßen entfernt: '' yum remove glibc-debuginfo-common.x86_64 glibc-debuginfo.x86_64''. Ich habe meine GDB-Sitzung erneut ausgeführt, und diese Aufrufe werden nicht mehr ausgeführt. Vielen Dank! – ChrisHem

Antwort

1

John Kommentar auf den ursprünglichen Beitrag genagelt es.

Ich habe festgestellt, dass die Maschine, die in die Bibliotheken trat, zwei Debugging-Pakete installiert hatte: glibc-debuginfo und glibc-debuginfo-common.

Nach dem Entfernen von ihnen mit yum remove glibc-debuginfo glibc-debuginfo-common funktioniert GDB jetzt so, wie ich es erwartet hatte!

Vielen Dank, John!

3

Sie sehen nicht "Maschinensprache". Sie sehen den Quellcode der Bibliothek.

Auf einigen Computern ist die Bibliothek offenbar mit Debug-Informationen und Quellcode installiert. Durch einen "Schritt" auf dieser Maschine wird der Vorgang eingeleitet. Auf einer anderen Maschine ist die Bibliothek offensichtlich nicht mit Debug-Informationen installiert, so dass der "Schritt" -Befehl über sie geht.

Hinweis: Der Befehl "step" sollte in jedem Fall in die Bibliothek gehen. Wenn kein Quellcode vorhanden ist, sollten Sie die (reale) Maschinensprache sehen. Es scheint, dass gdb das nicht tut (VS tut es).

+0

Paul, Vielen Dank für die Antwort. In meinem Beispiel wurde nicht die tatsächliche Maschinensprache angezeigt, sondern es wurde gezeigt, wie GDB in einen Bibliotheksaufruf trat, während dies auf der anderen Maschine nicht der Fall war. Ich behielt den ersten Beitrag kurz, da ich nicht allzu viele Informationen liefern wollte, aber ich versichere Ihnen, dass GDB zu den Maschinensprachenschritten zurückkehren würde. Ich habe den ursprünglichen Beitrag mit weiteren Details aktualisiert, einschließlich der Schritte in der Maschinensprache. – ChrisHem

+0

Chris, ich sehe immernoch nur C Sprache, nicht Maschinensprache wie 'push bp; bewegen bp, sp' –

+0

Blick in Richtung auf den Grund des zweiten Codeblocks: '' 27 MOVD% esi,% XMM1 (GDB) 28 movq% RDI, RCX % (GDB) 29 punpcklbw XMM1%,% xmm1 '' – ChrisHem

0

Sie scheinen ein falsches Verständnis für "Schritt" und "nächste" Befehle zu gdb zu haben.

‚Stufe‘ versucht, die nächste Zeile des Codes in dem Ausführungspfad (ihre volle Name ist ‚Schritt in auszuführen‘.

‚next‘ versucht, die Codezeile nach der aktuellen auszuführen (es hört nicht in einer aufgerufenen Funktion auf.)

Verwandte Themen