Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: MFC (Visual C++) ::  ExitInstance() liefert nicht den gewünschten wert zurück     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
chermanns
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.12.2005
Beiträge: 12
Beitrag chermanns Mitglied 10:03:17 30.08.2010   Titel:   ExitInstance() liefert nicht den gewünschten wert zurück            Zitieren

Hallo Leute,

ich habe eine MCF Applikation die ggf. einen Fehler zurückliefern soll.

Dazu habe ich ExitInstance() so überschrieben das der Fehler den ich mir in einer Variablen gemerkt habe zurückgegeben wird.
Soweit die Theorie, auf meinem Entwicklungsrechner funktioniert dies auch.
Ich rufe meine Applikation wiefolgt auf:
start /wait app.exe

nachdem sich die Applikation beendet hat lese ich den returncod mit:
echo %ERRORLEVEL%
aus und der Wert ist richtig, zb. -106 wenn ein Socket nicht geöffnet werden konnte.

Auf anderen Rechner funktioniert dies nicht. Der returncode ist immer 0.

Hier meine ExitInstance():
Code:
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
{
..
..
  exitCode = getExitCode();
  int l_returnInt = CWinApp::ExitInstance();
  TRACE(TRACE_LEVEL_INFO, _T( "ExitInstance:  (CWinApp::ExitInstance   returned %i)" ), l_returnInt );
 
  TRACE(TRACE_LEVEL_INFO, _T( "Return code:%i" ),m_exitCode );

  return m_exitCode;
}
Code:
1
2
3
4
5
6
7
8
9
10
11
{
..
..
exitCode = getExitCode();
int l_returnInt = CWinApp::ExitInstance();
TRACE(TRACE_LEVEL_INFO, _T( "ExitInstance: (CWinApp::ExitInstance returned %i)" ), l_returnInt );

TRACE(TRACE_LEVEL_INFO, _T( "Return code:%i" ),m_exitCode );

return m_exitCode;
}
Code:
1
2
3
4
5
6
7
8
9
10
11
{
..
..
  exitCode = getExitCode();
  int l_returnInt = CWinApp::ExitInstance();
  TRACE(TRACE_LEVEL_INFO, _T( "ExitInstance:  (CWinApp::ExitInstance   returned %i)" ), l_returnInt );
 
  TRACE(TRACE_LEVEL_INFO, _T( "Return code:%i" ),m_exitCode );

  return m_exitCode;
}




Das Logfile sieht wiefolgt aus (auf meinem Rechner und auf dem Rechner der 0 zurück gibt)



Step5.cpp - I - ExitInstance: 21 (CWinApp::ExitInstance returned 0)
Step5.cpp - I - Return code:-106


Also, das Log ist in Ordnung aber der returncode nicht!

In meinem Verständnis ist es so wie in dem Beitrag von Martin:
"ExitInstance gibt für dialogbasierende MFC Anwendungen Unfug zurück!"

Hat jemand eine Idee woran es liegen könnte?
Grüsse
Carsten


Zuletzt bearbeitet von chermanns am 10:44:59 30.08.2010, insgesamt 1-mal bearbeitet
chermanns
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.12.2005
Beiträge: 12
Beitrag chermanns Mitglied 16:07:35 30.08.2010   Titel:              Zitieren

Hallo Leute,

ich kann das Problem eingrenzen, ich habe zwei Rechner die sich "richtig" verhalten, also den Fehlercode zurückliefern. Auf diesen Rechnern ist VS2005 istalliert.
Auf weiteren zwei Rechnern bekomme ich trotz Fehler immer 0 zurück. Auf diesen Rechnern ist das reditributable Package installiert.

Konnte jemand dieses Verhalten bei sich beobachten (und evtl. beseitigen)?

Grüsse Carsten
chermanns
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.12.2005
Beiträge: 12
Beitrag chermanns Mitglied 16:56:06 30.08.2010   Titel:              Zitieren

Wenn ich hart mit aus dem Program austeige mit:
exit (1234);

bekomme ich auf den beiden Rechnern, die kein VS 2005 installiert haben den errorlevel 0 zurück.

