Autor Thema: Mein gcc spinnt...  (Gelesen 3223 mal)

bo-os

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« am: 04. July 2009, 17:48 »
Moin zusammen,
ich hab folgendes Problem, von dem ich glaube, dass mein Compiler (DJGPP/gcc Version 4.32) dran schuld ist.
Die Methode
void map(unsigned int* pageDirectory, void* virtual, void* physical, unsigned int flags);mappt die virtuelle Addresse auf die physische u.s.w., das klappt eigendlich ohne Probleme aber nur mit einem Trick:
Die letzten Zeilen sind:
pageTable[pageNumber] = (u32)physical & 0xFFFFF000;
if(virtual == KERNEL_HEAP) {
debug(pageTable, (p)pageNumber, physical, (p)((u32)physical & 0xFFFFF000));
}
pageTable[pageNumber] = pageTable[pageNumber] | flags;
Diese if-Abfrage ist zwar seltsam, vor allem, da sie nie "auslöst" (ich kann zu 100% sagen, dass die Funktion debug nicht aufgerufen wird, da dann der Prozessor angehalten wird), aber wenn ich die if-Abfrage weglasse, dann funktioniert die Funktion nicht mehr!

Hoffe mein Problem ist verständlich ;-)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 04. July 2009, 20:31 »
Wie äußert es sich denn, dass die Funktion nicht mehr funktioniert?

Die Wahrscheinlichkeit, dass der Compiler schuld ist, liegt ungefähr bei ε.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bo-os

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 05. July 2009, 14:00 »
das äußert sich, dass wenn die Methode mit physical=0x26000 aufgerufen wird, der entsprechende Eintrag in der PageTable nicht 0x26007, sondern 0x00007 ist, als würde
pageTable[pageNumber] = (u32)physical & 0xFFFFF000;gar nicht benutzt.

Ich hatte schonmal ein ähnliches Problem in dem Zusammenhang, nämlich in der Funktion, die die ersten 4MB auf sich selbst mappt.
Die Funktion
unsigned int count = 0;
while(count < 1024) {
   map(kernelPageDirectory, count * 0x1000, count * 0x1000, 7);
   count++;
}
hat nicht funktioniert, weil irgendwie die Veriable count nach dem Funktionsaufruf von map verändert war, aber wenn ich das geändert habe auf:
void* addr;
static unsigned int count = 0;
while(count < 1024) {
   addr = count * 0x1000;
   map(kernelPageDirectory, addr, addr, 7);
   count++
}
auf einmal schon.

Übrigens kompiliere ich mit:
gcc -ffreestanding -c -Os -o vmm.obj vmm.cbei einigen Optionen weiß ich nicht genau, was die machen - das habe ich aus einem Tutorial übernommen - vllt liegt es irgendwie daran!
« Letzte Änderung: 05. July 2009, 14:07 von bo-os »

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 05. July 2009, 14:48 »
Die Option -Os weist gcc an den Code in Bezug auf die Größe zu optimieren. Die Optimierung kann aber zu Problemen führen wenn gcc den Code nicht richtig überblicken kann.

Versuch mal mit -O0, -O1, -O2 oder -O3 statt -Os zu kompilieren.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 05. July 2009, 14:53 »
Eigentlich führt C allgemein dann zu Problemen, wenn man undefinierten Code schreibt, oder irgendwelche Bedingungen nicht einhält (Automatische Initialisierung der Variablen, Stack, ...) Das Ändern der Optimierungseinstellungen behebt nie Probleme, sondern verdeckt sie höchstens.

Ich würde einfach mal den Code disassemblieren und reingucken, was er da eigentlich macht, und auch evtl. mal die interessanten Stellen in Bochs durchsteppen.
« Letzte Änderung: 05. July 2009, 14:55 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

bo-os

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 05. July 2009, 17:53 »
So, ich hab jetzt den Fehler gefunden, und wie es zu erwarten war, war es natürlich mein Fehler, aber was das für ein Fehler war... Grund für diese "Anomalien" war, dass ich in der Funktion (die ich selber in Assembler) geschrieben habe, um freie Pages zu finden, nicht den Wert von ebx gesichert habe, weil ich als dich die geschrieben hab noch nichts von flüchtigen und nicht-flüchtigen Registern gehört hatte.
Dadurch, dass der Compiler den Code immer anders optimiert hat, war das dann zwischendurch egal und das ganze hat geklappt, und manchmal eben nicht.

hach macht das Spass über 10 Stunden nach einem so dummen Fehler zu suchen...

Aber danke, die Tips haben mir geholfen das Problem zu finden.
« Letzte Änderung: 05. July 2009, 18:02 von bo-os »

bo-os

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 05. July 2009, 19:29 »
da musst du dir bei mir keine Sorgen machen... Backups werden täglich angelegt!
Aber jetzt wars ja nicht viel zu verändern... musste ja nur an einer Stelle push ebx und pop ebx dazufügen ;-)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 05. July 2009, 19:33 »
"Backup" klingt so manuell, das ist nicht empfehlenswert. Jeder, der halbwegs ernsthaft Software entwickelt, sollte ein Versionsverwaltungssystem benutzen, zum Beispiel git oder SVN - auch wenn man allein und nur lokal entwickelt. Und dann halt regelmäßig einchecken, das ist das Backup.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 05. July 2009, 21:55 »
Aber jetzt wars ja nicht viel zu verändern... musste ja nur an einer Stelle push ebx und pop ebx dazufügen ;-)
Statt manuellem Sichern der Register mit push/pop würde ich das gcc überlassen und die Globberliste verwenden.

Denn gcc Adressiert manchmal auch in der Art: [rsp-0x10] (da ist es dann suboptimal wenn man den Stack manuell nutzt).
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

 

Einloggen