Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: bo-os am 04. July 2009, 17:48

Titel: Mein gcc spinnt...
Beitrag von: bo-os 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 ;-)
Titel: Re: Mein gcc spinnt...
Beitrag von: kevin 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 ε.
Titel: Re: Mein gcc spinnt...
Beitrag von: bo-os 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!
Titel: Re: Mein gcc spinnt...
Beitrag von: MNemo 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.
Titel: Re: Mein gcc spinnt...
Beitrag von: Jidder 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.
Titel: Und die Moral von der Geschicht: ich spinne und gcc nicht ;-)
Beitrag von: bo-os 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.
Titel: Re: Mein gcc spinnt...
Beitrag von: bo-os 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 ;-)
Titel: Re: Mein gcc spinnt...
Beitrag von: kevin 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.
Titel: Re: Mein gcc spinnt...
Beitrag von: MNemo 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).