amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Falscher Speicher überschrieben - wie debuggen? [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

22.08.2005, 10:53 Uhr

MarkusPohlmann
Posts: 164
Nutzer
Hallo,

ich stehe hier vor einem grundsätzlichen Problem und benötige mal ein paar Denkansätze. Zur Info: ich nutze das StormC 4 Paket.
Nun zum Problem:
Ein Programm von mir beinhaltet eine Initialisierungsroutine, welche Grafiken lädt, die Bilddaten aufnimmt und in Arrays ablegt.
Das Programm läuft super durch, aber wenn es beendet wird, sind einige Grafiken (immer die Schliessen Buttons links oben in den WB Fenstern und weiteres)zerschossen und grundsätzlich stürzen weitere Programme, selten auch die WB ab.

Durch auskommentieren habe ich den Fehler auf diese Routine isolieren können, denn wenn die auskommentiert ist, stürzt nichts ab.

Meine Hauptfrage:

Gibt es irgendwelche Debuggingtools, welche ich nutzen könnte, um zu prüfen, wo an welcher Stelle ich die Speicherbereiche zerschiesse?

Der Debugger im StormC4 ist Mist, weil die Variablenüberwachung da nicht richtig funktioniert.

Ein Beispiel anbei:
Ich habe ein Array
ULONG Grafik[8][30*30+30];
Und das fülle ich zum Beispiel mit
MemCpy(Sourcepointer,Grafik[1],(30*30+30)*sizeof(ULONG));
Gehe ich damit falsch an die Sache ran? Array besser noch grösser allokieren? Oder besser händisch allokieren (AllocVec)?

Wäre schön, wenn mir hier jemand ein paar Tipps zum debuggen geben könnte, oder wenn jemand ein paar Debugging hilfen kennt, die die Suche nach derartigen Phänomenen erleichtern.

[ - Antworten - Zitieren - Direktlink - ]

22.08.2005, 11:04 Uhr

thomas
Posts: 7716
Nutzer
@MarkusPohlmann:

Zitat:
MemCpy(Sourcepointer,Grafik[1],(30*30+30)*sizeof(ULONG));

Wo kommt denn die Funktion her ? Ich kenne nur exec.library/CopyMem, die funktioniert so wie du es hier machst, oder c.lib/memcpy. Die geht andersrum, also memcpy(ziel,quelle,größe). Vielleicht ist das dein Problem ?

Als Debugging-Hilfen kommen Enforcer (bzw. CyberGuard oder muForce) und Mungwall in Frage. Wobei das alles nichts nützt, wenn du vollkommen in die Weiten des Alls schreibst. Mungwall schützt nur Bereiche, die kurz vor oder hinter allokierten Bereichen liegen.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

22.08.2005, 11:21 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MarkusPohlmann:
Hallo,

ich stehe hier vor einem grundsätzlichen Problem und benötige mal ein paar Denkansätze. Zur Info: ich nutze das StormC 4 Paket.
Nun zum Problem:
Ein Programm von mir beinhaltet eine Initialisierungsroutine, welche Grafiken lädt, die Bilddaten aufnimmt und in Arrays ablegt.
Das Programm läuft super durch, aber wenn es beendet wird, sind einige Grafiken (immer die Schliessen Buttons links oben in den WB Fenstern und weiteres)zerschossen und grundsätzlich stürzen weitere Programme, selten auch die WB ab.

Durch auskommentieren habe ich den Fehler auf diese Routine isolieren können, denn wenn die auskommentiert ist, stürzt nichts ab.

Meine Hauptfrage:

Gibt es irgendwelche Debuggingtools, welche ich nutzen könnte, um zu prüfen, wo an welcher Stelle ich die Speicherbereiche zerschiesse?

Der Debugger im StormC4 ist Mist, weil die Variablenüberwachung da nicht richtig funktioniert.


Das ist nur dann der Fall, wenn Du den StormC-GCC in der 68K-Variante einsetzt. Da gehen oft die globalen Variablen "unter". Bei PPC-Code funktioniert der Debugger einwandfrei.

Im Zweifelsfall sollte es für 68K-Code helfen, nur fürs Debugging mit dem StormC3-Compiler zu kompilieren, dann sind die globalen Variablen auch wieder sichtbar. Das hilft zwar nicht gerade, etwaige Compiler-Bugs zu erkennen, aber fürs Debugging im Zusammenhang mit OS- oder Bibliotheks-Funktionen reichts allemal.

Zitat:
Ein Beispiel anbei:
Ich habe ein Array
ULONG Grafik[8][30*30+30];
Und das fülle ich zum Beispiel mit
MemCpy(Sourcepointer,Grafik[1],(30*30+30)*sizeof(ULONG));
Gehe ich damit falsch an die Sache ran? Array besser noch grösser allokieren? Oder besser händisch allokieren (AllocVec)?

Wäre schön, wenn mir hier jemand ein paar Tipps zum debuggen geben könnte, oder wenn jemand ein paar Debugging hilfen kennt, die die Suche nach derartigen Phänomenen erleichtern.


Auf den ersten Blick siehts okay aus. Ich hab mal schnell gerechnet, irgendwelche Optimierungen der Speicherkopier-Funktion dürften da auch nicht zum Tragen kommen.

Ist Grafik[][] global oder lokal? Die Probleme mit dem "Zerschießen" der Gadget-Grafiken kommen häufig vor, wenn Du in einen Speicherbereich hineinschreibst, auf den mit einem nicht initialisierten Zeiger verwiesen wird.

Sollte der Fehler verschwinden, wenn Du AllocVec() benutzt, gabs ein Problem mit dem Zeiger auf das Array.

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233


[ Dieser Beitrag wurde von whose am 22.08.2005 um 11:22 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

22.08.2005, 12:01 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Zitat:
Gehe ich damit falsch an die Sache ran? Array besser noch grösser allokieren? Oder besser händisch allokieren (AllocVec)?

Ich würde sagen wenn du den Gesamten freien Speicher allokierst dann ist die Wahrscheinlichkeit schon um einiges kleiner Fremde Bereiche zu überschreiben.

Nein das sollte man nun wirklich nicht, da man so den Bug nur versucht zu fixen indem man annimmt das das zuviel davor und dahinter ausreicht.

Zum Bug selber, es könnte ggf. auch sein das MemCpy() intern CopyMemQuick() nutzt, dann wird als SIZE nicht die Menge an Bytes angegeben, sondern die Anzahl an ULONGS, mach einfach mal des sizeof(ULONG) in MemCpy() weg.

[ - Antworten - Zitieren - Direktlink - ]

22.08.2005, 13:05 Uhr

gni
Posts: 1106
Nutzer
Zitat:
MarkusPohlmann:
MemCpy(Sourcepointer,Grafik[1],(30*30+30)*sizeof(ULONG));


Ich würde eher "&Grafik[1][0]" und "sizeof(Grafik[0])" schreiben. Ich denke aber nicht, das dieses MemCpy() was zerstört. Vermutlich liegt das Array "neben" anderen Daten, und bei Änderungen dieser danebenliegenden Daten, wird das Grafikfeld beschädigt.

Gibt es eine Aufräumfunktion? Sind die Daten im Array da auch schon zerstört? Für OS-alloziierten Speicher könnte Dir MuGuardianAngel helfen.

[ - Antworten - Zitieren - Direktlink - ]

22.08.2005, 17:07 Uhr

Holger
Posts: 8116
Nutzer
Ich streich das Posting...

[ Dieser Beitrag wurde von Holger am 22.08.2005 um 17:33 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

22.08.2005, 17:25 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Holger:
Zitat:
Ich würde eher "&Grafik[1][0]" und "sizeof(Grafik[0])" schreiben.
Versteh ich nicht. Ich würde eher "Grafik" schreiben. Was soll denn das Einsetzen von unbenutzten Indizes überhaupt bringen?
Damit ich weiss, das es zwei-dimensionales Array ist und das ich die Adresse eines bestimmten Elements/Bereiches davon übergeben will.
Zitat:
Und vor allem: wieso "&Grafik[1][0]" oder "&Grafik[1]"?
Für erstes siehe oben. Ob die zweite Variante gleichwertig ist, weis ich jetzt nicht.
Zitat:
Wenn überhaupt, dann doch sowieso "&Grafik[0]" oder "&Grafik[0][0]".
Für n==0 stimmt das auch ;-) Für die Adresse des n-ten Elements muß man n auch einsetzen.
Zitat:
Sonst braucht man sich doch nicht zu wundern, wenn falsche Speicherbereiche überschrieben werden.
Mag sein. Aber das trifft hier nicht zu. Mit sizeof() bekomme ich die Größe eines Elements. Damit brauche ich nur noch eine Stelle im Code ändern.

[ Dieser Beitrag wurde von gni am 22.08.2005 um 17:25 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

22.08.2005, 17:31 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MarkusPohlmann:
Ein Beispiel anbei:
Ich habe ein Array
ULONG Grafik[8][30*30+30];
Und das fülle ich zum Beispiel mit
MemCpy(Sourcepointer,Grafik[1],(30*30+30)*sizeof(ULONG));
Gehe ich damit falsch an die Sache ran?

Sieht so aus, denn was sind "30*30+30"?
Sind auch "31*30" oder "930", aber was bedeuten sie, warum benutzt Du keine aussagekräftigen Namen?
Wenn MemCpy etwas mit "memcpy" zu tun hat, hast Du Quelle und Ziel vertauscht. Wenn das Deinen Speicher trasht, also andere Variablen als die Quelle, dann ist offenbar die Quelle auch zu klein dimensioniert, ein weiterer Grund, Bezeichner statt Zahlen-Konstanten zu benutzen. Sowohl da, wo die Quelle herkommt, als auch an dieser Stelle.
Zitat:
Array besser noch grösser allokieren? Oder besser händisch allokieren (AllocVec)?
Nein.
Wenn man nicht weiß, was man falsch macht, ist das dümmste, was man machen kann, einfach größere Arrays anzulegen. Wieviel größer müßten sie denn sein, damit das Programm läuft? Woher willst Du das wissen.
Und wieviel größer müßten sie sein, um das Vertauschen von Quelle und Ziel zu kompensieren?

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

22.08.2005, 17:38 Uhr

Holger
Posts: 8116
Nutzer
@gni:
Ich hab mein Posting gestrichen, weil ich wohl den eigentlichen Zweck des Programms nicht verstanden habe. Es bringt auch nichts, auf Grundlage dessen zu diskutieren, was wir glauben, was das Programm machen sollte.

Im Originalprogramm steht übrigens: "Grafik[1]", nicht "&Grafik[1]". Unsereins liest dort automatisch das, was wir schreiben würden (unter der o.g. Annahme, daß wir wüßten, was das Programm eigentlich machen soll).
Deshalb ist es auch so schwer, den Fehler im vermeintlich korrekt aussehenden Programm zu finden.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

22.08.2005, 20:22 Uhr

geit
Posts: 332
[Ex-Mitglied]

Ich hab die Erfahrung gemacht, das es sich lohnt ein eigenes ResourceTracking zu stricken. 95% der Fehler werden automatisch gefunden.

So hab ich z.B. meine eigenen Speicherallokier/freigaberoutinen, die über Listen verwaltet werden. Via interner Memwall kann ich geziehlt Ausgaben zuschalten, die mir mit MungWall und Konsorten nicht zur Verfügung stehen. Vergessene Frees werden ebenfall mit einem Hexdump gelistet. Meistens sieht man schon auf den ersten Blick, was der Speicher beinhaltet und wozu er gehört.

Guido Mersmann

[ - Antworten - Zitieren - Direktlink - ]

22.08.2005, 21:06 Uhr

MarkusPohlmann
Posts: 164
Nutzer
Danke schonmal für die vielen Tipps und die rege Beteiligung.
Erstmal vorweg, ja, ich habe mich verschrieben: ich verwende CopyMem.
Hätte ich Quelle und Ziel vertauscht, dann würde mein Programm trotzdem funktionieren, nur wären alle Grafiken kaputt oder schwarz.

Das nicht alles so stilvoll geschrieben ist, wie man es gerne hätte, liegt unter anderem daran, dass ich das Programm vor ein paar Jahren begonnen, zwei/drei Jahre hab liegen lassen und jetzt wieder damit anfange.
Was jetzt die Pointeradressierung angeht:

Wenn ich ein ULONG Grafik[2][30*30+30] allokiere dann ist das so gemeint:
Ich habe einen Grafikbereich 30*30 (mit einem Puffer von 30 gegen überschreibungen) und den halt zweimal allokiert (erster Index).
Ist für ein Spiel und wird dann beispielsweise so adressiert:

Grafik[SpielerID][FrameID]

Ist jetzt &Grafik[1][1] nicht gleichzusetzen mit Grafik[1]?
Beides gibt doch soweit ich weiss die Adresse des 1. Elements des zweiten Indizes zurück.
Zumindest kann das nicht grundlegend falsch sein, sonst würde das Spiel überhauptnicht funktionieren, weil dann mindestens 75% aller Grafiken nicht angezeigt werden könnten.

Ich werde die Tage wohl mal eines der genannten Debuggingtools ausprobieren und die Arrays allesamt von Hand allokieren, mal sehen ob das hilft.


[ - Antworten - Zitieren - Direktlink - ]

23.08.2005, 01:12 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Teste doch einfach statt MemCopy() die Daten per Loop zu kopieren, ob's dann immer noch Probleme gibt, eigentlich sieht das wie ich das so sehe alles OK aus, und wenn dass so ist, dann kann es auch irgendwo vorher ein Problem geben. Das mit den +30 solltest du garnicht erst machen, wie gesagt ist das nicht sehr "Intelligent". Und wenn schon, warum kopierst du den Müll absichtlich mit?

[ - Antworten - Zitieren - Direktlink - ]

23.08.2005, 09:01 Uhr

MarkusPohlmann
Posts: 164
Nutzer
Mit "Per Loop" meinst Du jetzt, ich soll Wert für Wert umkopieren um sicherzustellen mit zwei Schleifen genau innerhalb der Indizes zu bleiben? Naja, einen Versuch kann ich ja mal riskieren.

Die +30 ist eine Altlast von damals, habe ich früher häufig gemacht und hier in diesem Programm nicht zurückgebaut.
Heute mache ich sowas nur, wenn abzusehen ist, dass sich der Speicherbedarf doch noch mal vergrössern könnte (als Puffer für Updates sozusagen).

Dabei fällt mir allerdings ein, wenn ich jetzt alle Puffer auf 0 reduziere, dann müsste der Fehler theoretisch viel intensiver ans Licht treten, wenn es denn wirklich am Speicherkopieren liegt.
Ich glaube das mache ich dann gleichzeitig mit einer Umrüstung von statischem Array auf per AllocVec reservierten Speicher.
Ich glaube so arbeite ich mich auch wieder ganz nett in die Routinen von damals ein...

[ - Antworten - Zitieren - Direktlink - ]

23.08.2005, 09:30 Uhr

gni
Posts: 1106
Nutzer
Zitat:
MarkusPohlmann:
Ist jetzt &Grafik[1][1] nicht gleichzusetzen mit Grafik[1]?

Nein. Grafik[1] == &Grafik[1][0]

[ - Antworten - Zitieren - Direktlink - ]

23.08.2005, 09:46 Uhr

DariusBrewka
Posts: 899
[Benutzer gesperrt]
Zitat:
Original von MarkusPohlmann:
Heute mache ich sowas nur, wenn abzusehen ist, dass sich der Speicherbedarf doch noch mal vergrössern könnte (als Puffer für Updates sozusagen).


Naja, dann solltest du wie Holger bereits sagte lieber

code:
ULONG Image[NUMIMAGES][WIDTH*HEIGHT];


anstatt

code:
ULONG Image[8][30*30];


nehmen.

das ist noch Zukunftssicherer.


[ Dieser Beitrag wurde von DariusBrewka am 23.08.2005 um 10:53 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

23.08.2005, 10:32 Uhr

whose
Posts: 2156
Nutzer
Zitat:
Original von MarkusPohlmann:
Die +30 ist eine Altlast von damals, habe ich früher häufig gemacht und hier in diesem Programm nicht zurückgebaut.
Heute mache ich sowas nur, wenn abzusehen ist, dass sich der Speicherbedarf doch noch mal vergrössern könnte (als Puffer für Updates sozusagen).


Da wären #defines wirklich angebrachter. Erstens verschwendest Du dann nicht unnötig Speicher, zweitens werden Berechnungen der Art, wie Du sie hier machst, überschaubarer.

Zitat:
Dabei fällt mir allerdings ein, wenn ich jetzt alle Puffer auf 0 reduziere, dann müsste der Fehler theoretisch viel intensiver ans Licht treten, wenn es denn wirklich am Speicherkopieren liegt.

Nicht zwingend. Es hängt ja davon ab, wo genau "verboten" reingeschrieben wird. Meist bleibts bei Fehlern, wie Du sie beschrieben hast. Beim StormC4 merkst Du u.U., daß sich der Lister nicht mehr ganz koscher verhält, das ist meist schon alles, was dann passiert.

Zitat:
Ich glaube das mache ich dann gleichzeitig mit einer Umrüstung von statischem Array auf per AllocVec reservierten Speicher.
Ich glaube so arbeite ich mich auch wieder ganz nett in die Routinen von damals ein...


Ist sowieso empfehlenswert. Dann gewöhnst Du Dich auch gleich an die Init...()-Funktionen, z.B. für BitMaps ;)

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

23.08.2005, 13:07 Uhr

MarkusPohlmann
Posts: 164
Nutzer
Zitat:
Original von gni:
Zitat:
MarkusPohlmann:
Ist jetzt &Grafik[1][1] nicht gleichzusetzen mit Grafik[1]?

Nein. Grafik[1] == &Grafik[1][0]

Böser Tippfehler meinerseits - schon klar, dass es eine 0 im 2. Index sein muss...

[ - Antworten - Zitieren - Direktlink - ]

23.08.2005, 13:17 Uhr

MarkusPohlmann
Posts: 164
Nutzer
Ich sag mal Danke für die vielen Tipps und melde mich nach dem Test der erwähnten Debughilfen mal wieder.

Was Defines angeht, die Vorteile von Init-routinen und co möchte ich nochmal erwähnen, vor ein paar Jahren habe ich noch ganz anders programmiert, schlechter, unstrukturierter und "C-übender" - meine heutigen Programme sehen GANZ anders aus. Nur habe ich gerade in diesem Oldie das Speicherproblem und würde es gerne möglichst einfach debuggen.

Wenn ich mir drei Wochen Zeit nehme und das Programm von Grund auf neuaufarbeite wird das problem auch verschwinden - ziemlich sicher sogar - aber ich dachte mit geeigneten Debugtools und ein paar Tipps wie man solche Fehler angeht geht es auch schneller.

[ - Antworten - Zitieren - Direktlink - ]

23.08.2005, 16:01 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MarkusPohlmann:
Wenn ich ein ULONG Grafik[2][30*30+30] allokiere dann ist das so gemeint:
Ich habe einen Grafikbereich 30*30 (mit einem Puffer von 30 gegen überschreibungen) und den halt zweimal allokiert (erster Index).
Ist für ein Spiel und wird dann beispielsweise so adressiert:

Grafik[SpielerID][FrameID]

FrameID?
Dein Array ist doch nur zweidimensional, das Ergebnis wäre ein einzelner ULONG-Wert. Was bedeutet dann "Grafik" in diesem Zusammenhang?

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

23.08.2005, 19:12 Uhr

MarkusPohlmann
Posts: 164
Nutzer
Das mit dem einzelnen ULONG stimmt schon so.
Okay, die Adressierung mit FrameID ist blödsinn, aber warum passiert mir so eine Verwechslung?

Nun, ich habe bewusst nicht den Sourcecodeausschitt gepostet, sondern nur zwei Beispielzeilen, ziemlich nah an dem was im Programm steht aber ziemlich aus dem Kontext gerissen.
Ich habe das genau so gepostet, damit keine Diskussion entsteht: "Das ist aber schlechter Stil, das macht man aber anders!" sondern damit sich
die Leute auf die Grundfrage des Threads "Denkansätze und Tipps zum debuggen von Speicherproblemen" konzentrieren.
Ging ziemlich nach hinten los weil doch viele sogar diese beiden simplen Zeilen aufpeppen wollen, auch wenns das Problem nicht löst...

Aber zur Verdeutlichung etwas mehr zu meinem Programm:

Ich habe ein Array struct SchiffStruct Schiff[2].
SchiffStruct ist eine Struktur aus mehreren Teilen, unter anderem:
ULONG Grafik[FrameID][Bildgroesse]

Die Konstanten sind jetzt ebenfalls NUR BEISPIELE UND STEHEN SO NICHT IM PROGRAMMCODE!!!

Richtig hätte ich jetzt schreiben müssen:
Schiff[SpielerID].Grafik[BildID] - wobei der zweite Index von Grafik nicht weiter interessiert, weil da die Bildgrafik drinn ist.

Ich bin also aus dem Kontext gerissen mit den Indizes eins zuweit nach rechts gerutscht.
Du hast recht, FrameID im zweiten Index von Grafik macht wirklich keinen Sinn.

Würde ich übrigens den Sourccode hier posten, es würden sich einige Leute die Haare ausreissen - bzw. mir am liebsten den Kopf von den Schultern!
Zwei Jahre vor dem Attentat auf das Worldtradecenter habe ich begonnen dieses Spiel zu schreiben, ein Remake von SaveNewYork vom C64.
Damals bin ich gerade soeben von Amos auf C umgestiegen, grösstenteils unstrukturiert selbstbeigebracht - ich muss selber lachen über die Gedankenkonstrukte die ich damals im Sorucecode als "optimale" Lösung betrachtet habe.
Naja, als das Worldtradecenter eingestürzt ist, habe ich die Entwicklung vollständig eingeforen, da mir das Spiel aufeinmal selbst zu makaber erschien.
(Wer SaveNewYork nicht kennt: Man düst mit einem kleinen Flugzeug über Hochhäusern umher und beschützt diese vor Riesenfledermäusen und kleinen Monstern in der Ubahn, welche die Hochhäuser anknabbern. Es ist durchaus möglich die Gebäude zu beschiessen und/oder mit dem eigenen Flugzeug zum Einsturz zu bringen...Noch Fragen?)

Jetzt, nach all den Jahren hab ich mich mal wieder an dieses Spiel gewagt, um es als Testtreiber für meine ersten Versuche mit AHI und Subtasks zu verwenden. Und eben dabei ist mir - nach all den Jahren - dieser Memorybug aufgefallen, für den ich eine geeignete Lösung suche, wie man solch einen Fehler schneller finden kann, als die komplette Speicherverwaltung im Programm von Grund auf neu zu designen.

Lange Rede - minimaler Sinn: Ich mach mich jetzt mit den von Thomas genannten Tools mal ans Debugging und melde mich wieder ob und wie es funktioniert hat.
Danke für all die Tipps - und nein - ich poste keine weiteren Sourcezeilen aus diesem Programm, nicht eine einzige! :lach:

[ - Antworten - Zitieren - Direktlink - ]

24.08.2005, 10:37 Uhr

MarkusPohlmann
Posts: 164
Nutzer
Sorry für den Doppelpost, aber es gibt einen Fortschritt:

Auf der Suche nach Mungwall bin ich im Aminet über MuForce und MuGuardianAngel gestossen und hab letzteres Archiv mal entpackt und verwendet.

Und siehe da, es meldet Speicherverstösse und zwar recht heftig.
Aber die von mir vermuteten Arrays sind gar nicht schuld, zumindest sieht es jetzt erstmal nicht mehr danach aus (es sei denn, die überschreiben mir meinen Pointer).

Folgende Definition, global, im Quellcode mit der Mainprozedur:

UWORD *PicBuffer16=NULL;
UWORD *EmptyPic16=NULL;

in der Mainprozedur weise ich beiden mittels AllocVec FastMem zu und zwar genau gleichviel. Sollte eines dieser AllocVecs fehlschlagen, wird Clearup aufgerufen welches alle Ressourcen freigibt und aus dem Programm aussteigt. Dies passiert aber nicht.

Im Sourcefile mit den Grafikroutinen habe ich weiterhin folgendes - global - stehen:

extern UWORD *PicBuffer16;
extern UWORD *EmptyPic16;

Und jetzt schlägt MuForce alarm in einer Grafikprozedur (der fraglichen Init-Routine) beim
CopyMem(PicBuffer16,EmptyPic16,<genau gleiche Grösse in Bytes wie bei AllocVec angefordert>);
(Source und Dest sind nicht vertauscht, die Grösse ist korrekt angegeben und der Compiler schmeisst keine Warning - auch nicht bei Deklaration Allokation und Deallokation der Pointer!)
Die Warnungen von MuForce rasen einfach nur so durch, als geht alles daneben, was die anschliessenden Abstürze erklärt. Aber irgendwie bin ich jetzt überfragt warum die Allokation wohl nicht gültig ist - und warum bei dem riesen Speicherbereich - wenn er denn vollständig daneben geht - nicht noch mehr Abstürze auftreten...
Ich glaube ich stricke mein clearup mal um, dass er mehr Warings rauswirft (Führt FreeVec nur dann kommentarlos aus, wenn Pointer!=Null).

Ob ich den Pointer selbst irgendwodurch zerschiesse?
Eine Klartextsuche im Source brachte nur die oben erwähnten Verwendungen.

Noch seltsamer: Genau das gleiche Prozedere findet statt für zwei Pointer:

ULONG *PicBuffer;
ULONG *EmptyPic;

Da geht nichts schief ob wohl die Kommandos die gleichen sind (werden entsprechend mit doppelter Byteanzahl gefüllt - alle ULONGs erhalten 24 Bit Grafiken, die UWORDs 16Bit Grafiken.
Naja, heute Nachmittag geht's Debugging weiter, aber ich glaube dank der Tools bin ich einen entscheidenden Schritt weiter. Oder sie führen mich an der Nase herum... :dance3:

[ - Antworten - Zitieren - Direktlink - ]

24.08.2005, 11:13 Uhr

gni
Posts: 1106
Nutzer
Zitat:
MarkusPohlmann:
extern UWORD *PicBuffer16;
extern UWORD *EmptyPic16;

Und jetzt schlägt MuForce alarm in einer Grafikprozedur (der fraglichen Init-Routine) beim CopyMem(PicBuffer16,EmptyPic16,<genau gleiche Grösse in Bytes wie bei AllocVec angefordert>);

Dann gibt doch die Zeiger sowohl nach den AllocVec() und direkt vor diesem CopyMem() mit kprintf() aus.

[ - Antworten - Zitieren - Direktlink - ]

24.08.2005, 20:24 Uhr

MarkusPohlmann
Posts: 164
Nutzer
Uff - Fehler gefunden!
Es lag doch noch woanders drann, genau eine Zeile tiefer im Sourccode und fiel mir erst auf, als ich hinter jeden Befehl einen Tastendruck zum Warten eingebaut habe...
(Meine Debuganzeige passte nicht zum Tempo des Debuggens weil die Ausgabe gepuffert war - super DAD (Dümster anzunehmender Debugger).

Und, was war es für ein simpler Blödsinn?
Ein weiterer globaler Pointer, allokiert nie Speicher, wird nie freigegeben - mein Ressourcentracking klappt eben doch bestens. :lach:

Sondern nach dem Initialisieren sperre ich die Bitmap für die Grafiken, biege den Pointer auf die Bitmap und kopiere mein Frame direkt rein.
Nach dem initialisieren...
Während ist die Bitmap weder gesperrt noch zeigt der Pointer drauf.

War mir vor ein paar Jahren nicht aufgefallen, was ich da für einen Blödsinn mache - und vor wenigen Tagen noch viel weniger.

Abschliessend kann ich sagen: MuForce und MuGuardianAngel haben mir einen kompletten Rewrite ersparrt!
Kann ich also jedem nur ans Herzlegen der mal ähnliche Speicherprobleme hat.

Danke nochmal an alle für die Tipps.

Jetzt schalte ich noch den zweiten Spieler frei und dann gibt es eventuell in ein/zwei Wochen ein Preview (jetzt wo ich nix mehr zum Absturz bringe...)!

[ - Antworten - Zitieren - Direktlink - ]

24.08.2005, 20:58 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MarkusPohlmann:
Abschliessend kann ich sagen: MuForce und MuGuardianAngel haben mir einen kompletten Rewrite ersparrt!
Kann ich also jedem nur ans Herzlegen der mal ähnliche Speicherprobleme hat.

So, wie Du den Zustand Deines Codes beschrieben hast, klingt das nicht unbedingt wie ein wirklicher Vorteil...

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

24.08.2005, 22:10 Uhr

MarkusPohlmann
Posts: 164
Nutzer
Scherzbold.
Ich könnte ja deine Signatur unter meinen Source hängen! :lach:




[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Falscher Speicher überschrieben - wie debuggen? [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.