2009-08-19 28 views

Respuesta

27

JCL es gratuito y tiene funciones para eso. Depende de qué tan bien se pueda hacer un seguimiento de pila y cuánta información de depuración esté presente.

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

Añadiré esto simplemente no se puede hacer sin información de depuración de algún tipo. –

6

Ver también our TSynMapFile class.

Puede cargar un archivo .map y comprimirlo en un formato binario optimizado. Será mucho más pequeño que el propio .map (por ejemplo, 900 KB .map -> 70 KB .mab). Este .mab se puede incrustar fácilmente dentro del exe. Por lo tanto, es más pequeño que el formato utilizado por JCL o MadExcept, y también es más pequeño que la información incorporada en tiempo de compilación por Delphi.

Vamos a usar como tal:

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; 

Por ejemplo, aquí es cómo se utiliza a partir de nuestras clases de registro.

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; 

Este método puede recuperar la dirección de la persona que llama y registrar su nombre de unidad, nombre de método y número de línea.

+0

¿Podría usar esto para registrar una pila de llamadas desde una compilación de depuración normal (o una versión con un mapa externo?) Sin tener que agregar, por ejemplo, el código de depuración de Jedi? En algunas circunstancias específicas, podría ser muy útil tener un código que pueda registrar e informar de dónde fue llamado. –

+0

@DavidM Sí, puedes hacer esto. Si no hay adjunto .map/.mab, registraría las direcciones hexadecimales. Entonces, nuestra herramienta LogView puede recuperar la línea de código fuente de un archivo .map existente que coincida con el .exe. Pero, por supuesto, dado que nuestro formato .mab es muy pequeño, no veo ninguna razón para no incrustarlo en .exe, en tiempo de compilación. –

+0

@ArnaudBouchez ¿Puede decirnos cómo incrustarlo en .exe en el momento de la compilación? – SOUser

Cuestiones relacionadas