Kann mir (mittlerweile verzweifelt) geholfen werden?

Grüsse
Carsten
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13517
Beitrag Martin Richter Moderator 10:34:25 31.08.2010   Titel:              Zitieren

Hmmm. Für exit macht mich das aber sehr stutzig.
Hast Du mal den exit Code gedebuggt?

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
chermanns
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.12.2005
Beiträge: 12
Beitrag chermanns Mitglied 12:56:10 31.08.2010   Titel:              Zitieren

Hallo,

In der "crtexe.c" kommen die richtigen Werte an (Das meintest Du doch, oder?).
exit(mainret);
enthält meine Werte. Aber auf den Rechnern, auf denen ich debugen kann bekomme ich ja auch den richtigen errorlevel zurück.
Problem sind die Rechner mit den redistributable packages und da kann ich nicht debugen. Aber wenn es damit diesbezüglich Probleme geben sollt hätte ich doch was im Netz gefunden.


Ich benutze die VS 2005 standard edition und auf den "anderen" Rechner das redistributable package 8.0.56336.

Hast du eine Idee?

Grüsse Carsten
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13517
Beitrag Martin Richter Moderator 17:56:00 31.08.2010   Titel:              Zitieren

Exit benutzt direkt die entsprechende Funktion um die Applikation zu beenden.
Mir ist kein Fehler bekannt in dieser Richtung, dass sich hier eine CRT anders verhält...

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
chermanns
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.12.2005
Beiträge: 12
Beitrag chermanns Mitglied 10:44:00 01.09.2010   Titel:              Zitieren

Habe noch auf zwei Rechnern mit Windows 7 und redistributable packages (ohne Entwicklungsumgebung) getestet. Auf den Rechnern bekomme ich den Rückgabewert den ich erwarte zurück.
Mit dem gleichen redistributable package auf den XP Rechnern installiert (zuvor alle anderen entfernt). Denoch bekomme ich eine 0 statt meinem Fehlercode.

Dazu fällt mit nichts mehr ein.

Hat jemand einen Idee was das sein kann?

Grüsse Carsten
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13517
Beitrag Martin Richter Moderator 13:25:35 01.09.2010   Titel:              Zitieren

Kannst Du Dein Projekt auch statisch Linken? Was passiert dann?

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
chermanns
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.12.2005
Beiträge: 12
Beitrag chermanns Mitglied 15:21:34 01.09.2010   Titel:              Zitieren

Das geht leider nicht, es ist ziemlich gross und beinhaltet dlls von anderen Leuten und besteht zudem aus recht vielen dlls die alle statisch gelinkt sind.
Ich schaue mir grade ob es einen Unterschied bei dem Beenden der Applikation hinsichtlich Threads gibt. Dazu benutze ich im ersten Schuss:
HANDLE hTaskSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
um mir die Anzahl der Threads ausgeben zu lassen

int threadCounter = 0;
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int threadCounterID = 0;
  {
     
    HANDLE  hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );

    THREADENTRY32 te32;
    te32.dwSize = sizeof(THREADENTRY32 );
    int ret = Thread32First( hThreadSnap, &te32 );
    while (ret == TRUE){
      if (te32.th32OwnerProcessID == GetCurrentProcessId() ){
        threadCounter ++;
      }
      if (te32.th32ThreadID == 0 ){
        threadCounterID++;
      }

      ret = Thread32Next( hThreadSnap, &te32 );
    }   DASTRACE(TRACE_LEVEL_INFO, _T( "th32OwnerProcessID:%i" ),threadCounter );
    DASTRACE(TRACE_LEVEL_INFO, _T( "th32ThreadID:%i" ),threadCounterID );

  }
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int threadCounterID = 0;
{

HANDLE hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );

