Autor Thema: c / c++ Debuggen  (Gelesen 10593 mal)

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« am: 01. September 2009, 19:32 »
Ich suche eine möglichkeit besser zu debuggen sprich inerhalb von c / c++ Funktionen wie z. B. bei beim gdb mit exen möglich ist.
Ich hab gelesen, das dass in verbindung mit Qemu möglich ist, jedoch kenne ich mich mit Qemu nicht so richtig aus (ich benutze eigentlich bochs). Mit Qemumanger unter Windows ist das einfache starten ja nicht schwer nur wie der lokalen Server einrichtet wird weis ich nicht, nur dass ich irgendwie den –s Paramter hinneinbekommen muss.
Ein Konsolenbefehl, in dem ich –s hineingefügt habe sieht so aus, nur weis ich nicht wie ich merke, dass das funktioniert hat.
"D:\Programme\QemuManager\qemu\qemu.exe" -L "D:\Programme\QemuManager\qemu" -M "pc" -m 32 -cpu "qemu32" -vga cirrus -serial vc -parallel vc -name "h_os" -drivefile="D:\Programme\Bochs-2.3.7\h_os\h_os.img",index=0,if=floppy -boot a -soundhw es1370 -net nic,vlan=0,model=rtl8139 -net user,vlan=0  -vnc :1 -k de -usbdevice tablet -localtime
« Letzte Änderung: 01. September 2009, 20:19 von Hauke »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 01. September 2009, 19:45 »
Also erstmal heißt das Ding nicht Qmeu, sondern qemu ("emu" wie in "Emulator"). ;)

Um den gdb-Stub zu aktivieren gibt es zwei Möglichkeiten. Die eine ist, wie du schon selber herausgefunden hast, -s zu übergeben, die andere ist, im Monitor gdbserver einzugeben. Daraufhin startet qemu einen Server auf Port 1234, auf den man mit gdb verbinden kann. Dazu gdb mit der passenden Binary starten (z.B. deinem Kernel) und target remote localhost:1234 eingeben (oder kurz tar re :1234). Anschließend ganz normal debuggen. Kernel debuggen geht auf diese Weise ganz gut, Programme sind problematischer, weil er ständig in den Kernel springt und dann keine Informationen über die aktuelle Adresse hat.

Dazu hatten wir auch mal einen Artikel im Wiki, wo ist der denn hingekommen? :|
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 02. September 2009, 18:59 »
OK  erst einmal noch einmal zum Aufruf.
qemu -L .\ -fda h_os.img -m 32 -s -S (nur um noch mal sicher zu gehen)
Ich schätze er macht das dann auch was er tun soll.

und zum gdb aufruf:
(gdb) file h_os.img
..h_os.img": not in executable format: File format not recognized
Gibt er das aus.

Es ist mir klar was das bedeuten soll, nur wie mach ich das damit gdb das akzeptiert?
Und der andere Befehl geht auch nicht (liegt wohl daran dass der erste Befehl nicht geht)
(gdb)  target remote localhost:1234
localhost:1234: No such file or directory (ENOENT).

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 02. September 2009, 19:05 »
(gdb) file h_os.img
..h_os.img": not in executable format: File format not recognized
Gibt er das aus.

Es ist mir klar was das bedeuten soll, nur wie mach ich das damit gdb das akzeptiert?
IIRC must du deine "kernel.sys" angeben, nicht das Image.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 02. September 2009, 19:46 »
Zitat
IIRC must du deine "kernel.sys" angeben, nicht das Image.
Zitat
Was ist der "kernel.sys"
Also es gibt zwei Teile Bootloader ,Startteil des OS (PM usw.) und dann der C++ Teil der halt gelinkt. Dort sollten dann auch die Debuginformationen enthalten sein und wenn ich diesen Teil mit file … übergebe geht das auch nicht.

Ich weis ja nicht was genau gemeint ist.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 02. September 2009, 20:12 »
Ah… ich bin von GRUB und ELF-Kernel ausgegangen.

