ENGLISH VERSION |
|
Links | | | Forum | | | Kommentare | | | News melden |
Chat | | | Umfragen | | | Newsticker | | | Archiv |
amiga-news.de Forum > Programmierung > gcc und Messages aargh | [ - Suche - Neue Beiträge - Registrieren - Login - ] |
-1- | [ - Beitrag schreiben - ] |
27.03.2004, 16:14 Uhr Inferno Posts: 157 Nutzer |
Hi, habe hier ein Problem mit gcc. Ich habe die GoldED - Installation von gcc drauf. Wenn ich folgendes kleines Programm compiliere, stürzt mir der Rechner gnadenlos ab: ------ #include <proto/exec.h> #include <proto/dos.h> #include <dos/dostags.h> #include <stdio.h> #include <clib/alib_protos.h> MsgPort *port = NULL; void __saveds threadProc() { Delay(20); Message *msg = new Message; PutMsg(port, msg); Delay(20); // Allow message to be received!! delete msg; return; } int main() { if((port = CreatePort(NULL, 0))) { struct Process *proc = CreateNewProcTags(NP_Entry, (long unsigned int)threadProc, NP_StackSize, 16384, NP_Name, (long unsigned int)"Thread1", TAG_END); if(proc) { WaitPort(port); printf("Message arrivedn"); } DeletePort(port); } } ----- mit c++ test.cpp compiliert und a.out ausgeführt. Dann sehe ich gerade noch "Message arrived" im Shell-Fenster und dann den Absturz. Was mache ich hier falsch? Danke im voraus, Inf! [ - Antworten - Zitieren - Direktlink - ] |
27.03.2004, 16:43 Uhr Mad_Dog Posts: 1944 Nutzer |
Wie wär's mit return 0? -- http://www.norman-interactive.com [ - Antworten - Zitieren - Direktlink - ] |
27.03.2004, 16:49 Uhr Inferno Posts: 157 Nutzer |
Kleiner Nachtrag: Wenn ich in der "threadProc" die Zeile "delete msg" auskommentiere, funktionierts!!!!! *grübel* [ - Antworten - Zitieren - Direktlink - ] |
27.03.2004, 17:18 Uhr thomas Posts: 7717 Nutzer |
Du solltest dir ein vernünftiges Protokoll ausdenken, mit dem du sicherstellst, daß 1. Speicher nicht freigegeben wird, wenn er noch benutzt wird 2. das Programm nicht verlassen wird, bevor alle Subtasks beendet sind. D.h. dein Thread sollte einen Reply-Port öffnen und warten, bis die Haupttask die Message beantwortet (GetMsg+ReplyMsg). Weiter sollte dein Hauptprogramm am Ende prüfen, ob die Subtask beendet wurde und ggf. warten, bis es soweit ist. Hier ist ein funktionierendes Beispiel: http://home.t-online.de/home/thomas-rapp/download/multi.c Gruß Thomas -- Email: thomas-rapp@web.de Home: home.t-online.de/home/thomas-rapp/ [ - Antworten - Zitieren - Direktlink - ] |
27.03.2004, 18:25 Uhr Inferno Posts: 157 Nutzer |
Hallo Thomas, danke für die Info. Dein Programm funktioniert so weit. Aber sobald ich aus der Message einen Pointer mache und diesen vor jedem senden "new"e und nach dem Delay wieder "delete", stürzt er beim ersten "delete" ab.... Komisch... Gruß, Inf. [ - Antworten - Zitieren - Direktlink - ] |
27.03.2004, 18:27 Uhr Inferno Posts: 157 Nutzer |
Noch was anderes: er findet die "proto/alib.h" nicht, ich muss stattdessen immer "clib/alib_protos.h" verwenden. Auch auf der OS 3.5 developer CD ist die alib.h nicht drauf. Wo kriege ich die her?? Gruß, Inf [ - Antworten - Zitieren - Direktlink - ] |
27.03.2004, 18:34 Uhr thomas Posts: 7717 Nutzer |
Zitat: Vermutlich ist C++ nicht reentrant. Versuch's mal mit AllocVec() und FreeVec(). Du kannst aus dem gleichen Grund in Subtasks auch nicht printf() verwenden, aber dos.library/Printf() funktioniert. Zitat: proto/xy.h ist nur eine Kombination aus xy_protos.h und xy_pragmas.h. Da es für die alib keine Pragmas gibt (ist ja keine externe Library, sondern eine Linker-lib), gibt es auch kein proto/alib.h. Fazit: für die alib mußt du immer nur clib/alib_protos.h einbinden (und sicherstellen, daß der Linker die amiga.lib einbindet). Gruß Thomas -- Email: thomas-rapp@web.de Home: home.t-online.de/home/thomas-rapp/ [ - Antworten - Zitieren - Direktlink - ] |
27.03.2004, 18:41 Uhr Inferno Posts: 157 Nutzer |
Hallo Thomas, genau das wars.... Jetzt habe ich nur ein Problem: Ich muß alle "news" & "deletes" in einem 200000 Zeilen StormC Quellcode in AllocVec/FreeVec ändern. Klingt schwer nach "Operatoren überladen"! Vielen Dank für den Tip! Kriegst auch Credits im Fertigen Produkt Inf. [ - Antworten - Zitieren - Direktlink - ] |
27.03.2004, 22:08 Uhr Inferno Posts: 157 Nutzer |
Hi, Wenn das wirklich so ist, daß new und delete nicht reentrant sind, was mache ich denn dann bei Objekten? Sprich, wie rufe ich Konstruktor und Destruktor auf, wenn ich alles über AllocVec / FreeVec realisiere? Ich habe eher das gefühl, daß ich falsche / alte Libraries habe. Die amiga.lib hier ist Version 45.3 und 226852 bytes groß. [ - Antworten - Zitieren - Direktlink - ] |
27.03.2004, 22:20 Uhr Holger Posts: 8116 Nutzer |
Zitat:Ich glaube nicht, daß das Problem dort liegt. Hast Du, nach der Änderung des Beispielprogramms von statisch zu dynamisch erzeugten Messages auch die Stelle mit der Message-Länge (sizeof(...)) geändert? Und an welcher Stelle in dem Programm hast Du die new und delete Anweisungen eingefügt? mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
27.03.2004, 22:57 Uhr Inferno Posts: 157 Nutzer |
Hallo Holger, Du kannst meinen kurzen Code von oben nehmen. Ersetze das new/delete durch eine statische Message (auf dem Stack) und es funktioniert. Mit new & delete gibts 'nen crash. Ich habe Thomas' multi.c wie folgz verändert: 1) Bei der Definition statt "struct Message mymsg" eben struct Message *mymsg" 2) Nach dem "DateToStr(&dt);" - Aufruf eine Zeile "mymsg = new Message" eingefügt. 3) alle mymsg. - referenzen in mymsg-> geändert 4) Bei PutMsg anstat &mymsg nur mymsg 5) Nach der Zeile "Delay(50)" Eine Zeile "delete mymsg;" eingefügt Und schon kommt der crash Gruß, Inf. Ups, vergessen: Natürlich habe ich auch die Länge in sizeof(struct Message) geändert [ Dieser Beitrag wurde von Inferno am 27.03.2004 editiert. ] [ - Antworten - Zitieren - Direktlink - ] |
28.03.2004, 00:49 Uhr whose Posts: 2156 Nutzer |
Ich weiß, ich werde bestimmt wieder verbal gesteinigt, weil ich das sage, aber: Mit StormC3 compiliert läufts einwandfrei, auch wenn das kleine Prog alles andere als sauber ist. Ist eine der "Merkwürdigkeiten", die der GCC in seiner 68K-Variante schon ne Ewigkeit mit sich rumschleppt. Der 2.95.2 macht da auch ein absturzfreudiges Programm draus. Der delete-Operator hat wohl ein generelles Problem mit lokalen Variablen. Im übrigen erfolgt der Absturz erst bei Austritt aus dem Hauptprogramm, also beim cleanup. Vielleicht sollte man Heinz Wrobel mal zu diesem Problem befragen, er hat bestimmt eine Lösung dafür parat. Grüße [ - Antworten - Zitieren - Direktlink - ] |
28.03.2004, 19:51 Uhr Inferno Posts: 157 Nutzer |
Problem gelöst, funzt jetzt auch mit new & delete !!! Problam war (wie so oft) benutzerfehler Gruß, Inf. [ - Antworten - Zitieren - Direktlink - ] |
29.03.2004, 01:02 Uhr whose Posts: 2156 Nutzer |
Teilst Du uns denn auch noch mit, was genau das Problem war? Ich komme da nämlich jetzt nicht so einfach drauf. Wäre nett! Grüße [ - Antworten - Zitieren - Direktlink - ] |
29.03.2004, 04:12 Uhr whose Posts: 2156 Nutzer |
Ich weiß zwar nicht, was Inferno verkehrt gemacht hat, aber bei mir läufts jetzt auch, nachdem ich bei seinem kleinen Prog die Logik ein bißchen verändert hab So, wie das Prog da oben steht, beendet der Vaterprozess, bevor der Kindprozess beendet (der wartet nämlich ein bißchen, während der Vaterp. munter weiterläuft und sich beendet). Das haut dann natürlich nicht mehr hin, weil zu dem Zeitpunkt bereits alle Daten des Programms (inkl. Subprozess und zu delete nde msg) aus dem Speicher verschwunden sind. Also nicht die Merkwürdigkeit vom GCC *stirnklatsch* Grüße [ - Antworten - Zitieren - Direktlink - ] |
29.03.2004, 10:20 Uhr Inferno Posts: 157 Nutzer |
Hi whose, -noixemul hat bei mir geholfen. Hatte es schlicht im Makefile vergessen.... Der Code-Ausschnitt oben war nur ein sehr kleiner aus 'nem riesigen Projekt, aber der Absturz kam auch, wenn man in der main-Prozedur noch auf das Beenden des Sub-Prozesses wartet. Lag eindeutig an der delete-Funktion.... und natürlich am vergessenen noixemul. Gruß, Inf. [ - Antworten - Zitieren - Direktlink - ] |
29.03.2004, 10:41 Uhr whose Posts: 2156 Nutzer |
Zitat: Ah, okay, danke. Ich hatte es auch mit dem StormC4-GCC probiert, der arbeitet defaultmäßig ohne ixemul. Jetzt wäre nur noch interessant zu wissen, in wie weit ixemul den delete-Operator des GCC3.x beeinflußt, daß sowas passieren kann... Grüße [ - Antworten - Zitieren - Direktlink - ] |
29.03.2004, 14:31 Uhr Inferno Posts: 157 Nutzer |
In der Tat. Aber vielleicht habe ich auch ne uralt-Version der ixemul.library drauf. Ich schaue heute abend mal nach (bin z.Zt. im Büro). Gruß, Inf. [ - Antworten - Zitieren - Direktlink - ] |
29.03.2004, 18:23 Uhr Holger Posts: 8116 Nutzer |
Zitat:Vermutlich so: new und delete rufen Funktionen der ixemul.library auf und diese unterstützt möglicherweise parallele Ausführung nur, wenn die Threads auch über die ixemul.library erzeugt wurden. Mit -noixemul wird eben mit einer anderen Bibliothek verlinkt, die wie der Name schon sagt, nicht die ixemul.lib für die Speicherverwaltung benutzt. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
01.04.2004, 11:41 Uhr gni Posts: 1106 Nutzer |
Zitat:Was nicht überraschend ist. Lies nochmal den ersten Kommentar von Thomas im Thread und denk drüber nach. PS: Nachrichten für IPC _müssen_ in PUBLIC Speicher sein. Das garantiert Dir kein malloc/new (es sei denn, Du kannst deren Verhalten beinflussen oder hast diese Funktionen selber implementiert). Wenn Du wirklich die Message freigeben möchtest, dann mußt Du _zwingend_ ein WaitPort drin haben um auf das ReplyMsg() zu warten. Danach kannst Du die Nachricht freigeben. [ - Antworten - Zitieren - Direktlink - ] |
01.04.2004, 15:09 Uhr Inferno Posts: 157 Nutzer |
Zitat: Okay, GENAU DAS MACHT das multi.c - Programm ja auch. Warten auf den Reply, etc. Der Crash kam aufgrund der ixemul - library.... Letzten Endes funktionieren ALLE Versionen, wenn sie mit -noixemul kompiliert werden! Was den public-Speicher angeht, sehe ich allerdings einige Probleme kommen. Was mache ich denn, wenn ich in einer Message einen Zeiger auf ein Objekt übergeben will? Das kann ich ja nur korrekt über "new" erzeugen (oder kann mir jemand sagen, wie ich konstruktor- und destruktor-Aufrufe nach 'nem AllocVec ausführe? Gruß, Inf. [ - Antworten - Zitieren - Direktlink - ] |
01.04.2004, 15:14 Uhr Solar Posts: 3680 Nutzer |
Evtl. hilft Dir "placement new" weiter. [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 09:22 Uhr Inferno Posts: 157 Nutzer |
Danke für den Tip, ist aber ziemlich von hinten durch die Brust ins Auge!! Gibts da keinen "sauberen" Weg, z.B. durch Parametrisierung des gcc? (a la gcc -noixemul -publicnew) Gruß, Inf. [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 12:10 Uhr gni Posts: 1106 Nutzer |
Zitat:Vergiss multi.c. Das ist kein gutes Beispiel. DOS-Prozesse entfernt man _nicht_ mit RemTask(). Dann verwendet der Subtask GetMsg ohne Prüfung des Ergebnisses. Zitat:Der Crash liegt _nicht_ an ixemul! Der Fehler liegt bei Dir, weil etwas falsch verwendest. Auch wenn es mit -noixemul funktioniert, heisst das nicht, das es richtig ist. Du hast nur "Glück". [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 12:46 Uhr Holger Posts: 8116 Nutzer |
Zitat:Das kann ja nicht der Sinn der Sache sein. Du hast nunmal zwei Möglichkeiten a) Du ignorierst die Tatsache, daß es ein public flag für Speicher im AmigaOS gibt, weil es eh nicht benutzt wird oder b) Du versuchst ein wie auch immer funktionierendes (ich glaube nicht daran) Speichermodell eines zukünftigen OS zu unterstützen, in dem Du das public flag richtig benutzt, also nur dann setzt, wenn das entsprechende Objekt tatsächlich von verschiedenen tasks zugänglich sein soll. Ein generelles setzen des flags mit einer Art "-publicnew" Option wäre jedenfalls genauso falsch, wie es nie zu setzen. Vermutlich gibt es genausoviel Programme, die immer public-mem anfordern, wie Programme, die das flag nie setzen. Und zusammen sind das 99% aller existierenden. Deshalb ist auch nicht zu erwarten, daß zukünftige Betriebssysteme mit Abwärtskompatibilität das flag jemals benutzen werden. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 13:33 Uhr Solar Posts: 3680 Nutzer |
Zitat: Gibt es. Die operatoren new() und delete() so überladen, das sie AllocMem() und FreeMem() so aufrufen, wie Du das brauchst... [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 23:18 Uhr Inferno Posts: 157 Nutzer |
Ein alternativer Vorschlag wäre mittels #pragmas jeweils umzustellen, wäre wohl am "saubersten". Aber überladen ist auch in Ordnung, solange man es nicht auf mehreren Platformen compilieren will, dann braucht's dafür auch noch nen Haufen #ifdefs Naja, der Quähl-Code wimmelt jetzt schon vor lauter defines für Mac, Amiga, AROS, etc.... Gruß, Inf. [ - Antworten - Zitieren - Direktlink - ] |
-1- | [ - Beitrag schreiben - ] |
amiga-news.de Forum > Programmierung > gcc und Messages aargh | [ - Suche - Neue Beiträge - Registrieren - Login - ] |
Impressum |
Datenschutzerklärung |
Netiquette |
Werbung |
Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten. |