2009-08-19 18 views

risposta

27

JCL è gratuito e ha funzioni per questo. Dipende da quanto può essere fatta una traccia di stack e quante informazioni di debug sono presenti.

JclDebug.pas

function FileByLevel(const Level: Integer = 0): string; 
function ModuleByLevel(const Level: Integer = 0): string; 
function ProcByLevel(const Level: Integer = 0): string; 
function LineByLevel(const Level: Integer = 0): Integer; 
+14

Aggiungerò semplicemente che non può essere eseguito senza informazioni di debug di qualche tipo. –

6

Vedi anche our TSynMapFile class.

È in grado di caricare un file .map e comprimerlo in un formato binario ottimizzato. Sarà molto più piccolo dello .map stesso (ad esempio 900 KB .map -> 70 KB .mab). Questo .mab può essere facilmente incorporato all'interno dell'exe. È quindi più piccolo del formato utilizzato da JCL o MadExcept e anche più piccolo delle informazioni incorporate in fase di compilazione da Delphi.

Potrai utilizzare come tale:

Map := TSynMapFile.Create; // or specify an exe name 
try 
    i := Map.FindSymbol(SymbolAddr); 
    if i>=0 then 
    writeln(Map.Symbols[i].Name); 
    // or for your point: 
    writeln(Map.FindLocation(Addr)); // e.g. 'SynSelfTests.TestPeopleProc (784)' 
finally 
    Map.Free; 
end; 

Per esempio, ecco come viene utilizzato dai nostri corsi di registrazione.

procedure TSynLog.Log(Level: TSynLogInfo); 
var aCaller: PtrUInt; 
begin 
    if (self<>nil) and (Level in fFamily.fLevel) then begin 
    LogHeaderLock(Level); 
    asm 
     mov eax,[ebp+4] // retrieve caller EIP from push ebp; mov ebp,esp 
     sub eax,5  // ignore call TSynLog.Enter op codes 
     mov aCaller,eax 
    end; 
    TSynMapFile.Log(fWriter,aCaller); // here it will call TSynMapFile for the current exe 
    LogTrailerUnLock(Level); 
    end; 
end; 

Questo metodo è in grado di recuperare l'indirizzo del chiamante e registrare il nome dell'unità, il nome del metodo e il numero di riga.

+0

Si può usare questo per registrare uno stack di chiamate da una normale build di debug (o rilasciare con una mappa esterna?) Senza dover aggiungere, ad esempio, il codice di debug Jedi? In alcune circostanze specifiche potrebbe essere molto utile avere un codice che possa registrare e segnalare da dove è stato chiamato. –

+0

@DavidM Sì, puoi farlo. Se non è associato .map/.mab, registrerebbe gli indirizzi esadecimali. Quindi il nostro strumento LogView è in grado di recuperare la riga del codice sorgente da un file .map esistente che corrisponde al file .exe. Ma ovviamente, dal momento che il nostro formato .mab è molto piccolo, non vedo alcun motivo per non incorporarlo nell'exe, al momento della compilazione. –

+0

@ArnaudBouchez Puoi dire come incorporarlo in .exe in fase di compilazione? – SOUser

Problemi correlati