![]() |
DEUTSCHE VERSION |
|
![]() |
Links | | | Forums | | | Comments | | | Report news |
![]() |
Chat | | | Polls | | | Newsticker | | | Archive |
![]() |
amiga-news.de Forum > Programmierung > gcc und Messages aargh | [ - Search - New posts - Register - Login - ] |
-1- | [ - Post reply - ] |
2004-03-27, 16:14 h Inferno Posts: 157 User |
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! [ - Answer - Quote - Direct link - ] |
2004-03-27, 16:43 h Mad_Dog Posts: 1944 User |
Wie wär's mit return 0? ![]() -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2004-03-27, 16:49 h Inferno Posts: 157 User |
Kleiner Nachtrag: Wenn ich in der "threadProc" die Zeile "delete msg" auskommentiere, funktionierts!!!!! *grübel* [ - Answer - Quote - Direct link - ] |
2004-03-27, 17:18 h thomas Posts: 7719 User |
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/ [ - Answer - Quote - Direct link - ] |
2004-03-27, 18:25 h Inferno Posts: 157 User |
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. [ - Answer - Quote - Direct link - ] |
2004-03-27, 18:27 h Inferno Posts: 157 User |
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 [ - Answer - Quote - Direct link - ] |
2004-03-27, 18:34 h thomas Posts: 7719 User |
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/ [ - Answer - Quote - Direct link - ] |
2004-03-27, 18:41 h Inferno Posts: 157 User |
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. [ - Answer - Quote - Direct link - ] |
2004-03-27, 22:08 h Inferno Posts: 157 User |
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ß. [ - Answer - Quote - Direct link - ] |
2004-03-27, 22:20 h Holger Posts: 8116 User |
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. [ - Answer - Quote - Direct link - ] |
2004-03-27, 22:57 h Inferno Posts: 157 User |
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. ] [ - Answer - Quote - Direct link - ] |
2004-03-28, 00:49 h whose Posts: 2156 User |
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 [ - Answer - Quote - Direct link - ] |
2004-03-28, 19:51 h Inferno Posts: 157 User |
Problem gelöst, funzt jetzt auch mit new & delete !!! Problam war (wie so oft) benutzerfehler ![]() Gruß, Inf. [ - Answer - Quote - Direct link - ] |
2004-03-29, 01:02 h whose Posts: 2156 User |
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 [ - Answer - Quote - Direct link - ] |
2004-03-29, 04:12 h whose Posts: 2156 User |
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 [ - Answer - Quote - Direct link - ] |
2004-03-29, 10:20 h Inferno Posts: 157 User |
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. [ - Answer - Quote - Direct link - ] |
2004-03-29, 10:41 h whose Posts: 2156 User |
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 [ - Answer - Quote - Direct link - ] |
2004-03-29, 14:31 h Inferno Posts: 157 User |
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. [ - Answer - Quote - Direct link - ] |
2004-03-29, 18:23 h Holger Posts: 8116 User |
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. [ - Answer - Quote - Direct link - ] |
2004-04-01, 11:41 h gni Posts: 1106 User |
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. [ - Answer - Quote - Direct link - ] |
2004-04-01, 15:09 h Inferno Posts: 157 User |
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. [ - Answer - Quote - Direct link - ] |
2004-04-01, 15:14 h Solar Posts: 3680 User |
Evtl. hilft Dir "placement new" weiter. [ - Answer - Quote - Direct link - ] |
2004-04-02, 09:22 h Inferno Posts: 157 User |
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. [ - Answer - Quote - Direct link - ] |
2004-04-02, 12:10 h gni Posts: 1106 User |
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". [ - Answer - Quote - Direct link - ] |
2004-04-02, 12:46 h Holger Posts: 8116 User |
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. [ - Answer - Quote - Direct link - ] |
2004-04-02, 13:33 h Solar Posts: 3680 User |
Zitat: Gibt es. Die operatoren new() und delete() so überladen, das sie AllocMem() und FreeMem() so aufrufen, wie Du das brauchst... [ - Answer - Quote - Direct link - ] |
2004-04-02, 23:18 h Inferno Posts: 157 User |
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. [ - Answer - Quote - Direct link - ] |
-1- | [ - Post reply - ] |
amiga-news.de Forum > Programmierung > gcc und Messages aargh | [ - Search - New posts - Register - Login - ] |
![]() |
Masthead |
Privacy policy |
Netiquette |
Advertising |
Contact
Copyright © 1998-2025 by amiga-news.de - all rights reserved. |
![]() |