EurekaLog Forums
  #11  
Old 22-Jul-2009, 07:19 AM
Alex Alex is offline
Support Team
 
Join Date: Jan 2009
Location: Russia
Posts: 1,538
Send a message via ICQ to Alex
Default

Hi,

You can use CustomDataRequest event to add any additional info you like to bug reports. See here: http://www.eurekalog.com/docs/custom...uesthowto.html

Or sometimes you can use CPU and assembly tabs to extract info on local variables.
__________________
Best regards...

Alexander - EurekaLog Developer Team
  #12  
Old 22-Nov-2010, 07:56 AM
E_Pluribus_Unum E_Pluribus_Unum is offline
Junior Member
 
Join Date: Jan 2009
Posts: 5
Default Values of Procedure/Method parameters

Hi!

It would be great, if the report contain the values of the Procedure/Method parameters.
  #13  
Old 22-Nov-2010, 03:30 PM
Kevin G. McCoy
Guest
 
Posts: n/a
Default Re: Values of Procedure/Method parameters

On 11/22/2010 12:56 AM, E_Pluribus_Unum wrote:
Quote:
It would be great, if the report contain the values of the Procedure/Method parameters.
This and your global variable idea would be difficult/impossible/impractical to implement I think. The amount of overhead required to hold all memory locations of all variables and their original type would be huge. It is not possible to determine variable values by simply looking at the stack, without knowing the original data type. The IDE "knows" the variable types/values because it has full access to the source code and DCUs.  EL, bound to your EXE,
does not have access to the original source code.

The better way to do this would be to log variable values to a file and include this file when EL catches an exception.  Since *you* know the variable type, you can do the conversion to a string yourself in the debug code.

In my apps, I log all SQL queries in one log file and debug values in another. I periodically trim the files so the do not get too big, yet hold about 8-24 hours of application use.

You can add any file you like to the EL error report by using the OnAttachedFilesRequest event and add the names of your logs using AttachedFiles.Add() method.

As a programmer, you generally know where the problem areas in your code are located :-)  So, this is where you put the debug logging code.

I also log button clicks and user navigation (notebook tab clicks, etc) around my apps, so I know what they were doing, leading up to the crash.

When EL catches an exception, I tell EL to zip up the two debug files
along with the normal screen shot and ELF file. EL sends the zip and the bug report to my Mantis server where I can open the ELF, SQL or Debug logs to see what was happening in my app in the hours leading up to the crash.

99% of the time, I can tell exactly what went wrong, just by looking at
the logs. I can even catch stupid-user-mistakes :-)

My debug logger stores the date/time, proc/function/method name, unit
name, class name, and line number of the debug function call, along with any text I wish to add.  Everything except the text is done automatically by the debug function internal code, so a debug statements looks something like: LogMsg('Button click'), which produces a line in my log looking something like this: 19-Nov-2010 08:58:38 [D] ejNotify.pas:1440 (ejNotify.TNotifyAccountWriteOff.BuildNotifyEmail) "Button click" The SQL logger simply logs all outbound SQL text going to the database server.  I can cut and paste out of this log into a query browser and recreate the results of the query. I use the normal logging feature of the MyDAC or Zeos Lib SQL components for this.

HTH,

Kevin G. McCoy
  #14  
Old 18-Mar-2011, 04:02 PM
jffournon jffournon is offline
Junior Member
 
Join Date: Jul 2010
Posts: 3
Default Re: Values of Procedure/Method parameters

I'm not a specialist, but I think it's theoretically possible for you to show the values of simple parameters (not pointers-based values) of Procedure/Method at loading time of the bug report, from/within the IDE opened on the right version of the project :

The principle would consist to store the values of the parameters found in the stack at exception time (hexa format) and exploit them at loading time through the match of theses hexa values with the declarations of Procedure/Method.

Of course, this never can replace an exhaustive and preventive log for debugging, as you describe.

We experienced a similar solution and the verdict was that it cannot be kept in production because of slowdown execution it produced.

So now whe always put our applications in production without any preventive log, and always keep the same versions of theses applications compiled with our exhaustive log options, to be able to punctually install them if a bug cannot be resolved with the standard EKL log.

And so the disposal of parameters values (even only for simple parameters) become again interesting because it can prevent the heavy install and use of the exhaustive and preventive log applications.

Thanks.
J.F. Fournon

Quote:
Originally Posted by Kevin G. McCoy View Post
On 11/22/2010 12:56 AM, E_Pluribus_Unum wrote:

This and your global variable idea would be difficult/impossible/impractical to implement I think. The amount of overhead required to hold all memory locations of all variables and their original type would be huge. It is not possible to determine variable values by simply looking at the stack, without knowing the original data type. The IDE "knows" the variable types/values because it has full access to the source code and DCUs.  EL, bound to your EXE,
does not have access to the original source code.