THREADENTRY32 te32;
te32.dwSize = sizeof(THREADENTRY32 );
int ret = Thread32First( hThreadSnap, &te32 );
while (ret == TRUE){
if (te32.th32OwnerProcessID == GetCurrentProcessId() ){
threadCounter ++;
}
if (te32.th32ThreadID == 0 ){
threadCounterID++;
}

ret = Thread32Next( hThreadSnap, &te32 );
} DASTRACE(TRACE_LEVEL_INFO, _T( "th32OwnerProcessID:%i" ),threadCounter );
DASTRACE(TRACE_LEVEL_INFO, _T( "th32ThreadID:%i" ),threadCounterID );

}
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int threadCounterID = 0;
  {
     
    HANDLE  hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );

    THREADENTRY32 te32;
    te32.dwSize = sizeof(THREADENTRY32 );
    int ret = Thread32First( hThreadSnap, &te32 );
    while (ret == TRUE){
      if (te32.th32OwnerProcessID == GetCurrentProcessId() ){
        threadCounter ++;
      }
      if (te32.th32ThreadID == 0 ){
        threadCounterID++;
      }

      ret = Thread32Next( hThreadSnap, &te32 );
    }   DASTRACE(TRACE_LEVEL_INFO, _T( "th32OwnerProcessID:%i" ),threadCounter );
    DASTRACE(TRACE_LEVEL_INFO, _T( "th32ThreadID:%i" ),threadCounterID );

  }

dabei erhalte ich folgene Ausgabe, die mir nicht klar ist:

Auf den Systemen die sich richtig verhalten:
th32OwnerProcessID:4
th32ThreadID:2

bzw Windows 7:
th32OwnerProcessID:6
th32ThreadID:2


Auf den Systemen die sich falsch verhalten:
th32OwnerProcessID:4
th32ThreadID:1

Beschreibung zu th32ThreadID:
The thread identifier, compatible with the thread identifier returned by the CreateProcess function.


Da stosse ich an meine Grenzen was das bedeutet, hast du einen Tip?


Zuletzt bearbeitet von chermanns am 16:16:07 01.09.2010, insgesamt 1-mal bearbeitet
chermanns
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.12.2005
Beiträge: 12
Beitrag chermanns Mitglied 16:42:19 02.09.2010   Titel:              Zitieren

jubel!!
ich habe die Ursache gefunden.
Die Applikation ist etwas grösser. sie besteht aus der *.exe plus ca 20 DLLSs die von mir kommen plus ca 15 DLLs die von verschiedenen Zulieferen kommen.

In einer der zugelieferten DLLs hat sich etwas geändert und das hat meinen Returncode überschrieben.
Ich weiss nicht wie aber ich erhalte mit einer älteren Version der DLL den richtigen Returncode.


Mit der "fehlerhaften" DLL sehe ich, das aus der WinMain mit meinem Fehlercode (5) herauskomme, die Applikation aber mit 0 beendet wird.

Wenn mir das jemand erklären kann wäre ich dankbar!

Ausgabe Debugfenster:
'App.exe': Unloaded 'C:\WINDOWS\system32\comdlg32.dll'
'App.exe': Unloaded 'C:\WINDOWS\system32\winspool.drv'
The thread 'Win32 Thread' (0x8e0) has exited with code 5 (0x5).
The thread 'Win32 Thread' (0x9c8) has exited with code 5 (0x5).
The thread 'Win32 Thread' (0xbc8) has exited with code 5 (0x5).
The program '[2644] App.exe: Native' has exited with code 0 (0x0).


Grüsse Carsten
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13517
Beitrag Martin Richter Moderator 18:31:43 02.09.2010   Titel:              Zitieren

Kann es sein, dass die andere DLL Deinen Prozess vorher mit ExitProcess beendet, bevor dein exit zuschlägt?

Setz mal einen Breakponint drauf.

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
chermanns
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.12.2005
Beiträge: 12
Beitrag chermanns Mitglied 08:44:25 03.09.2010   Titel:              Zitieren

Beim Debugen sieht ja alles gut aus. ExitInstance() wird durchlaufen, danach sehe ich das noch einige Destruktoren von Singeltons durchlaufen werden.
bei einem BreckDann Raus aus der WinMain() sehe ich in der den mainret = meinen Exitcode (5).

