Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλημέρες,

 

έχω τον παρακάτω κώδικα:

 

 

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

int main(void)
{
    char str_a[20];

    strcpy(str_a, "Hello, world!\n");
    printf(str_a);

    return 0;
}

 

 

 

Τον κάνω compile με αυτή την εντολή:

 

 

gcc -ggdb3 -o char_array2 char_array2.c

 

 

 

Θέλω να τον τρέξω στο gdb και να βάλω ένα breakpoint στην strcpy. Έλα όμως που δε λέει να την εντοπίσει. Ορίστε η ροή στον gdb:

 

 

 gon1332@localhost ⮀ ~/Hacking_2nd_edition ⮀ gdb -q ./char_array2
Reading symbols from /home/gon1332/Hacking_2nd_edition/char_array2...done.
(gdb) list
1	#include <stdio.h>
2	#include <string.h>
3	
4	int main(void)
5	{
6	    char str_a[20];
7	
8	    strcpy(str_a, "Hello, world!\n");
9	    printf(str_a);
10	
(gdb) break 7
Breakpoint 1 at 0x400514: file char_array2.c, line 7.
(gdb) break strcpy
Function "strcpy" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y   
Breakpoint 2 (strcpy) pending.
(gdb) break 9
Breakpoint 3 at 0x400536: file char_array2.c, line 9.
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400514 in main at char_array2.c:7
2       breakpoint     keep y   <PENDING>          strcpy
3       breakpoint     keep y   0x0000000000400536 in main at char_array2.c:9
(gdb) run
Starting program: /home/gon1332/Hacking_2nd_edition/char_array2 
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000

Breakpoint 1, main () at char_array2.c:8
8	    strcpy(str_a, "Hello, world!\n");
(gdb) i r rip
rip            0x400514	0x400514 <main+8>
(gdb) x/5i $rip
=> 0x400514 <main+8>:	lea    rax,[rbp-0x20]
   0x400518 <main+12>:	mov    DWORD PTR [rax],0x6c6c6548
   0x40051e <main+18>:	mov    DWORD PTR [rax+0x4],0x77202c6f
   0x400525 <main+25>:	mov    DWORD PTR [rax+0x8],0x646c726f
   0x40052c <main+32>:	mov    WORD PTR [rax+0xc],0xa21
(gdb) cont
Continuing.

Breakpoint 3, main () at char_array2.c:9
9	    printf(str_a);
(gdb) cont
Continuing.
Hello, world!
[Inferior 1 (process 5850) exited normally]

 

 

 

Βάζω συνολικά 3 breakpoints. Ένα στην γραμμή 7, ένα στην strcpy κι ένα στην γραμμή 9.

Όταν όμως εκτελώ run, εμφανίζεται το εξής warning:

warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000

Στη συνέχεια δε φαίνεται να γίνεται resolve το breakpoint της strcpy κι έτσι δεν το πιάνει.

 

Τί γίνεται σε αυτή την περίπτωση;

 

Edit: Έχω την τελευταία έκδοση gdb από aptitude (7.4.1-debian).

Δημοσ.

Γράψε εκεί ενα asm int 3 :-P

 

Πλάκα πλάκα. Το θέμα είναι όμως πως θέλω ένα breakpoint στην strcpy. Το __asm__("int3") θα το προσθέσει στη main (αφού θα το γράψω στη main).

 

Βασικά είναι λίγο άκυρο που δε μπορώ να βάλω breakpoint σε κάποια συνάρτηση που κάνω include από κάποιο άλλο αρχείο. Αυτό μπορούσα να το κάνω άλλες φορές. Ας πούμε στην printf μπορώ να βάλω κανονικά και να δουλέψει κιόλας.

Δημοσ.

Λογικά το -ggdb3 είναι ισοσύναμο με το -g3, αλλά ίσως ανάλογα την πλατφόρμα να αναφέρεται σε διαφορετικό φορμά (dwarf-2, stabs, κλπ).

 

Επίσης δεν θυμάμαι αν η "break" δουλεύει από default με function names. Δοκίμασε το με line number και λογικά θα δουλέψει.


EDIT:

 

Τώρα είδα τα error messages που σου βγάζει... νομίζω πως αναβάθμισες το gcc toolchaing στο debian, αλλά άφησες τον παλιό gdb. Από ότι ξέρω, σε Ubuntu πρέπει να κάνεις ξεχωριστά update τον gdb ώστε να ταιριάξεις την νέα εκδοση του gcc που έβαλες.

Δημοσ. (επεξεργασμένο)

Λογικά το -ggdb3 είναι ισοσύναμο με το -g3, αλλά ίσως ανάλογα την πλατφόρμα να αναφέρεται σε διαφορετικό φορμά (dwarf-2, stabs, κλπ).

 

Επίσης δεν θυμάμαι αν η "break" δουλεύει από default με function names. Δοκίμασε το με line number και λογικά θα δουλέψει.

EDIT:

 

Τώρα είδα τα error messages που σου βγάζει... νομίζω πως αναβάθμισες το gcc toolchaing στο debian, αλλά άφησες τον παλιό gdb. Από ότι ξέρω, σε Ubuntu πρέπει να κάνεις ξεχωριστά update τον gdb ώστε να ταιριάξεις την νέα εκδοση του gcc που έβαλες.

Οι εκδόσεις που έχω είναι οι εξής:

 gon1332@localhost ⮀ ~ ⮀ gdb --version
GNU gdb (GDB) 7.4.1-debian
 gon1332@localhost ⮀ ~ ⮀ gcc --version
gcc (Debian 4.7.2-5) 4.7.2

Να σημειώσω ότι τα ίδια συμβαίνουν και με -g3.

 

Από εδώ και εδώ καταλαβαίνω ότι μπορεί κανείς από default να θέσει breakpoint σε function. Εξάλλου αυτό μπορώ να το κάνω και στην printf. Στην strcpy κολλάει.

 

UPDATE:

Εγκατέστησα τον GNU gdb (GDB) 7.8.1 από source. Πλέον δε μου εμφανίζει το περίεργο μήνυμα, αλλά ακόμη δε σταματά στην strcpy. Επίσης αν βάλω breakpoint στην γραμμή της strcpy, αυτό θα αναφέρεται στο χώρο διευθύνσεων της main και όχι της strcpy, όταν δημιουργηθεί για αυτή κάποιο πλαίσιο εκτέλεσης. Όταν βρω λίγο χρόνο θα εγκαταστήσω και την τελευταία έκδοση gcc από source για να δω αν θα παίξει.

Επεξ/σία από gon1332
Δημοσ.

Είμαι σχεσόν σίγουρος πως πρόκειται για mismatch των default debugging φορμά μεταξύ gcc και gdb. Μπορείς να δοκιμάσεις να κάνεις εσύ sepcify το forma, π.χ.: -gdwarf-2, -gdwarf-3, κλπ. Δες το 1ο bullet στο changelog του gcc 4.8. Από default βγάζει dwarf-4, το οποίο με τη σειρά του διαβάζει από default ο gdb 7.5 (από ότι διαβάζω στο bullet, το gcc 4.7 βγάζει από default dwarf-2, άρα πρέπει να δεις τι διαβάζει από default ο gdb που χρησιμοποιείς και να τον "ταίσεις" ανάλογα... δες μήπως υπάρχει και κάνα flag στον gdb να διαβάζει άλλο φορμά, γιατί δεν τα θυμάμαι απ' έξω).

 

Ένας συνδυασμός που ξέρω πως δουλεύει με κοινό φορμά από default στο Ubuntu, είναι gcc 4.8.1 και gdb 7.6.1 (έχω προσωπική άποψη δηλαδή, γιατί χρειάστηκε να τα αναβαθμίσω σχετικά πρόσφατα, ξεχωριστά το καθένα).

Δημοσ.

Τον κάνω compile με αυτή την εντολή:

gcc -ggdb3 -o char_array2 char_array2.c
Θέλω να τον τρέξω στο gdb και να βάλω ένα breakpoint στην strcpy. Έλα όμως που δε λέει να την εντοπίσει. Ορίστε η ροή στον gdb:

(gdb) break strcpy
Function "strcpy" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y   

 

Το μήνυμα σου λέει ότι δεν μπορεί να βρει την συνάρτηση strcpy άρα το πρώτο που πρέπει να σου έρθει στο μυαλό είναι ότι δεν πρέπει να υπάρχει τέτοια συνάρτηση.

 

Δοκίμασε να τρέξεις

nm char_array2 |egrep "strcpy|printf" 
Λογικά θα πρέπει να πάρεις ως αποτέλεσμα "printf@@GLIBC" αλλά κανένα symbol για την strcpy.

 

Γιατί να συμβαίνει αυτό ? Γιατί ο gcc έχει υλοποιήσει εσωτερικά πολλές συναρτήσεις και επειδή η δική του υλοποίηση είναι πιο γρήγορη από αυτήν της libc (σύμφωνα με τον gcc τουλάχιστον), επιλέγει να εισάγει (κάτι σαν inlining να στο περιγράψω μπακάλικα) την δική του έκδοση οπότε το "strcpy" που ζητάς από τον gdb δεν υπάρχει.

 

Αυτό φυσικά δεν είναι η μόνη αιτία αλλά είναι η πιο πιθανή σύμφωνα με αυτό που μας περιγράφεις. Αν η εκτέλεση της nm δεν δώσει symbol για την strcpy, δοκίμασε να προσθέσεις στον gcc την παράμετρο -fno-builtin-strcpy και να ξαναδοκιμάσεις μετά το "break strcpy".

 

Edit: Ο ένας γράφει στις 02:01, ο δεύτερος στις 02:08 και ο τρίτος στις 03:24. Ύπνο δεν έχετε εσείς ? :)

  • Like 2
Δημοσ.

Ευχαριστώ πολύ.

 

@imitheos

Αυτό ήταν. Γνώριζα πως ο compiler έχει υλοποιημένες βιβλιοθήκες της C, αλλά δε μπορούσα να φανταστώ πως τις καλούσε και implicitly χωρίς κανένα note έστω.

 

@migf1

Αυτό το θέμα το έχω τώρα με (εμφανίζει warning μέσα στο gdb) με τη νεότερη έκδοση gdb. Το λύνω κάνοντας compile με -ggdbX.

Δημοσ.

Ευχαριστώ πολύ.

 

...

 

@migf1

Αυτό το θέμα το έχω τώρα με (εμφανίζει warning μέσα στο gdb) με τη νεότερη έκδοση gdb. Το λύνω κάνοντας compile με -ggdbX.

Δοκίμασε μήπως έχεις πρόβλημα και στο Valgrind (αν το χρησιμοποιείς). Ιδανικά, όταν βρεις χρόνο, φέρε όλα τα tools που χρησιμοποιείς σε εκδόσεις με κοινά defaults.

 

@pmav99: Στο Ubuntu είναι ξεχωριστά repos ο gcc και ο gdb, αν το θυμάμαι σωστά.

@imitheos: Ύπνος; Τί είναι αυτό; :lol:

Δημοσ.

Δοκίμασε μήπως έχεις πρόβλημα και στο Valgrind (αν το χρησιμοποιείς). Ιδανικά, όταν βρεις χρόνο, φέρε όλα τα tools που χρησιμοποιείς σε εκδόσεις με κοινά defaults.

 

@pmav99: Στο Ubuntu είναι ξεχωριστά repos ο gcc και ο gdb, αν το θυμάμαι σωστά.

@imitheos: Ύπνος; Τί είναι αυτό; :lol:

Στο Valgrind όλα καλά!

To αρχικό μου θέμα λύθηκε σύμφωνα με την παρατήρηση του imitheos.

Όσον αφορά τις ασυμβατότητες στα repositories μάλλον θα πρέπει να κοιτάξουμε πιο σοβαρά το LFS για να ξέρουμε και τί μας γίνεται με το σύστημά μας.

 

Καλημέρες!

Δημοσ.

Ευχαριστώ πολύ.

 

@imitheos

 

Αυτό ήταν. Γνώριζα πως ο compiler έχει υλοποιημένες βιβλιοθήκες της C, αλλά δε μπορούσα να φανταστώ πως τις καλούσε και implicitly χωρίς κανένα note έστω.

Η glibc έχει πολύ πολύπλοκο κώδικα και λαμβάνει υπόψιν της ένα κάρο αρχιτεκτονικές οπότε λογικά η έκδοση της libc είναι πιο γρήγορη από αυτήν του gcc και δεν θα έπρεπε να χρησιμοποιήσει τη δική του. Έχει όμως κάθε δικαίωμα να το κάνει.

 

Για το "implicitly χωρίς κανένα note" που λες, καλώς ή κακώς, υπάρχει μια μαγκιά στο πρότυπο που λέει ότι δεν πρέπει να παρατηρείται διαφορά μεταξύ του αρχικού κώδικα και του παραγόμενου από τον compiler. Μέσα σε αυτό το πλαίσιο, ο compiler μπορεί να κάνει ό,τι θέλει χωρίς καμία ενημέρωση. Για παράδειγμα θα μπορούσε να καλέσει την memcpy αντί για την strcpy, να καλέσει τη δική του έκδοση όπως έχει κάνει, να καλέσει κατευθείαν την puts με ένα literal και να μην εκχωρήσει καθόλου χώρο για την μεταβλητή ή 1002 άλλα πράγματα.

 

@migf1

Αυτό το θέμα το έχω τώρα με (εμφανίζει warning μέσα στο gdb) με τη νεότερη έκδοση gdb. Το λύνω κάνοντας compile με -ggdbX.

Ποια είναι η ασυμβατότητα ? Διάβασα τη συζήτηση για τα dwarf αλλά εφόσον χρησιμοποιείς -ggdb και όχι -g δεν θα έπρεπε να υπάρχει πρόβλημα. Συνήθως όταν γίνεται κάποια αλλαγή σε format (ή γενικά σε κάποιο default setting), πάντα δίνεται ο απαραίτητος χρόνος ώστε τα προγράμματα που εξαρτώνται από αυτό να περάσουν στις διανομές. Ειδικά σε τόσο δυσκίνητα project όσο ο gcc, θα έχει υποστηριχτεί το format από τα άλλα προγράμματα αιώνες πριν γίνει default.

 

Κοιτώντας το ChangeLog της διανομής μου, βλέπω ότι όντως ποτέ δεν έχει αναβαθμιστεί gdb και gcc μαζί και ποτέ δεν είχα πρόβλημα. Βέβαια διαβάζω ότι έχεις debian οπότε αν μιλάμε για debian stable, πάντα μπορείς να βασιστείς να έχει κάτι αρχαίο μέσα :)

  • Like 1
