Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 06-10-2005
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Lepe, muchas gracias por tu información, que me ha servido para probar el "JclDebug" e incluso implementarlo (a partir de uno de los ejemplos que se pueden encontrar) en XEditor. ¿Para qué demonios? Ahí está el caso. Este programa, cuando se produce una excepción, muestra al usuario un mensaje con la misma y le da la posibilidad de enviarme por correo un reporte de error.

Entonces, me he dicho, hombre, si añades la información del "JclDebug" el reporte de error contendrá bastante más información, que podrá resultar muy útil para tratar de solucionar posibles problemas en el programa. Y dicho y hecho, más o menos, he conseguido que el reporte incluya la información que puede proporcionar en caso de excepción el "JclDebug".

Ahora bien, parece ser que no puedo utilizar el compresor de ejecutables para comprimir el del programa susomentado, porque, entonces el "JclDebug" no funciona como debe y al producirse la excepción e intentar conseguir la información correspondiente se produce a su vez otra excepción y... para qué seguir.

El programa ocupa ahora unos 3,44 MB, y comprimido se quedaba en menos de uno, pero, no es esto del todo importante, puesto que el programa instalador comprime el ejecutable (y el resto de archivos) sin que afecte al "JclDebug" y, al cabo, estamos hablando de que antes de implementar lo dicho el programa de instalación ocupaba unos 1,41 MB y ahora se quedaría en 1,95 MB.

Puesto que la ejecución del programa no se ve ralentizada (es aquello de que ahora, incluso, no es preciso descomprimir el ejecutable cada que se pone en marcha el programa) y al convencerme el asunto como para pensar en publicar el programa de este modo, asumiendo que no irá comprimido y que el asistente de instalación ocupará un poco más, me pregunto todavía...

¿Merece la pena el reporte de error? ¿Es necesario o puede ser útil cuando el programa ya se ha publicado, quiero decir, cara al usuario? ¿Debería usar el "JclDebug" únicamente cuando esté trabajando yo mismo en el programa y dejar de usarlo a la hora de publicar el mismo? ¿Puedes tú mismo o alguien que esto lea decirme algo que me aclare un poco estas dudas que tengo?

Muchas gracias de antemano. Si véis que me dejo algo en el tintero, me lo hacéis saber y veremos cómo hago para explicar lo que sea necesario explicar con más detalle. En todo caso, Lepe, gracias por la información, puesto que nada más sencillo que valerse uno del "JclDebug" (al menos para ciertas cosas, porque no es poco potente, a lo que se ve), sin olvidar el trabajo que les ha tenido que llevar a sus programadores el preparar algo así, claro está.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 06-10-2005 a las 02:50:07. Razón: Corrección del texto.
Responder Con Cita
  #2  
Antiguo 06-10-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 31
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
  #3  
Antiguo 06-10-2005
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Cita:
Empezado por Lepe
En la distribución de tu ejecutable, tienes que distribuir un archivo .map que se crea al compilar, (...)
El caso es que obtengo los mismos resultados (tras probar con cierta excepción) tanto si el archivo "MAP" está junto al ejecutable como si no lo está... ¿me estoy perdiendo algo? Obviamente el archivo "MAP" contiene no poca información, entonces, ¿cómo es que obtengo los mismos resultados tanto si este archivo está disponible como si no lo está? ¿Tal vez se por el tipo de excepción conque estoy probando todo esto, que no precise de la información del archivo "MAP"? Gracias Lepe por la información, en todo caso.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #4  
Antiguo 06-10-2005
ingel ingel is offline
Miembro
 
Registrado: jun 2003
Posts: 244
Poder: 24
ingel Va por buen camino
donde consigo los componentes

estoy buscandolos pero hasta ahora no los encuentro ..
y la ultima
Lepe: a que te refieres con lo de las ventanas abiertas ?

GRACIAS por tu ayuda
Ingel
Responder Con Cita
  #5  
Antiguo 06-10-2005
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Cita:
Empezado por ingel
estoy buscandolos pero hasta ahora no los encuentro ..
Si te refieres a la Jedi Library puedes encontrar esta en su página Web: Project JEDI.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #6  
Antiguo 06-10-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 31
Lepe Va por buen camino
Si tu programa tiene 60 o 70 ventanas y se produce una excepción del tipo '' is not a valid date... ¿En cual de las 70 ventanas se ha producido el error?.

Podríamos averiguarlo por el nombre de la unidad (UnitName del mensaje), pero también nos dá más información de los hábitos de ese usuario, es decir, si tiene varias ventanas de nuestro programa abiertas al mismo tiempo, o si abre una ventana, modifica lo que sea y la cierra; según los hábitos de los usuarios, podemos agilizar la apertura y cierre de las ventanas u otros detalles de nuestra aplicación.


El bucle sería algo así:
Código Delphi [-]
for i:= 0 to Screen.Count-1 do
 Mensaje := Mensaje + Screen[i].ClassName + ' ' + Screen[i].Name + #10#13

ShowMessage (mensaje);

Ni que decir tiene que todo esto debe grabarse en un .txt o .log y al usuario solo indicarle que ha habido un error y se ha guardado la información de depuración.

Para el .log, ya que instalas la JVCL, tienes el TjvLogfile en la pestaña
"Jv Utils"

En cuanto a las preguntas de dec no puedo asegurar nada. Soy consciente de que en el .exe van algunos datos de la JCLdebug, tal y como dice la ventana que aparece tras hacer un Build Project estando activo el "insert jcl debug data", en mi caso, dice que el archivo .map son 3 megas, y la información de debug incluida en el .exe son 414 kb. No me queda claro si va todo en el exe o no.

Compilar sin información de debug y con información de debug si varía 400 kb en el tamaño del ejecutable.

saludos

saludos
Responder Con Cita
  #7  
Antiguo 07-10-2005
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Gracias Lepe, por todo.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 01:26:58.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi