Debug: Programm läuft! Release: Programm macht fehler!



  • Hallo!
    Ich habe folgendes Problem: Ich habe ein Consolenprogramm geschrieben, welches in der registry einige arbeiten erledigt (regloadkey,regopenkeyex,regsavekey,shdeleteKey...). Ich habe dem Programm die nötigen Rechte gegeben: SE_BACKUP_NAME und SE_RESTORE_NAME.

    Nun es lief alles gut, alles ging perfekt. Dann hab ich am Ende das Programm mal als release kompiliert und hoppla hat regsavekey(hKey,"temp.dat",NULL); plötzlich probleme: fehler 1314: ERROR NOT PRIVILEGED! Aber warum? ich hab die privilegien vorher zugewiesen und mit debug hats eben funktioniert 😕

    Warum?? Ich versteh nicht wiesos unter debug läuft und dann mit release nicht mehr 😞

    Kann mir da jemand helfen?

    mfg
    mitos



  • Höchstwahrscheinlich ein Problem mit deinem Speicher.
    Einfachste Möglichkeit das zu überprüfen: Ändere deine Konfiguration so ab, dass auch Release mit Debug-Informationen kompiliert wird, aber ohne all die anderen Einstellungen, die die Debug-Konfig ausmacht (z.B. DEBUG_).
    Dann kannst du es im Release-Modus debuggen und genauer gucken, wieso es crasht.



  • Hast du vielleicht nicht-initialisierte Variablen verwendet? (im Debug-Modus bekommen die einen compiler-spezifischen Defaultwert zugewiesen, im Release-Modus enthalten sie Müll)
    Oder hast du Teilberechnungen in Assert()-Anweisungen o.ä. versteckt? (die werden im Release-Modus ersatzlos weggelassen)
    ...

    (am besten du zeigst mal einen Ausschnitt aus deinem Code - und beschreibst genauer, wie sich die aufgetretenen Fehler äußern)



  • Hallo!
    Danke für die schnellen Antworten. Hier der Code:
    Einmal die Funktion die die Privilegien "gibt":

    bool SetProcRegAccessPrivs(bool bSet)
    {
    	HANDLE hCurrentToken; 
    	LUID lPriv1,lPriv2;
    	TOKEN_PRIVILEGES tpPriv;
    
    	if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hCurrentToken))
    	{
    		MessageBox(0,"Error getting Process Token","ERROR",MB_ICONERROR|MB_ICONINFORMATION);
    		return false;
    	}
    
    	if(!LookupPrivilegeValue(NULL,SE_RESTORE_NAME, &lPriv1)||!LookupPrivilegeValue(NULL,SE_BACKUP_NAME, &lPriv2))
    	{
    		MessageBox(0,"Error getting Privilege Values","ERROR",MB_ICONERROR|MB_ICONINFORMATION);
    
            return false;
    	}
    
    	tpPriv.PrivilegeCount = 2;
    	tpPriv.Privileges[0].Luid = lPriv1;
    	tpPriv.Privileges[1].Luid = lPriv2;
    
    	if(bSet)
    	{
            tpPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    		tpPriv.Privileges[1].Attributes = SE_PRIVILEGE_ENABLED;
    	}
        else
    	{
            tpPriv.Privileges[0].Attributes = 0;
    		tpPriv.Privileges[1].Attributes = 0;
    	}
    
    	if(!AdjustTokenPrivileges(hCurrentToken, FALSE, &tpPriv, 0, (PTOKEN_PRIVILEGES) NULL, 0))
    	{
    		MessageBox(0,"Error setting Privilege Values","ERROR",MB_ICONERROR|MB_ICONINFORMATION);
            return false;
    	}
    
    	return true;
    }
    

    das wird ganz am anfang aufgerufen, und nur wenn true zurückgeliefert wird, läuft das Programm weiter.

    so und dann werden keys geladen usw. und dann:

    sprintf(szTempDir,"tempdir%04i",iUserCounter);
    printf(cPathTempBuffer,"C:\\%s\\ntusertemp.dat",cPath);
    if(RegOpenKeyEx (hRootKey,szTempDir, 0, KEY_READ, &hSubKey)!=ERROR_SUCCESS)
    				{
    					iError++;
    
    	cout<<"ERROR:		Rootkey could not be opened!"<<endl;
    
    				}
    				else
    				{
    
    	cout<<"OK:		Rootkey opened!"<<endl;
    
    				}
    
    				int err=RegSaveKey(hSubKey,cPathTempBuffer,NULL);
    				if(err!=ERROR_SUCCESS) //fehler bei release 1314
    				{
    					iError++;
    
    	cout<<"ERROR:		Error while saving new Regstructure!"<<err<<endl;
    				}
    				else
    				{
    
    	cout<<"OK:		New Regstructure saved!"<<endl;
    
    				}
    
    				RegCloseKey(hSubKey);
    				RegCloseKey(hRootKey);
    

    Er öffnet den key, aber save geht eben nicht, hier noch die variablen, die hierfür notwendig sind:

    int iError=0;
    	char cPathBuffer[512]="";
    	char cPathTempBuffer[512]="";
    	char szTempDir[512]="";
    	char szRegPTempDir[512]="";
    	char szRegPExplorerPath[512]="";
    	char cTimeBuffer[256]="";
    	char cFSizeBuffer[256]="";
    	char cNumProf[256]="";
    	char cBackUpBuffer[512]="";
    
    	float fFileSize=0;
    	fpos_t fposSize=0;
    	struct tm *locTime;  
    	time_t tTime; 
    	HKEY hSubKey=0;
    

    Diese Vars sind in der Funktion deklariert.

    Leider kann ich nicht debuggen, da ich auf dem PC hier nicht die Registry zumüllen kann, und ich das testen deshalb auf nem anderem rechner mache...

    PS: also es funktioniert eben alles, nur ist komisch dass der Fehler eben darauf hinweist dass irgendwo rechte fehlen, das Problem hatte ich am anfang, hab ich allerdings mit der RechteFunktion behoben... zumindest eben beim debugmodus
    mfg
    mitos



  • Kann es irgendwie sein dass das Programm keine Rechte mehr annimmt oder dass der Compiler da irgendwie was weglässt, weil eben alles andere funktioniert... 😕 😕



  • hmm also es ist wirklich mehr als komisch:
    ich hab die Privilegienfunktion nun verändert:

    BOOL SetProcRegAccessPrivs(char* szPriv,bool bSet)
    {
    	HANDLE hCurrentToken=NULL; 
    	LUID lPriv={NULL};
    	TOKEN_PRIVILEGES tpPriv={NULL};
    
    	if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hCurrentToken))
    	{
    		//MessageBox(0,"Error getting Process Token","ERROR",MB_ICONERROR|MB_ICONINFORMATION);
    		return false;
    	}
    
    	if(!LookupPrivilegeValue(NULL,szPriv, &lPriv))
    	{
    		//MessageBox(0,"Error getting Privilege Values","ERROR",MB_ICONERROR|MB_ICONINFORMATION);
    
            return false;
    	}
    
    	tpPriv.PrivilegeCount = 1;
    	tpPriv.Privileges[0].Luid = lPriv;
    
    	if(bSet)
            tpPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        else
            tpPriv.Privileges[0].Attributes = 0;
    
    	if(!AdjustTokenPrivileges(hCurrentToken, FALSE, &tpPriv, 0, (PTOKEN_PRIVILEGES) NULL, 0))
    	{
    		//MessageBox(0,"Error setting Privilege Values","ERROR",MB_ICONERROR|MB_ICONINFORMATION);
            return false;
    	}
    
    	return true;
    }
    

    so und an der gleichen Pos im Quelltext hab ich die nötigen privilegien "händisch" übergeben:
    if(!SetProcRegAccessPrivs(SE_BACKUP_NAME,true)||!SetProcRegAccessPrivs(SE_RESTORE_NAME,true))
    {
    cout<<endl;
    cout<<"Fatal-Error: Privileg-Registration failed!"<<endl;

    return 0;
    }

    und nun läufts plötzlich.
    Nun wäre meine Frage: Sind Funktionen im Releasemodus plötzlich anders?? Oder nimmt meine einstige nur den ersten Parameter und im Debugmode funktionierts trotzdem!? 😕
    Ich blick da nicht ganz durch...

    Danke,
    mfg
    mitos



  • Ich würde mal sagen, das ist ein klassischer Fall von Bereichsüberschreitung - TOKEN_PRIVILEGES endet mit einem unbestimmten Array, und der Compiler hat vermutlich hinter diesem Array keinen Platz mehr gelassen, so daß der Zugriff auf tpPriv.Privileges[1] andere Variablen beschädigt hat.



  • hmm also kürtzt der compiler im releasemode alles total 🙂 ich hatte eigentlich immer nur probleme mit dem releasemode... Was sind den eigentlich die grundsätzlichen unterschiede zwischen den beiden modi (klar, größe, geschwindigkeit und debuginfos) aber sonst?

    danke,
    mfg
    mitos



  • Der Compiler optimiert stärker, lässt einige "unnütze" Daten und Anweisungen weg (z.B. setzt er im Debug-Modus Füll-Bytes um deine Daten, so daß Bereichsüberschreitungen nichts gefährliches bewirken) und Debug-Anweisungen wie ASSERT() oder TRACE() werden auch ersatzlos gestrichen.

    (außerdem werden gelegentlich Funktionen ausgetauscht gegen schnellere, aber anfälligere Versionen)



  • naja dann ist es doch eigentlich besser oder sicherer die debug versionen zu nehmen und einfach bei den projekteigenschaften für die entgültige version die debuginfos weglassen...
    denn eigentlich hab ich nicht wirklich nachteile bis auf die größe was aber egal ist 120KB oder 500KB naja... und ob das Programm 2ms früher fertig ist... 😉

    oder?

    mfg
    mitos



  • Ja, theoretisch kannst du meist mit der Debug-Version wunderbar arbeiten, allerdings ist die nicht nur größer, sondern auch langsamer. (und die Debug-Bibliotheken dürfen oft nicht unabhängig vom Compiler weitergegeben werden)



  • (und die Debug-Bibliotheken dürfen oft nicht unabhängig vom Compiler weitergegeben werden)

    Wie läuft das genau? 🙂 solange ich keine urrheberrechtlich geschützten dll's z.b. von microsoft mit meinem Programm zusammen weiterschicke, ist das ja egal oder?
    Solange ich nur die *.exe-Datei habe, die einfach die Standard-windows-dll's nutzt, darf ich das programm doch weitergeben oder?
    Und wenn nicht, wieso darf ichs im release schon und im debug-mode nicht mehr weitergeben bzw. wo ist dann der unterschied?

    danke für deine geduld 🙂

    mfg
    mitos



  • hi, weil die debug vesion bibliotheken braucht, die du nicht weitergebben daffst.



  • ja ok, aber welche? und ich geb auch keine *.dll dateien weiter, sondern wenn würd ich nur meine .exe weitergeben... Oder kann man in vc++ irgendwo in den projekteintstellungen die einstellung setzen dass er die bibliotheken gleich weglässt? was sind das eigentlich für biblios? 🙂

    danke

    mfg
    mitos



  • Statisch gelinkte. Die sind in deiner EXE drin und somit würdest du sie mitgeben. Sind prinzipiell Bibliotheken, die den Debug-Prozess unterstützen, also Dinge wie ASSERT und ähnliches. AFAIK!

    gruß
    Martin


Anmelden zum Antworten