Δημοσ.

...

 

Ποια είναι η ασυμβατότητα ? Διάβασα τη συζήτηση για τα dwarf αλλά εφόσον χρησιμοποιείς -ggdb και όχι -g δεν θα έπρεπε να υπάρχει πρόβλημα. Συνήθως όταν γίνεται κάποια αλλαγή σε format (ή γενικά σε κάποιο default setting), πάντα δίνεται ο απαραίτητος χρόνος ώστε τα προγράμματα που εξαρτώνται από αυτό να περάσουν στις διανομές. Ειδικά σε τόσο δυσκίνητα project όσο ο gcc, θα έχει υποστηριχτεί το format από τα άλλα προγράμματα αιώνες πριν γίνει default.

 

Κοιτώντας το ChangeLog της διανομής μου, βλέπω ότι όντως ποτέ δεν έχει αναβαθμιστεί gdb και gcc μαζί και ποτέ δεν είχα πρόβλημα. Βέβαια διαβάζω ότι έχεις debian οπότε αν μιλάμε για debian stable, πάντα μπορείς να βασιστείς να έχει κάτι αρχαίο μέσα :)

 

Σήμερα είναι πολύ καλύτερα τα πράγματα από ότι παλαιότερα, γιατί το dwarf δείχνει να έχει επικρατήσει στις περισσότερες πλατφόρμες που χρησιμοποιούν gcc/gdb. Το -g βγάζει native format πλατφόρμας (ενδεχομένως και με ενεργοποιημένα τα gdb extensions, ανάλογα την πλατφόρμα), και το -ggdb βγάζει ειδικά για gdb. Θεωρητικά ο gdb μπορεί και τα διαβάζει όλα, αλλά εγώ προφανώς δεν τα έχω δοκιμάσει όλα. Κατά κανόνα δουλεύω με τα defaults. Εξαρτάται από την πλατφόρμα, αλλά συνήθως το -g ισοδυναμεί με το -ggdb

 

Λεπτομέρειες μπορείτε να διαβάσετε στα σχετικά docs: https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging-Options

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...