Domanda

Sto cercando di aggiungere miglioramenti al programma di un VC ++ 4 anni 6.0. La build di debug viene eseguito dalla riga di comando, ma non nel debugger: si blocca con una violazione di accesso all'interno printf (). Se mi salta la printf, poi si blocca a malloc () (chiamato dall'interno di fopen ()) e non riesco a saltare questo.

Questo significa che non posso correre nel debugger e devono fare affidamento sui vecchi istruzioni printf per vedere cosa sta succedendo. Questo rende ovviamente molto più difficile.

Qualsiasi idea del perché printf () e malloc () fallirebbe durante l'esecuzione in debugger di VC ++? Io non sono bravo in queste cose di basso livello!

Questa è la stack di chiamate dopo la violazione di accesso:

_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()

Questa è la di debug lo smontaggio fino al funzionamento che non riesce:

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

Qui è la nostra fonte di che chiama fopen () e non riesce a 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 );
}

L'errore che ottengo è

Unhandled exception inPISCOOP.exe: 0xC00000005: Access Violation

Saluti,

--- Alistair.

È stato utile?

Soluzione

È possibile utilizzare _CrtSetDbgFlag() per consentire un gruppo di tecniche mucchio debugging utili. C'è una miriade di altri disponibili funzioni di debug CRT che dovrebbe aiutare a rintracciare dove il problema è.

Altri suggerimenti

Quando viene eseguito dal debugger, viene utilizzato un mucchio di diverso; questo viene indicato come il di debug mucchio . Questo ha un comportamento diverso dal mucchio utilizzato al di fuori del debugger, ed è lì per aiutare a catturare i problemi come questo.

Si noti che il Win32 "debug mucchio" è distinto dal VC ++ "debug mucchio"; entrambi sono destinati a fare più o meno la stessa cosa, però. Vedere questo articolo che descrive la differenza di comportamento quando si esegue l'applicazione nel debugger.

In questo caso, probabilmente avete corrotto il mucchio prima di chiamare questa funzione, sia scrivendo al largo della fine o spegnere l'inizio di un blocco di heap.

Il modo più semplice di approcci (a condizione che l'applicazione non utilizza la memoria troppo ampiamente) è quello di consentire il pieno controllo pagina heap (che porrà cosiddetta pagina di guardia dopo la pagina di memoria vostra allocazione è fornito da, che, a sua volta, individuare il luogo esatto nel codice in cui la corruzione si svolge).

Dato che si dispone di strumenti debug di Windows a portata di mano, eseguire il seguente comando per configurare gflags pagina intera mucchio:

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

Nota, è necessario fornire nome dell'eseguibile solo (vale a dire senza prefisso del percorso!)
Poi basta eseguirlo nel debugger - si romperà con il primo tentativo di danneggiare l'heap. La differenza è che qui danneggiamenti mucchio sono per lo più difetti che si manifestano più tardi, quando un (eventualmente) il funzionamento mucchio valido è in effetti ritardati.

Nota, anche:

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

sarà inoltre inserire una pagina di guardia prima della assegnazione.

Correndo con opzione / p solo visualizzerà le opzioni della pagina mucchio attualmente in vigore.

Si può avere un errore di heap corruzione. L'applicazione potrebbe aver corrotto il mucchio prima di open_new_log() è chiamato.

Ho il sospetto jmattias è giusto. La causa principale del problema è probabilmente da qualche altra parte rispetto a dove si va in crash.

Un sacco di cose possono causare il danneggiamento di heap.

  • crei oltre la fine (o inizio) del blocco di memoria allocata.
  • liberando un puntatore due volte, o liberare un puntatore che non è stato assegnato.
  • multithreading vostro programma e il collegamento con il singolo-threaded (non thread-safe) RTL.
  • allocazione di memoria da un'unica pila e liberando in un'altra mucchio.
  • ecc., Ecc.,

Dal momento che si sta utilizzando Visual C ++, è possibile utilizzare la funzione di _CrtSetDbgFlag () del mucchio di debug per accendere il controllo degli errori. È possibile impostare per controllare l'integrità del mucchio a ogni chiamata a malloc o libero. Questo verrà eseguito molto lentamente, ma dovrebbe individuare dove l'insetto è per voi.

Cerca _CrtSetDbgFlag nella documentazione del compilatore.

Ho il sospetto che ci sia una DLL compilata con una versione diversa del runtime C ++ rispetto al resto dell'applicazione. Questo risulta spesso in "memoria all'indirizzo XXX non poteva essere 'letta' / 'scritte'" violazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top