Zugriffsverletzung beim Schreiben an Position 0x00000000.
-
Hallo zusammen,
ich weiß, der Fehler kam schon öfters, aber ich konnte bis her nicht die richtige Antwort finden, deshalb bitte ich nun selber um Hilfe.Ich hab ein fremdes, lauffähiges C++ Programm von MVS .Net in MVS10 portiert, doch jetzt kommen Fehlermeldungen, bei denen ich nicht weiter weiß.
EXPDATA* PL2AddExperiment(PL2DATA* lpPL2Data, WCHAR* lpName, WCHAR* lpPath, int iType) { typedef struct{ short Rows[MAX_COPYROWS]; short Cols[MAX_COPYCOLS]; COPYCELL Cells[MAX_COPYVALS]; int iRows; int iCols; int iCells; int iAll; }COPYVALUES; : : if(lpExpNew != NULL) { eCode = ExperimentSetHwndExp(lpExpNew,(HWND)SendMessage(hWnd, WM_EXP_CREATEWINDOW,0,(LPARAM)lpExpNew)); if(eCode >= 0)eCode = ExperimentSetHwndLayout(lpExpNew,(HWND)SendMessage( hWnd,WM_LAY_CREATEWINDOW,0,(LPARAM)lpExpNew)); if(eCode >= 0)eCode = ExperimentSetHwndProfile(lpExpNew,(HWND)SendMessage( hWnd,WM_PRO_CREATEWINDOW,0,(LPARAM)lpExpNew)); if(eCode >= 0)eCode = ExperimentSetHwndResults(lpExpNew,(HWND)SendMessage( hWnd,WM_RES_CREATEWINDOW,0,(LPARAM)lpExpNew)); : : } } BOOL CALLBACK ResultsDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { : COPYVALUES* lpCVals = malloc(sizeof(COPYVALUES)); memset(lpCVals,0,sizeof(COPYVALUES)); }
Wenn ich mit dem Debugger bei
if(lpExpNew != NULL){
anhalte, schreibt er u. a. folgende Meldungen ins Ausgabefenster:
"ABC.exe": "C:\WINDOWS\system32\browseui.dll" geladen, Exporte wurden geladen.
"ABC.exe": "C:\WINDOWS\system32\shdocvw.dll" geladen, Exporte wurden geladen.
"ABC.exe": "C:\WINDOWS\system32\crypt32.dll" geladen, Exporte wurden geladen.
"ABC.exe": "C:\WINDOWS\system32\msasn1.dll" geladen, Exporte wurden geladen.
"ABC.exe": "C:\WINDOWS\system32\cryptui.dll" geladen, Exporte wurden geladen.
"ABC.exe": "C:\WINDOWS\system32\wininet.dll" geladen, Exporte wurden geladen.
"ABC.exe": "C:\WINDOWS\system32\wintrust.dll" geladen, Exporte wurden geladen.
"ABC.exe": "C:\WINDOWS\system32\imagehlp.dll" geladen, Exporte wurden geladen.
"ABC.exe": "C:\WINDOWS\system32\wldap32.dll" geladen, Exporte wurden geladen.
"ABC.exe": "C:\WINDOWS\system32\riched20.dll" geladen, Exporte wurden geladen.
"ABC.exe": "C:\WINDOWS\system32\riched20.dll" entladen.
"ABC.exe": "C:\WINDOWS\system32\browseui.dll" entladen.
"ABC.exe": "C:\WINDOWS\system32\shdocvw.dll" entladen.
"ABC.exe": "C:\WINDOWS\system32\cryptui.dll" entladen.
"ABC.exe": "C:\WINDOWS\system32\wldap32.dll" entladen.
"ABC.exe": "C:\WINDOWS\system32\wintrust.dll" entladen.
"ABC.exe": "C:\WINDOWS\system32\imagehlp.dll" entladen.
"ABC.exe": "C:\WINDOWS\system32\wininet.dll" entladen.
"ABC.exe": "C:\WINDOWS\system32\crypt32.dll" entladen.
"ABC.exe": "C:\WINDOWS\system32\msasn1.dll" entladen.Was bedeutet das? Hat er hat diese DLL’s wieder rausgeschmissen?? Ist das normal?
Ich habe die Zeile
eCode = ExperimentSetHwndExp(lpExpNew,HWND)SendMessage(hWnd, WM_EXP_CREATEWINDOW,0,(LPARAM)lpExpNew));
zerlegt in:
Hwdd = (HWND)SendMessage(hWnd,WM_EXP_CREATEWINDOW,0,(LPARAM)lpExpNew); eCode = ExperimentSetHwndExp(lpExpNew,Hwdd); //eCode = ExperimentSetHwndExp(lpExpNew,(HWND)SendMessage(hWnd,WM_EXP_CREATEWINDOW, 0,(LPARAM)lpExpNew));
Aus SendMessage kommt er mit den Fehlemeldungen:
Eine Ausnahme (erste Chance) bei 0x7c929d6f (ntdll.dll) in ABC.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xfefefefe.
Eine Ausnahme (erste Chance) bei 0x7c929d6f (ntdll.dll) in ABC.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xfefefefe.
Eine Ausnahme (erste Chance) bei 0x7c929d6f (ntdll.dll) in ABC.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xfefefefe.eCode ist und bleibt 0x00000000,
bei der Ausführung vonif(eCode >= 0)eCode = ExperimentSetHwndResults(lpExpNew,(HWND)SendMessage( hWnd,WM_RES_CREATEWINDOW,0,(LPARAM)lpExpNew));
springt er statt in
ExperimentSetHwndResults
in
BOOL CALLBACK ResultsDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
Und erzeugt wieder die Fehlermeldung
Eine Ausnahme (erste Chance) bei 0x7c929d6f (ntdll.dll) in ABC.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xfefefefe.
COPYVALUES* lpCVals = (COPYVALUES*)malloc(sizeof(COPYVALUES));
Ausserdem kann er lpCVals nicht finden, obwohl es gerade erst erstellt wurde:
CXX0017: Fehler: Symbol „lpCVals“ nicht gefunden
und bei
memset(lpCVals,0,sizeof(COPYVALUES));
fliegt er mit der Fehlermeldung ganz und gar raus:
Unbehandelte Ausnahme bei 0x00506370 in ABC.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00000000.
Ich komm nicht mehr weiter und hoffe, dass von euch jemand mein Kauderwelsch versteht und mir bitte, bitte helfen kann. :xmas1:
-
Bring erst mal Ordnung in deinen Code. Wo kommt lpExpNew her? Was machen die ganzen Doppelpunkte da? Könntest du das mal übersichtlich einrücken? (PS: Das gehört in das WinAPI Forum.)
-
cooky451 schrieb:
Was machen die ganzen Doppelpunkte da?
Vermutung: das ist quasi "..." nach unten gerichtet.^^
-
Triple? schrieb:
Aus SendMessage kommt er mit den Fehlemeldungen:
Eine Ausnahme (erste Chance) bei 0x7c929d6f (ntdll.dll) in ABC.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xfefefefe.
Die Ausnahme weist dich drauf hin, dass irgendwer versucht, über einen Pointer auf Speicher zuzugreifen, der dem Prozess nicht gehört. Deshalb Zugriffsverletzung. Die Adresse, an der er lesen will, hast höchstwahrscheinlich du übergeben. Direkt oder indirekt. Wenn du ein wenig googlest, wirst du rausfinden, dass 0xfefefefe darauf hindetutet, dass es da um freigegebenen Speicher geht, sprich die Funktion sucht sich von "irgendwo" einen Pointer und versucht drauf zuzugreifen. Der Pointer hat aber den Wert 0xfefefefe, liegt also in freigegebenem Speicher. Ich schätze, du hast ihm einen Pointer übergeben, der auf etwas zeigt, das schon längst wieder freigegeben wurde. Ich rate mal ins Blaue: lpExpNew ist so ein Pointer.(Hinweis: delete lpExpNew; gibt den Speicher frei, setzt aber den Pointer nicht auf 0)
eCode ist und bleibt 0x00000000
Kein Wunder, wenn er vorher Zugriffsfehler hat, kommt er garnicht so weit, das zu ändern.
bei der Ausführung von
if(eCode >= 0)eCode = ExperimentSetHwndResults(lpExpNew,(HWND)SendMessage( hWnd,WM_RES_CREATEWINDOW,0,(LPARAM)lpExpNew));
springt er statt in
ExperimentSetHwndResults
in
BOOL CALLBACK ResultsDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
Rück das mal ordentlich ein und schau, ob er überhaupt in den if-Block kommt.
-
Euch allen vielen Dank für die Tipps. Ich hab versuch den Code noch mal besser aufzuschreiben. Ich denke ja auch das es an unsauberen Zeigern liegt, aber ich finde nicht wo. Ich habe bei der Konvertierung alle sprintf in sprintf_s wandeln müssen, so dass ich denke da liegt der Hase begraben. Jedoch sind in dem Code, der alles vor den Fehlermeldungen liegt, nur ein oder zwei solche Aufrufe und bei denen denke ich sind die Puffer-Angaben i.O.
EXPDATA* PL2AddExperiment(PL2DATA* lpPL2Data, WCHAR* lpName, WCHAR* lpPath, int iType) { EXPDATA* lpExpNew = NULL; int eCode = 0; HWND hWnd = lpPL2Data->hWnd; if(WaitForSingleObject(lpPL2Data->hAccess,5000) == WAIT_OBJECT_0) { if(lpPL2Data->iExperiments < MAX_EXPERIMENTS) lpExpNew = CreateExperiment(); SetEvent(lpPL2Data->hAccess); } if(lpExpNew != NULL) { eCode = ExperimentSetHwndExp(lpExpNew,HWND)SendMessage(hWnd, WM_EXP_CREATEWINDOW,0,(LPARAM)lpExpNew)); if(eCode >= 0) eCode = ExperimentSetHwndLayout(lpExpNew,(HWND)SendMessage(hWnd, WM_LAY_CREATEWINDOW,0,(LPARAM)lpExpNew)); if(eCode >= 0) eCode = ExperimentSetHwndProfile(lpExpNew,(HWND)SendMessage(hWnd, WM_PRO_CREATEWINDOW,0,(LPARAM)lpExpNew)); if(eCode >= 0) eCode = ExperimentSetHwndResults(lpExpNew,(HWND)SendMessage(hWnd, WM_RES_CREATEWINDOW,0,(LPARAM)lpExpNew)); } } typedef struct{ WCHAR* lpAlias[MAX_GROUPS]; }RSDLGGROUPALIAS; typedef struct{ short Rows[MAX_COPYROWS]; short Cols[MAX_COPYCOLS]; COPYCELL Cells[MAX_COPYVALS]; int iRows; int iCols; int iCells; int iAll; }COPYVALUES; BOOL CALLBACK ResultsDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { LRESULT lResult = FALSE; switch(Msg) { case WM_INITDIALOG: { int i; HWND hWndTT; COPYVALUES* lpCVals = (COPYVALUES*)malloc(sizeof(COPYVALUES)); RSDLGGROUPALIAS* lpGroupAlias = (RSDLGGROUPALIAS*)malloc(sizeof(RSDLGGROUPALIAS)); memset(lpCVals,0,sizeof(COPYVALUES)); memset(lpGroupAlias, 0,sizeof(RSDLGGROUPALIAS)); } break; } return(lResult); }
Werde einfach mal versuchen Teile aus dem Programm herauszukommentieren und sehen ob ich da was erreiche.
Oder?
-
- sicher dass Zeile 17 so aussieht?
- Sicher dass du C++ und kein C schreibst? Das ist pure ugly C was du da stehen hast. Von C++ keine Spur.
- Wie sieht die CreateExperiment-Methode aus?
- Dir ist klar, dass die Bedingung in Zeile 10 nur Zeile 11 bedingt ausführt, Zeile 12 aber unbedingt ausgeführt wird (Wenn denn der Block betreten wird)?
-
Wie gesagt habe ich das Programm nicht geschrieben. Aber in Resource.h steht, dass es C++ ist, also geh ich mal davon aus.
// Microsoft Visual C++ generated include file.
Zeile 10-12 hier nochmal mit den Zwischenschritten:
int iTwice = FALSE; HANDLE hAccess; if(WaitForSingleObject(lpPL2Data->hAccess,5000) == WAIT_OBJECT_0){ if(lpPL2Data->iExperiments < MAX_EXPERIMENTS){ lpExpNew = CreateExperiment(); if(lpExpNew != NULL){ ExperimentSetName(lpExpNew,lpName); ExperimentSetPath(lpExpNew,lpPath); if(!iTwice){ lpPL2Data->lpExperiment[lpPL2Data->iExperiments] = lpExpNew; lpPL2Data->iExperiments++; } } } SetEvent(lpPL2Data->hAccess); } int ExperimentSetName(EXPDATA* lpExpData, WCHAR* lpName) { if(lpExpData != NULL){ if(WaitForSingleObject(lpExpData->hAccess,2000) == WAIT_OBJECT_0){ memset(lpExpData->lpName,0,sizeof(WCHAR)*MAX_EXPERIMENTNAME); wcsncpy_s(lpExpData->lpName,100,lpName,Min(MAX_EXPERIMENTNAME-1,wcslen(lpName))); SetEvent(lpExpData->hAccess); } } return(0); }
ExperimentSetPath sieht genauso aus, nur dass da statt lpName lpPath steht
EXPDATA* CreateExperiment() { EXPDATA* lpExpData = (EXPDATA*)malloc(sizeof(EXPDATA)); if(lpExpData != NULL){ memset(lpExpData,0,sizeof(EXPDATA)); lpExpData->hAccess = CreateEvent(NULL,FALSE,TRUE,NULL); lpExpData->hClosed = CreateEvent(NULL,TRUE,FALSE,NULL); GetSystemTime(&(lpExpData->Timestamp)); //Id } return(lpExpData); }
In der Zeile
EXPDATA* lpExpData = (EXPDATA*)malloc(sizeof(EXPDATA));
kam der Fehler
IntelliSense: Ein Wert vom Typ ""void *"" kann nicht zum Initialisieren einer Initialisieren einer Entität vom Typ ""EXPDATA *"" verwendet werden.
Ich hab (EXPDATA*) vor malloc geschrieben. Jetzt kommt jedenfalls die Fehlermeldung nicht mehr, aber vielleicht ist das ja ein Fehler?
Zeile 17 sieht wirklich so aus. Dort in den darauf folgenden Zeilen springt er in die Unterprogramme ExperimentSetHwnd...(). In allen dreien trifft WaitForSingleObject() zu und er beendet die Programme mit return(eCode=0);
int ExperimentSetHwndExp(EXPDATA* lpExpData, HWND hWnd) { int eCode = 0; if(hWnd != NULL){ if(lpExpData != NULL){ if(WaitForSingleObject(lpExpData->hAccess,2000) == WAIT_OBJECT_0){ lpExpData->hWndExp = hWnd; SetEvent(lpExpData->hAccess); } } else{ eCode = E_ACCESSTIMEOUT; } } else{ eCode = E_NOHWND; } return(eCode); }
Ich habe beschlossen nochmals alle meine Änderungen genauestens auf zu große Zahlen zu überprüfen.
Aber ich hoffe, iht schaut noch mal mit über den Code
Danke
-
Mit Zeile 17 meinte ich die hier:
eCode = ExperimentSetHwndExp(lpExpNew,HWND)SendMessage(hWnd, WM_EXP_CREATEWINDOW,0,(LPARAM)lpExpNew));
Das kann dort nicht genau so stehen. Compiliert nämlich auf keinen Fall (Klammern...)
Aber mal im Ernst: Das Forum ist eigentlich nicht dafür da, den Leuten die Fehler aus blind kopiertem Code zu suchen. Versuch nachzuvollziehen und zu verstehen, was der Code macht. Dir das jetzt zum Laufen zu bringen ist keine große Hilfe, wenn du den Code nicht verstehst. Dann stehst du nämlich nach der nächsten kleinen Änderung, die nicht so funktioniert wie erwartet, wieder im Wald...
-
Danke euch allen für eure Bemühungen. Ich versuche jetzt erst mal meinem Programm beizubringen, dass es eine, von ihm gesuchte DLL findet.
Ich habe übrigens den Code nicht irgendwo abgeschrieben, sondern den Auftrag bekommen das komplette Programm zum konvertieren und zu ändern.
Vielen Dank
-
Triple? schrieb:
Ich habe übrigens den Code nicht irgendwo abgeschrieben, sondern den Auftrag bekommen das komplette Programm zum konvertieren und zu ändern.
Das ändert nichts an der Tastache, dass du für die Konvertierung den Code erstmal verstehen musst.