Parameter - Debugger zeigt <Schlechtes Ptr> - Absturz
-
Hab neue Erkenntnisse. Hab den Code wie folgt geändert:
void fprint_long_canframe(FILE *stream , TCANoverSocketMsg *cf, char *eol, int view) { /* documentation see lib.h */ //stream = stdout; static FILE* Temp = stream; static TCANoverSocketMsg *cfTemp = cf; static char *willi = eol; static int ierwin = view; char buf[MAX_LONG_CANFRAME_SIZE]; sprint_long_canframe(buf, cf, view); fprintf(Temp, "%s", buf); if ((ierwin & CANLIB_VIEW_ERROR) && (cfTemp->ID & CAN_ERR_FLAG)) { //snprintf_can_error_frame(buf, sizeof(buf), cf, "\n\t"); fprintf(Temp, "\n\t%s", buf); } if (willi) fprintf(Temp, "%s", willi); }
Hab also die Parameter zwischengespeichert. Ursprünglich waren die Parameter nach Eintritt in die Funktion okay. Nach Aufruf der Funktion
sprint_long_canframe(buf, cf, view);
stand in den parametern überall 0xfefefefe.
Jezt kommt folgende Fehlermeldung wenn ich die Funktion fprint_long_canframe verlasse:
Run-Time Check Failure #2 - Stack around the variable 'buf' was corrupted.
-
int main(int argc, char* argv[]) { myPeakCan = new PeakCan()); myPeakCan->ConnectClient(); myPeakCan->CanReceiveHandler(onCanReceiveHandler); }
Nur so aus logischer Sicht:
Sollte eine Callback Funktion nicht vor einer bewirkenden Methode registriert werden? Immerhin wird ein Thread erstellt, welcher auch irgendwann deine Callback Func aufruft. Könnte zu undefiniertem Verhalten führen. Das solltest du ändern.
-
Woher weis die Funktion "sprint_long_canframe" wieviel sie maximal in "buf" schreiben darf? AUch würde ich große Datenmengen nie auf dem Stack anlegen sondern immer auf dem Heap.
Leg es auf den Heap (malloc), dann FullPageHeap aktivieren, dann siehst Du sofort wo es kracht...
-
Die max länge für buf ist über ein Define im Header angegeben. Beschrieben wird buf über sprintf_s und dort gebe ich das define als max-länge mit.
Wie benutzt man FullPageHeap? Hab ich noch nie von gehört.
Hab gerade buf mal mit malloc angelegt. Jezt werden auch die Paramter nicht mehr verbogen. Es hat also definitiv etwas mit dem Stack zu tun.
Die Funktion sieht jetzt so aus:
void fprint_long_canframe(FILE *stream , TCANoverSocketMsg *cf, char *eol, int view) { /* documentation see lib.h */ char *buf = (char*)malloc(MAX_LONG_CANFRAME_SIZE);//[MAX_LONG_CANFRAME_SIZE]; sprint_long_canframe(buf, cf, view); fprintf(stdout, "%s", buf); if ((view & CANLIB_VIEW_ERROR) && (cf->ID & CAN_ERR_FLAG)) { //snprintf_can_error_frame(buf, sizeof(buf), cf, "\n\t"); fprintf(stdout, "\n\t%s", buf); } if (eol) fprintf(stdout, "%s", eol); free(buf); }
Wenn ich allerdings jetzt die Funktion verlassen, kommt folgende Fehlermeldung:
Windows hat einen Haltepunkt in xyz.exe ausgelöst.
Dies kann auf eine Beschädigung des heaps zurückzuführen sein, die auf eine Problem in xyz.exe oder in einer der geladenen DLLs hinweist.
-
Ich habe das Programm gflags.exe auf meinem Rechner. Da kann man "Enable page heap" aktivieren.
-
Wie Du ja auch erkennen kannst, wird eben der Puffer überschrieben!!! Stelle also sicher, dass Du wirklich genügend Speicher allokiert hast und an beiden Stellen das *gleiche* Define verwendest! Besser noch: Übergebe die Länge!!!
-
Full PageHeap:
gflags /p /enable NameDer.EXE /full
Musst allerdings als "Admin (UAC)" ausführen!
-
Hi Jochen,
wird dann Full PageHeap nur für die EXE aktiviert? Ich hatte es über gflags.exe aktiviert (anscheinend global) und nach einem Neustart war der Rechner grotten langsam. Hab es jetzt über gflags.exe wieder raus genommen.Wenn ich das aktiviert habe, starte ich ganz normal den debugger und lasse das Programm laufen bis es abstürzt. Und dann? Sollte der Debugger mir jetzt etwas spezielles anzeigen, oder wird irgendwo eine Datei angelegt?
Danke noch mal für Eure Mühe und Gedult.
-
Ich habs gefunden, glaube ich jedenfalls.
in der Funktion
fprint_long_canframe
wird die Funktion
sprint_long_canframe
aufgerufen.
Dort wird per sprintf_s auf buf geschrieben.sprintf_s(buf+offset, MAX_LONG_CANFRAME_SIZE," %02X", cf->DATA[i]);
Der zweite Parameter von sprintf_s gibt je die größe von Parameter 1 an.
Bei mir wird jedoch die Startadresse von buf um Offset verschoben, aber die maximale größe blieb gleich. Anscheinend prüft sprintf_s die größe ab der Startadresse.
Hab die Zeile jetzt wie folgt geändert und es funktioniert
sprintf_s(buf+offset, MAX_LONG_CANFRAME_SIZE-offset," %02X", cf->DATA[i]);
Kann jemand meine Vermutung bestätigen, oder ist das blödsinn?
Eine weitere Frage. Wird die Heapgröße beim Anlegen eines Projektes auf einen Standardwert geseetzt? Ich habe unter Projekteigenschaften->Linker->System nachgesehen und da waren folgende Einträge:
Heapreservierungsgröße: 0
Heapcommitgröße: 0
Stapelreservierungsgröße: 0
Stapelcommitgröße: 0Wird ein Standardwert benutzt, so lange dort 0 eingetragen ist, oder muss dort die Speichergröße in Byter eingetragen werden?
-
Das sieht besser aus.
Auch wird der eap mit einem Default-Wert initialisiert und kann auch dynamisch wachsen...