The better way to do this would be to log variable values to a file and include this file when EL catches an exception.  Since *you* know the variable type, you can do the conversion to a string yourself in the debug code.

In my apps, I log all SQL queries in one log file and debug values in another. I periodically trim the files so the do not get too big, yet hold about 8-24 hours of application use.

You can add any file you like to the EL error report by using the OnAttachedFilesRequest event and add the names of your logs using AttachedFiles.Add() method.

As a programmer, you generally know where the problem areas in your code are located :-)  So, this is where you put the debug logging code.

I also log button clicks and user navigation (notebook tab clicks, etc) around my apps, so I know what they were doing, leading up to the crash.

When EL catches an exception, I tell EL to zip up the two debug files
along with the normal screen shot and ELF file. EL sends the zip and the bug report to my Mantis server where I can open the ELF, SQL or Debug logs to see what was happening in my app in the hours leading up to the crash.

99% of the time, I can tell exactly what went wrong, just by looking at
the logs. I can even catch stupid-user-mistakes :-)

My debug logger stores the date/time, proc/function/method name, unit
name, class name, and line number of the debug function call, along with any text I wish to add.  Everything except the text is done automatically by the debug function internal code, so a debug statements looks something like: LogMsg('Button click'), which produces a line in my log looking something like this: 19-Nov-2010 08:58:38 [D] ejNotify.pas:1440 (ejNotify.TNotifyAccountWriteOff.BuildNotifyEmail) "Button click" The SQL logger simply logs all outbound SQL text going to the database server.  I can cut and paste out of this log into a query browser and recreate the results of the query. I use the normal logging feature of the MyDAC or Zeos Lib SQL components for this.

HTH,

Kevin G. McCoy
  #15  
Old 05-Mar-2012, 04:37 PM
berocoder berocoder is offline
Junior Member
 
Join Date: Sep 2008
Location: Finland in Österbotten
Posts: 7
Send a message via Skype™ to berocoder
Exclamation Can EurekaLog do this ?

I currently use JCL to log the callstack to a log-file in case of exception. It works fine. But I miss 2 things.

1. When I re raise an exception I loose the original source line of exception. For example:

procedure Buggy;
begin
// Many sourcelines and code that cause an exception
end;

procedure Caller;
begin
try
Buggy;
except
// Code that cleanup after an exception.
raise TException.Create('procedure Caller failed'); // Callstack show this line
end;
end;

In this case the callstack contains the line for raise TException, not the original sourceline in procedure Buggy. Can EurekaLog log the original sourceline in this case ?

2. When an exception happens in Delphi IDE I noticed I can see the values of arguments in the callstack. But JCL is unable to log those. Can EurekaLog do that ?

I use Delphi 2007, but plan to upgrade to Delphi XE2 when time permits and some components is ported to Unicode.

Regards
Roland Bengtsson
Team Attracs
  #16  
Old 16-Mar-2012, 09:07 AM
Alex Alex is offline
Support Team
 
Join Date: Jan 2009
Location: Russia
Posts: 1,538
Send a message via ICQ to Alex
Default

Hi,

Sorry for the delay.

1. Such feature is implemented in EurekaLog 7. See: http://www.eurekalog.com/help/eureka...tions_page.php

EurekaLog 6 doesn't have any specific support for this feature, but you may try to workaround this manually. This, however, is not pretty.

The easiest approach is to use different exception types and use exception filters to alter default processing.

For example:

procedure Caller;
begin
  try
    Buggy;
  except
    on E: Exception do
    begin
      StandardEurekaNotify(E, ExceptAddr);
      // Code that cleanup after an exception. 
      raise ECallerError.Create('procedure Caller failed'); // setup exception filter for 'ECallerError', Handler = RTL
    end;
  end;
end;
If you can't afford custom exception types - then thingg get more complicated. You need to setup your own event handlers, which alters processing based on flags (defined by you). Those flags can set in your "except" handlers.

2. Unfortunately, it is not possible in x86-32. This may be implemented in EurekaLog for x64.

Such feature requires knowledge of source files, which is available to debugger, but usually is not present in final exe. Even if you add it (for example, by including TD32/TDS info) - x86-32 has architecture, which may prevent you from getting arguments. For example, typical calling convention for Delphi is "register". This means that arguments are passed via CPU registers. Those registers can be re-used for other purposes immediately at routine's start. Debugger can track this. External software - not so much.

x86-64 is different in this matter: there is only 1 calling convention and arguments are always accessible. (I may be wrong; this requires more investigation)
__________________
Best regards...

Alexander - EurekaLog Developer Team
  #17  
Old 19-Mar-2012, 07:07 AM
berocoder berocoder is offline
Junior Member
 
Join Date: Sep 2008
Location: Finland in Österbotten
Posts: 7
Send a message via Skype™ to berocoder
Smile Can EurukaLog do this