Du musst eine ungestripte Objectdatei(ELF o.ä.) angegeben (ich vermute mal, dass sie statisch gelinkt sein muss), die die Debuginformationen enthält.
GDB muss aus der Datei ja die Symboltabllen usw. rauslesen können.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 12. September 2009, 12:17 »
OK da ich ja das ELF Format brauche, hab ich das jetzt fast hinbekommen nur beim Linken noch nicht ganz.
Folgende Fehlermeldung hab ich noch. Dazu sei noch gesagt, dass ich das C++ Kernel  Tutorial benutzt habe.
i586-elf-ld -shared-ffreestanding -T Link.ld -o Kernel.bin
Kernel.o: In function `__static_initialization_and_destruction_0(int, int)':
Kernel.cpp:11: undefined reference to `___dso_handle'
Kernel.cpp:11: undefined reference to `___cxa_atexit'
Kernel.cpp:13: undefined reference to `___dso_handle'
Kernel.cpp:13: undefined reference to `___cxa_atexit'
Kernel.cpp:15: undefined reference to `___dso_handle'
Kernel.cpp:15: undefined reference to `___cxa_atexit'
 

Mit diesem Aufruf  ohne den Schaltern -fleading-underscore hatte ich ähnliche Fehlermeldungen nur. Das betraf (soweit ich das gesehen habe) C Funktionsaufrufe von Assembler aus.

Hier noch einmal Ausschnitte der Aufrufe der Objekt Dateien.
nasm -f elf -o kernel32.obj kernel32.asm
i586-elf-g++ -x  c++ -c Kernel.cpp -g -m32  -fleading-underscore -ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions –Wall

Am an Anfang des Linker Scipts bin ich mir noch nicht sicher ob OUTPUT_FORMAT(elf32-i386) oder OUTPUT_FORMAT("binary") hinnein soll.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 12. September 2009, 14:52 »
i586-elf-ld -shared-ffreestanding -T Link.ld -o Kernel.bin
Ich halte es für unwahrscheinlich, dass du wirklich -shared willst.

Zitat
Am an Anfang des Linker Scipts bin ich mir noch nicht sicher ob OUTPUT_FORMAT(elf32-i386) oder OUTPUT_FORMAT("binary") hinnein soll.
Egal, was die Frage ist, flache Binaries sind für Code immer die falsche Antwort.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 12. September 2009, 15:12 »
OK ich hab das jetzt wieder so i586-elf-ld -T Link.ld -o Kernel.bin(wie ich das vorher hatte), nur der Fehler ist noch der gleiche. (natürlich ist der Parameter wohl nicht der Grund des Fehlers)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 12. September 2009, 15:21 »
Dann musst du sie wohl selber definieren, siehe http://lowlevel.brainsware.org/wiki/index.php/C++
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 12. September 2009, 15:53 »
Mit selber schreiben sind wohl die Funktionen dso_handle, … gemeint nur im nicht ELF Format (also vorher) hat er die Funktionen gekannt, das ergibt für mich nicht so einen richtigen Sinn.  :?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 12. September 2009, 16:30 »
Ich nehme nicht an, dass er sie gekannt hat. Er hat wahrscheinlich nur anderen Code erzeugt, der diese Symbole nicht benutzt.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 12. September 2009, 18:46 »
Ich denke das liegt am Linker Scipt, die Funktionen müssen da nur anders heißen.
...
ENTRY(start)
SECTIONS
{
.text 0x10200 :
{
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data :
{
__CTOR_LIST__ = .; LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
*(.ctors) LONG(0) __CTOR_END__ = .;
__DTOR_LIST__ = .; LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
*(.dtors) LONG(0) __DTOR_END__ = .;

data = .; _data = .; __data = .;
*(.data)
. = ALIGN(4096);
}

.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}

end = .; _end = .; __end = .;
}
Nur weis ich nicht genau in was ich das ändern muss (also wie das aussehen soll)

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #13 am: 13. September 2009, 03:26 »
Du musst im Prinzip nur start_ctors bzw. end_ctors aus dem Code von lowlevel-wiki: C++ durch __CTOR_LIST__ und __CTOR_END__ ersetzen (wobei ich kA hab was genau du da mit dem ganzen "LONG" machst. Das erscheint mir überflüssig. Ich selbst verwende: Linkerscript
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 13. September 2009, 17:59 »
OK das geht jetzt wieder nur das mit dem gdb noch nicht welche Datei muss ich da denn jetzt angeben.
(gdb) file …
… Kernel.o": not in executable format: File format not recognized
Er gibt diese Fehlermeldung bei alle Dateien aus.

Was noch sein kann, dass GDB mit falschen Einstellungen gestartet wird. Hier die Präambel.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=i386-pc-msdosdjgpp --target=djgpp"..."

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 13. September 2009, 18:45 »
Du solltest nicht den DJGPP nutzen. Der GDB von MinGW sollte ELF können.
Dieser Text wird unter jedem Beitrag angezeigt.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 15. September 2009, 16:44 »
OK das lag wirklich am falschen GDB.
Nur habe ich noch folgende Probleme:

Damit der gdb die gesamte Symboltabelle hat linke ich auch noch mit  OUTPUT_FORMAT(elf32-i386), die ich dann mit file … lade. Einzeln kann ich sie auch laden, nur die Objektdatein von NASM nicht. (siehe aufruf oben)
Reading symbols from kernel32.obj...(no debugging symbols found)...done.
Dann wird nicht bei einem Breakpoint auf z. B. auf die Main Funktion angehalten.
(gdb) file Kernel.bin
Reading symbols from Kernel.bin...done.
(gdb) break main
Breakpoint 1 at 0x108be: file Kernel.cpp, line 34.
Jedoch funktionier das wenn ich einen breakpoint auf eine direkte Adresse setze wie z. B.
(gdb) break 0x10200
Function "0x10200" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Ich denke das geht auch nur wie.  :?

Der veränderte Funktionsumfang, hat wohl, mit dem Modus zu tun, in dem der GDB läuft.
(gdb) run
The "remote" target does not support "run".  Try "help target" or "continue".
Der Qemu Monitor füllt diese Lücke ja wieder auf.

 

Einloggen