Code:
           /*
             * Note that if the exe is managed app, we don't really need to
             * call exit or _c_exit. .cctor should be able to take care of
             * this.
             */
            if ( !managedapp )
                exit(mainret);
Code:
/*
* Note that if the exe is managed app, we don't really need to
* call exit or _c_exit. .cctor should be able to take care of
* this.
*/
if ( !managedapp )
exit(mainret);
Code:
           /*
             * Note that if the exe is managed app, we don't really need to
             * call exit or _c_exit. .cctor should be able to take care of
             * this.
             */
            if ( !managedapp )
                exit(mainret);


danach halt die Ausgabe

Code:
The thread 'Win32 Thread' (0xd34) has exited with code 5 (0x5).
The thread 'Win32 Thread' (0x9f4) has exited with code 5 (0x5).
The thread 'Win32 Thread' (0x734) has exited with code 5 (0x5).
The program '[2356] App.exe: Native' has exited with code 0 (0x0).
Code:
The thread 'Win32 Thread' (0xd34) has exited with code 5 (0x5).
The thread 'Win32 Thread' (0x9f4) has exited with code 5 (0x5).
The thread 'Win32 Thread' (0x734) has exited with code 5 (0x5).
The program '[2356] App.exe: Native' has exited with code 0 (0x0).
Code:
The thread 'Win32 Thread' (0xd34) has exited with code 5 (0x5).
The thread 'Win32 Thread' (0x9f4) has exited with code 5 (0x5).
The thread 'Win32 Thread' (0x734) has exited with code 5 (0x5).
The program '[2356] App.exe: Native' has exited with code 0 (0x0).



Meitest du das oder habe ich dich falsch verstanden?
Die veursachende DLL wird dynamisch von einer andern DLL geladen, die auch zugeliefert wird (zumindest zeigt mir der depedency walker das so an).

Mir ist nicht klar was passiert, ob in der verursachenden DLL ein exit(0) aufgerufen wird oder ein ExitInstanze().

Kann ich (ausser den entsprechenden Entwickler zu benachrichtigen) etwas tun um das fehlerhafte Verhalten zu beseitigen (mir ist nichts bekannt, dass heisst aber nichts :-) )?


Grüsse Carsten
Martin Richter
Moderator

Benutzerprofil
Anmeldungsdatum: 18.04.2006
Beiträge: 13517
Beitrag Martin Richter Moderator 10:13:20 03.09.2010   Titel:              Zitieren

Du kannst doch auch einen Breakpoint auf Funktionen im OS setzen. Hier wäre ExitProcess oder ExitThread der Ansatz...

Evtl. kommt die DLL beim Uninit mir irgendwas nicht klar und terminiert seinerseits den Prozess...

Bist Du denn soweit vorgedrungen beim Debuggen in exit, dass Du wirklich sehen kannst das ExitProcess aufgerufen wird?

_________________
Martin Richter (MVP für C++) WWJD http://blog.m-ri.de
"A well-written program is its own heaven; a poorly written program is its own hell!" The Tao of Programming
chermanns
Mitglied

Benutzerprofil
Anmeldungsdatum: 05.12.2005
Beiträge: 12
Beitrag chermanns Mitglied 13:11:58 06.09.2010   Titel:              Zitieren

Hallo Martin,

ich habe mit dem Entwickler gesprochen, der die "problematische" DLL läde.
Er sagte mir, dass er schon Probleme hatte und er früher innerhalb seiner DLL die problematisch DLL lädt und entlädt, dies (entladen ) nun aber nicht mehr macht (sich aber nun darum kümmert das es klappt).

Mein Statmente ist:
Ich bin zur Zusammenarbeit bereit bin aber nicht für alles verantwortlich was n Zulieferer bereitstellen, zumal der Integrationstest nicht bei uns stattfindet.

Ich bin dankbar für dieses Forum, die Hilfe die es beinhaltet und die offenen Ohren für die Probleme.

Grüsse Carsten
C/C++ Forum :: MFC (Visual C++) ::  ExitInstance() liefert nicht den gewünschten wert zurück   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.