Thanks for the information.
Actually we ship full debug info to released exe-file. And we have plans to update from Delphi 2007 to latest Delphi XE2 and x64. So to get arguments to methods would be a very nice feature in future versions of EurekaLog.
Even if it only apply for x64 exe.

Regards
Roland Bengtsson

Quote:
Originally Posted by Alex View Post
Hi,

Sorry for the delay.

1. Such feature is implemented in EurekaLog 7. See: http://www.eurekalog.com/help/eureka...tions_page.php

EurekaLog 6 doesn't have any specific support for this feature, but you may try to workaround this manually. This, however, is not pretty.

The easiest approach is to use different exception types and use exception filters to alter default processing.

For example:

procedure Caller;
begin
  try
    Buggy;
  except
    on E: Exception do
    begin
      StandardEurekaNotify(E, ExceptAddr);
      // Code that cleanup after an exception. 
      raise ECallerError.Create('procedure Caller failed'); // setup exception filter for 'ECallerError', Handler = RTL
    end;
  end;
end;
If you can't afford custom exception types - then thingg get more complicated. You need to setup your own event handlers, which alters processing based on flags (defined by you). Those flags can set in your "except" handlers.

2. Unfortunately, it is not possible in x86-32. This may be implemented in EurekaLog for x64.

Such feature requires knowledge of source files, which is available to debugger, but usually is not present in final exe. Even if you add it (for example, by including TD32/TDS info) - x86-32 has architecture, which may prevent you from getting arguments. For example, typical calling convention for Delphi is "register". This means that arguments are passed via CPU registers. Those registers can be re-used for other purposes immediately at routine's start. Debugger can track this. External software - not so much.

x86-64 is different in this matter: there is only 1 calling convention and arguments are always accessible. (I may be wrong; this requires more investigation)
  #18  
Old 28-Nov-2013, 10:55 AM
Alex Alex is offline
Support Team
 
Join Date: Jan 2009
Location: Russia
Posts: 1,538
Send a message via ICQ to Alex
Default

Hi,

Sorry, won't do.

While it is technically possible in some cases, but implementing this feature is very hard, and the results will not be pretty, it won't work in all cases. Basically, it will fail more often that succed.

There are the following problems with this feature:
1. Default calling convention is "register", which means most of the time arguments are stored in registers, not in the stack.
2. Arguments in registers may be used and throwed away before calling routine in question, so attempt to read registers directly will give us some trashed values instead.
3. Even if arguments are still valid, when code calls next routine - arguments of current routine are stored somewhere else (either in stack or in another register). In order to get original values we need to create a simple virtual machine able to partially execute/translate x86 code backwards, so instructions can be reversed.
4. Arguments may simply optimized out after usage, so it won't be accessible in any form at all.
5. Even though x86-64 architecture demands using stack space for each argument, but this stack space is considered as free slack space. There is no requerement to store actual arguments here. In fact, any compiler with optimizations will treat this space as free/temp.
6. Even if we have somehow get RAW representation of value, the most arguments are complex and passed by pointers. It is not possible to translate such arguments into single values to be inserted into call stack.

Why debugger can do this?
1. Debugger executes code step by step, so it may follow where arguments go while it executes code. Exeption tracer (such as EurekaLog) activates only when exception is raised - e.g. after code was already executed. Attempt to debug your application from within (by exception tracer) will greatly slow down execution.
2. Debugger has access to advanced debug information (about 10 Mb per 1 Mb of code). Exception tracer has to use compact debug information. We already have enough complains about application size increases.
3. Even debugger is unable to show all arguments when these arguments are optimized out. Debugger shows "???" instead of actual values.
4. Even debugger is unable to show complex objects, showing pointers instead.

To summarize:
1. This feature is insanely hard to implement properly.
2. This feature will not give satisfying results even when implementing properly (e.g. missed arguments, complex objects, etc.).
3. This feature will not give you power of debugger: the ability to investigate/evaluate arguments.
4. Alternative (using logger such as SmartInspect) is much simplier to implement, and much more reliable: you are guarantee to see arguments which you want - because you manually specified them. You can log anything you want, in any form you want.
5. The performance drawback of logging can be mitigated by logging on request. You can log only important places, which will not slow down your execution. When you receive bug report which you can not solve without knowing arguments, alter you logging to add logging of desired arguments and re-release application. Remove additional logging as soon as you fix the problem. Or you may implement logging anywhere, but enable it only if "debug me" option is enabled.
6. If you don't like "manual log", then the only solution is to use CPU stack and memory dump. Unfortunately, Delphi does not have any support for dumps, so you has to create/view dumps manually.
__________________
Best regards...

Alexander - EurekaLog Developer Team
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
"Variables" don't work in all fields where they are needed Alexander Closed suggestions 4 15-Apr-2009 11:09 AM
Variables Ed.. Closed bug reports 13 08-Oct-2008 06:13 PM
Variables in options dialog RFloor General 1 10-May-2007 04:42 PM


All times are GMT. The time now is 02:47 AM.


Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.