Frage

Ich versuche, Verbesserungen eines 4 Jahre alten 6.0-Programm VC ++ hinzuzufügen. Das Debug-Build läuft von der Kommandozeile, aber nicht in dem Debugger: es mit einer Zugriffsverletzung innerhalb printf stürzt (). Wenn ich die printf überspringen, dann stürzt es in malloc () (genannt von innen fopen ()) und ich kann nicht über das überspringen.

Das bedeutet, dass ich nicht im Debugger laufen und auf den alten printf Aussagen verlassen, um zu sehen, was los ist. Das ist offensichtlich macht es schwieriger, eine ganze Menge.

Jede Idee, warum printf () und malloc () fehlschlagen würde, wenn unter dem Debugger VC ++ ausgeführt wird? Ich bin nicht gut auf diesem niedrigen Niveau stuff!

Hier ist der Aufruf-Stack nach der Zugriffsverletzung:

_heap_alloc_dbg(unsigned int 24, int 2, const char * 0x0046b3d8 `string', int 225) line 394 + 8 bytes
_nh_malloc_dbg(unsigned int 24, int 0, int 2, const char * 0x0046b3d8 `string', int 225) line 242 + 21 bytes
_malloc_dbg(unsigned int 24, int 2, const char * 0x0046b3d8 `string', int 225) line 163 + 27 bytes
_lock(int 2) line 225 + 19 bytes
_getstream() line 55 + 7 bytes
_fsopen(const char * 0x00468000 `string', const char * 0x00466280 `string', int 64) line 61 + 5 bytes
fopen(const char * 0x00468000 `string', const char * 0x00466280 `string') line 104 + 15 bytes
open_new_log(const char * 0x00468000 `string') line 66 + 14 bytes
log_open(const char * 0x00468000 `string', int 0) line 106 + 9 bytes
Xlog_open(const char * 0x00468000 `string', int 0) line 51 + 13 bytes
service_start(unsigned long 1, char * * 0x009a0e50) line 3152 + 12 bytes
service_init2(char * 0x00471fcc char * NTPROGRAM, char * 0x004723c4 char * NTSERVICE, char * 0x00466540 `string', unsigned long 1, char * * 0x009a0e50) line 508 + 13 bytes
service_init(char * 0x00471fcc char * NTPROGRAM, char * 0x004723c4 char * NTSERVICE, unsigned long 2, char * * 0x009a0e50) line 548
main(unsigned long 2, char * * 0x009a0e50) line 3131
mainCRTStartup() line 206 + 25 bytes
KERNEL32! 7c817067()

Hier ist die Debug-Zerlegen für den Betrieb auf, die fehlschlägt:

0041EA7E   jmp         _heap_alloc_dbg+2B3h (0041eb23)
0041EA83   mov         edx,dword ptr [_lTotalAlloc (004b4294)]
0041EA89   add         edx,dword ptr [nSize]
0041EA8C   mov         dword ptr [_lTotalAlloc (004b4294)],edx
0041EA92   mov         eax,[_lCurAlloc (004b429c)]
0041EA97   add         eax,dword ptr [nSize]
0041EA9A   mov         [_lCurAlloc (004b429c)],eax
0041EA9F   mov         ecx,dword ptr [_lCurAlloc (004b429c)]
0041EAA5   cmp         ecx,dword ptr [_lMaxAlloc (004b42a0)]
0041EAAB   jbe         _heap_alloc_dbg+249h (0041eab9)
0041EAAD   mov         edx,dword ptr [_lCurAlloc (004b429c)]
0041EAB3   mov         dword ptr [_lMaxAlloc (004b42a0)],edx
0041EAB9   cmp         dword ptr [_pFirstBlock (004b4298)],0
0041EAC0   je          _heap_alloc_dbg+25Fh (0041eacf)
0041EAC2   mov         eax,[_pFirstBlock (004b4298)]
0041EAC7   mov         ecx,dword ptr [pHead]
0041EACA   mov         dword ptr [eax+4],ecx

Hier ist unsere Quelle für die Anrufe fopen () und nicht in malloc ()

FILE *open_new_log( const char *logfile )
{
    FILE *fp;
    int retry = 0;

    while( ( fp = fopen( logfile, "w" ) ) == NULL && ++retry < 300 )
        Sleep( 1000 );

    return( fp );
}

Der Fehler ich erhalte, ist

Unhandled exception inPISCOOP.exe: 0xC00000005: Access Violation

Grüße,

--- Alistair.

War es hilfreich?

Lösung

Sie können mit _CrtSetDbgFlag() ermöglichen eine Reihe von nützlichen Heap-Debugging-Techniken. Es gibt eine Vielzahl von anderen CRT Debugging-Funktionen zur Verfügung das sollte Ihnen helfen, die Spur zu kommen, wo Ihr Problem ist.

Andere Tipps

Wenn Sie aus dem Debugger ausführen, wird ein anderer Haufen verwendet; dies wird als Debug-Heap bezeichnet. Dies hat ein anderes Verhalten aus dem Heap außerhalb des Debugger verwendet und hilft Ihnen Probleme wie diese fangen zu helfen.

Beachten Sie, dass der Win32 "Debug-Heap" aus dem "Debug-Heap" VC ++ unterscheidet; beide sollen mehr oder weniger die gleiche Sache tun, aber. Siehe diesem Artikel , die den Unterschied im Verhalten beschreibt, wenn Sie die Anwendung ausführen unter dem Debugger.

In diesem Fall haben Sie wahrscheinlich den Heap beschädigt, bevor Sie diese Funktion aufrufen, entweder durch das Ende abschreiben oder aus dem Start eines Heap-Blocks.

Die einfachste Ansätze (vorausgesetzt, dass die Anwendung nicht-Speicher verwendet, ist zu umfangreich) voll Seitenheap Prüfung ermöglichen (die so genannte Schutzseite nach der Speicherseite platzieren Ihre Zuordnung von zur Verfügung gestellt wird, die wiederum wird lokalisiert die genaue Stelle im Code, wo Korruption stattfindet).

Da haben Sie Windows-Debugging-Tools handlich, führen Sie die folgenden gflags ganze Seite Heap konfigurieren Befehl:

gflags[.exe] /p /enable yourapp.exe /full

Hinweis, sollten Sie Namen der ausführbaren Datei zur Verfügung stellen allein (das heißt ohne Pfadpräfix!)
Dann führen Sie es einfach unter dem Debugger - mit dem ersten Versuch zu verderben den Haufen brechen. Der Unterschied hier ist, dass Haufen Verfälschungen sind meist Mängel verzögert, die sich später manifestieren, wenn ein (möglicherweise) gültig Heap Betrieb wirksam ist.

Beachten Sie auch:

gflags[.exe] /p /enable yourapp.exe /full /backwards

findet zusätzlich eine Schutzseite vor Ihrer Zuordnung.

Beim Laufen mit / p allein Heap Seite Optionen zur Zeit in der Tat angezeigt werden soll.

Sie können eine Heapbeschädigung Fehler haben. Ihre Anwendung beschädigt haben den Heap vor open_new_log() genannt wird.

Ich vermute, jmattias ist richtig. Die Ursache des Problems wahrscheinlich irgendwo anders als dort, wo es abstürzt.

Eine Menge Dinge kann Heapbeschädigung führen.

  • Schreiben über das Ende (oder Anfang) des Speicherblocks, der zugeordnet wurde.
  • befreit einen Zeiger zweimal oder einen Zeiger zu befreien, die nicht zugewiesen wurden.
  • Multithreading Ihr Programm und die Verknüpfung mit dem Single-Threaded (nicht Thread-sicher) RTL.
  • Speicher von einem Haufen Aufteilung und es auf einem anderen Haufen zu befreien.
  • usw., Etc.

Da Sie Visual C ++ verwenden, können Sie die _CrtSetDbgFlag () Funktion des Debug-Heap verwenden einzuschalten Fehlerprüfung. Sie können es die Integrität des Haufens bei jedem Aufruf von malloc oder kostenlos zu überprüfen. Das wird sehr langsam laufen, aber es sollte genau feststellen, wo der Fehler für Sie.

Suchen Sie nach _CrtSetDbgFlag in dem Compiler-docs.

Ich habe den Verdacht, dass es eine DLL mit einer anderen Version der C ++ Laufzeit als der Rest der Anwendung kompiliert wird. Dies wird dazu führen, oft als „Speicher an der Adresse XXX kann nicht‚gelesen‘/‚geschrieben‘wird“ Verletzungen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top