Ver Mensaje Individual
  #10  
Antiguo 06-10-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Reputación: 29
Lepe Va por buen camino
Como en este hilo se daba información general, eso mismo hice yo.

Para el caso de jclDebug, ha de tenerse en cuenta 2 cosas:
- Hay que incluir en el primer formulario o Datamodule que crees el uses jclDebug, ya que realiza una inicialización en su unidad para empezar el "traceo" de excepciones.

- En la distribución de tu ejecutable, tienes que distribuir un archivo .map que se crea al compilar, (abrelo con el bloc de notas para saber de que hablo). En este caso se tiene que distribuir un par de megas más, pero perece la pena.

- Además de la información de jclDebug, se debe incluir las ventanas abiertas en tu aplicación (si son varias) para saber lo que hacia el usuario, (el objeto TScreen vale para eso).

-En cuanto al uso de compresores de ejecutables, acabo de probarlo, y efectivamente el compresor elimina la información de debug, por lo que interfiere con JCLDEBUG, como ya sabemos: no se puede tener todo .

Para el primer punto, yo me he construido mi propia jclDebug, que unicamente cambia los procedimientos por funciones y devuelve el error en una variable. Os lo dejo aqui:

(El nombre de la unidad lleva el prefijo LP (Lepe) para que no interfiera con posibles modificaciones de la JCL)

Saludos
Código Delphi [-]
{-----------------------------------------------------------------------------
 Unit Name: lpJclDebug
 Author:    Lepe
 Purpose:   Tracear excepciones usando JclDebug.

 - Project --> options --> INsert Jcl Debug
    (Eso activará las opciones de project ->Options:
     - Compiler -> Debugging todas marcadas excepto la ultima
     - Linker   -> Map file -> Detailed
    )
 - Poner esta unidad al principio de los uses del primer Formulario o datamodule.
 - Usar un applicationEvents y en el evento ONException añadir:

     ShowMessage(lpjcldebug.Error)

 - solo se necesita acceder a esa variable, lo demás de esta unidad ni tocarlo.

History: Modificado para que sea una funcíón y devuelva el string con las
          excepciones.
-----------------------------------------------------------------------------}


unit lpJclDebug;

interface
//procedure MyLogException(ExceptObj: TObject; ExceptAddr: Pointer; IsOS: Boolean);

{-----------------------------------------------------------------------------
  Procedure: LogException
  Author:    Lepe
  Date:      09-mar-2005
  Arguments: ExceptObj: TObject; ExceptAddr: Pointer; IsOS: Boolean
  Result:    string
      Devuelve un string con la traza de la excepcion.
-----------------------------------------------------------------------------}
  function LogException(ExceptObj: TObject; ExceptAddr: Pointer; IsOS: Boolean):string;

  procedure MyLogException(ExceptObj: TObject; ExceptAddr: Pointer; IsOS: Boolean);

  var Error:string; // se tiene el error producido
  var UseMaxDeep:Boolean; // usará una profundidad el doble de lo normal

implementation
uses
  JclDebug, JclHookExcept, TypInfo, Classes,sysutils;

function LogException(ExceptObj: TObject; ExceptAddr: Pointer; IsOS: Boolean):string;
var
  TmpS: string;
  ModInfo: TJclLocationInfo;
  I: Integer;
  ExceptionHandled: Boolean;
  HandlerLocation: Pointer;
  ExceptFrame: TJclExceptFrame;
  MaxDeep, idx:Integer;
  Log:TStringList;

begin
  log:= TStringList.Create;
  try
  Log.Clear;
  MaxDeep:=0;
  TmpS := 'Exception ' + ExceptObj.ClassName;
  if ExceptObj is Exception then
    TmpS := TmpS + ': ' + Exception(ExceptObj).Message;
  if IsOS then
    TmpS := TmpS + ' (OS Exception)';
  Log.Add(TmpS);
  ModInfo := GetLocationInfo(ExceptAddr);
  idx:= Log.Add(Format(
    'Exception '+ #13#10+
    ' UnitName   : %s' +#13#10+
    ' Procedure  : %s' +#13#10+
    ' Line       : %d'+
    ' OffsetLine : %d',
    [ModInfo.UnitName,
     ModInfo.ProcedureName,
     ModInfo.LineNumber,
     modinfo.offsetfromlinenumber]));
  Inc(MaxDeep);
  if stExceptFrame in JclStackTrackingOptions then
  begin
// added at the end    Log.Add('  Except frame-dump:');
    I := 0;
    ExceptionHandled := False;
    while (UseMaxDeep or not ExceptionHandled) and
      (I < JclLastExceptFrameList.Count) do
    begin
      ExceptFrame := JclLastExceptFrameList.Items[i];
      ExceptionHandled := ExceptFrame.HandlerInfo(ExceptObj, HandlerLocation);
      if (ExceptFrame.FrameKind = efkFinally) or
          (ExceptFrame.FrameKind = efkUnknown) or
          not ExceptionHandled then
        HandlerLocation := ExceptFrame.CodeLocation;
      ModInfo := GetLocationInfo(HandlerLocation);
      TmpS := Format(
        '    EXCFRAME $%p (TIPO %s',
        [ExceptFrame.ExcFrame,
         GetEnumName(TypeInfo(TExceptFrameKind), Ord(ExceptFrame.FrameKind))]);


      if ExceptionHandled then
        TmpS := TmpS + ', handles exception)'
      else
        TmpS := TmpS + ')';
//      Log.Add(TmpS);
//      if ExceptionHandled then
//        Log.Add(Format(
//          '      HANDLERLOCATION $%p',
//          [HandlerLocation]))
//      else
//        Log.Add(Format(
//          '      HANDLERLOCATION $%p',
//          [HandlerLocation]));
  Inc(MaxDeep);
      Log.Add(STRINGofchar(' ',MaxDeep*2)+Format(
    ' UnitName   : %s' +
    ' Procedure  : %s' +
    ' SourceName : %s' +
    ' Line       : %d',
        [ModInfo.UnitName,
         ModInfo.ProcedureName,
         ModInfo.SourceName,
         ModInfo.LineNumber]));
      Inc(I);
//    'Exception '+ #13#10+
//    ' UnitName   : %s' +#13#10+
//    ' Procedure  : %s' +#13#10+
//    ' SourceName : %s' +#13#10+
//    ' Line       : %d',

    end;
  end;
  Log.Add('');
  Log.Insert(idx+1,'  Deep of Except frame-dump : '+IntToStr(MaxDeep));
  finally
    Result := Log.Text;
    FreeAndNil(Log);
  end;
end;

procedure MyLogException(ExceptObj: TObject; ExceptAddr: Pointer; IsOS: Boolean);
begin
  Error := LogException(ExceptObj, ExceptAddr, IsOS);
end;

initialization
  UseMaxDeep:= False;
  JclAddExceptNotifier(MyLogException);

  JclStackTrackingOptions := JclStackTrackingOptions + [stExceptFrame];
  JclStartExceptionTracking;

finalization
  JclRemoveExceptNotifier(MyLogException);
end.

saludos
Responder Con Cita