Wir haben eine native C++ - Anwendung, die über COM + auf einem Windows 2003-Server läuft. Ich habe vor kurzem von der Ereignisanzeige bemerkt, dass es Ausnahmen wirft, speziell die C0000005-Ausnahme, die laut http://blogs.msdn.com/calvin_hsia/archive/2004/06/30/170344.aspx bedeutet, dass der Prozess versucht, in den Speicher nicht innerhalb seines Adressraums zu schreiben, aka Zugriffsverletzung.Wie liest man einen Call-Stack?
Der Eintrag in der Ereignisanzeige liefert einen Call-Stack:
LibFmwk UTIL_GetDateFromLogByDayDirectory (char const *, Klasse utilCDate &) + 0xa26c LibFmwk UTIL_GetDateFromLogByDayDirectory (char const *, Klasse utilCDate &) + 0x8af4 ! LibFmwk! UTIL_GetDateFromLogByDayDirectory (char const *, Klasse utilCDate &) + 0x13a1 LibFmwk! utilCLogController :: GetFLFInfoLevel (void) const + 0x1070 LibFmwk! utilCLogController :: GetFLFInfoLevel (void) const + 0x186
Jetzt verstehe ich, dass es mir Methodennamen gibt, um zu sehen, aber ich bekomme das Gefühl, dass die Adresse am Ende jeder Zeile (z. + 0xa26c) versucht mich auf eine bestimmte Zeile oder Anweisung innerhalb dieser Methode zu verweisen.
Also meine Fragen sind:
- Wer weiß, wie ich diese Adresse oder andere Informationen, die in einem Call-Stack, die Linie auf seine fallen innerhalb des Codes zu bestimmen, verwenden könnte über?
- Gibt es irgendwelche Ressourcen da draußen, die ich lesen konnte, um Anruflisten zu verstehen,
- Gibt es Freeware/opensource-Tools, die bei der Analyse eines Aufruf-Stacks helfen könnten, vielleicht durch Anhängen an eine Debug-Symboldatei und/oder Binärdateien ?
Edit: Wie gewünscht, hier ist die Methode, die das Problem verursacht zu sein scheint:
BOOL UTIL_GetDateFromLogByDayDirectory(LPCSTR pszDir, utilCDate& oDate)
{
BOOL bRet = FALSE;
if ((pszDir[0] == '%') &&
::isdigit(pszDir[1]) && ::isdigit(pszDir[2]) &&
::isdigit(pszDir[3]) && ::isdigit(pszDir[4]) &&
::isdigit(pszDir[5]) && ::isdigit(pszDir[6]) &&
::isdigit(pszDir[7]) && ::isdigit(pszDir[8]) &&
!pszDir[9])
{
char acCopy[9];
::memcpy(acCopy, pszDir + 1, 8);
acCopy[8] = '\0';
int iDay = ::atoi(&acCopy[6]);
acCopy[6] = '\0';
int iMonth = ::atoi(&acCopy[4]);
acCopy[4] = '\0';
int iYear = ::atoi(&acCopy[0]);
oDate.Set(iDay, iMonth, iYear);
bRet = TRUE;
}
return (bRet);
}
Dieser Code mehr als 10 Jahren von einem Mitglied unserer Gesellschaft geschrieben Wer ist schon lange weg, so nehme ich nicht an, genau zu wissen, was das tut, aber ich weiß es beteiligt in den Prozess der Umbenennung eines Log-Verzeichnisses von "Heute" zu dem bestimmten Datum, z % 20090329. Die Array-Indizierung, das Memcpy und die Adresse von Operatoren lassen es ziemlich verdächtig aussehen.
Ein anderes Problem, das wir zu haben scheinen, ist, dass dies nur auf dem Produktionssystem passiert, wir konnten es hier auf unseren Testsystemen oder Entwicklungssystemen nie reproduzieren, was uns erlauben würde, einen Debugger anzuhängen.
Sehr geschätzt! Andy
Wenn Sie mit Debug-Symbolen erstellen, erhalten Sie möglicherweise eine tatsächliche Zeilennummer anstelle eines Byte-Offsets. –
Vielen Dank, dass Sie darauf hingewiesen haben. –
Sind Sie sicher, dass das übergebene pszDir mindestens 10 Zeichen lang ist? Es wird definitiv zum Absturz kommen, wenn das nicht der Fall ist. – jussij