Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am getting an error "Invalid floating point operation" while creating a new form as below:
procedure TfrmForm1.actMyProcedureExecute(Sender: TObject);
var
MyForm2 : TfrmForm2;
begin
MyForm2 := TfrmForm2.Create(Self); //Getting error while executing this statement. I put a breakpoint on Create event of TForm2 form, but before that I am getting this error and breakpoint never comes on OnCreate event of TForm2 form.
end;
The error is raised during execution of the constructor of TfrmForm2. The error is raised before your OnCreate event is executed.
The most likely explanation therefore is that the exception is raised during creation and property setting of the controls specified in the dfm file.
Another possibility, I suppose, is that you have added a constructor for the class and code in there raises the exception. That I suspect is less likely.
Debug this by enabling debug DCUs and then looking at the call stack when the exception is raised. This should give you a pointer to which part of construction is failing. Once you've identified the point of failure you can then attempt to solve the problem.
Finally, in the absence of an MCVE in the question, this is the type of answer you can expect. Broad and general.
Related
This question already has answers here:
How to get current method's name in Delphi 7?
(3 answers)
How To Get the Name of the Current Procedure/Function in Delphi (As a String)
(6 answers)
Closed last year.
I'm creating an error report generator as part of a global exception handler. Right now I'm relying on the user to tell us what exactly they were doing when the exception happened.
I'm already adding the "exception.message" string to the report, but is there any way to grab the name of the procedure or the call stack "log" so I can add it to the report as well?
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I created an empty unit to store my public procedures and functions but I get access violation in the first line of a procedure, but this for the first time only I call this procedure, later calls work normally !!
The unit code:
unit myFunc;
interface
uses
Windows, Messages, SysUtils, System.UITypes, Variants, Classes, Graphics, Controls, Forms;
Procedure GSet(grid_form: TForm; app, operation: string);
implementation
Procedure GSet(grid_form: TForm; app, operation: string);
var
grd_idx: integer;
begin
if operation = 'save' then begin // Access violation in this line
if (grid_form.components[grd_idx] is TMyComponent) then
(grid_form.components[grd_idx] as TMyComponent).Storedata('c:\'+app);
end;
end;
Update:
I call this procedure from form create event like this
GridSettings(myform, 'cost', 'save');
From the code in the question, the most obvious mistake is that the variable grd_idx is not initialised. You must initialise variables before using them.
On top of that it is possible that you are passing an invalid object reference in the first parameter. We cannot tell from here. However, it is possible that you are passing a global variable that has not been initialised. It looks awfully like you should be passing Self rather than that global variable.
GridSettings(Self, 'cost', 'save');
Of course, I am assuming here that Self is what you intend to pass here. Since you did not supply very much code, we can only guess as to the details of your code.
You ask how to make the OnCreate event fire after all controls are created. Well, that is already the case. The OnCreate method is fired after the controls are created and their properties streamed in.
I would also comment that using strings to select discrete options is not a good idea. Use enumerated types for that.
I'm trying to figure out how to obtain a stack trace after an exception is thrown in Delphi. However, when I try to read the stack in the Application.OnException event using the function below, the stack already seems to be flushed and replaced by the throwing procedures.
function GetStackReport: AnsiString;
var
retaddr, walker: ^pointer;
begin
// ...
// History of stack, ignore esp frame
asm
mov walker, ebp
end;
// assume return address is present above ebp
while Cardinal(walker^) <> 0 do begin
retaddr := walker;
Inc(retaddr);
result := result + AddressInfo(Cardinal(retaddr^));
walker := walker^;
end;
end;
Here's what kind of results I'm getting:
001A63E3: TApplication.HandleException (Forms)
00129072: StdWndProc (Classes)
001A60B0: TApplication.ProcessMessage (Forms)
That's obviously not what I'm looking for, although it's correct. I'd like to retrieve the stack as it was just before the exception was thrown, or in other words the contents before (after would do too) the OnException call.
Is there any way to do that?
I am aware that I'm reinventing the wheel, because the folks over at madExcept/Eurekalog/jclDebug have already done this, but I'd like to know how it's done.
It is not possible to manually obtain a viable stack trace from inside the OnException event. As you have already noticed, the stack at the time of the error is already gone by the time that event is triggered. What you are looking for requires obtaining the stack trace at the time the exception is raised. Third-party exception loggers, like MadExcept, EurekaLog, etc handle those details for you by hooking into key functions and core exception handlers inside of the RTL itself.
In recent Delphi versions, the SysUtils.Exception class does have public StackTrace and StackInfo properties now, which would be useful in the OnException event except for the fact that Embarcadero has chosen NOT to implement those properties natively for unknown reasons. It requires third-party exception loggers to assign handlers to various callbacks exposed by the Exception class to generate stack trace data for the properties. But if you have JclDebug installed, for instance, then you could provide your own callback handlers in your own code that use JCL's stack tracing functions to generate the stack data for the properties.
I'd like to retrieve the stack as it was just before the
exception was thrown, or in other words the contents before
(after would do too) the OnException call.
Actually, you don't want the stack before the OnException call. That's what you've already got. You want the stack at the point at which the exception was raised. And that requires the stack tracing to happen ASAP after the raise. It's too late in the OnException call because the exception has propagated all the way to the top-level handler.
madExcept works by hooking all the RTL functions that handle exceptions. And it hooks the lowest level functions. This takes some serious effort to bring about. With these routines hooked the code can capture stack traces and so on. Note that the hooking is version specific and requires reverse engineering of the RTL.
What's more the stack walking is very much more advanced than your basic code. I don't mean that in a derogatory way, it's just that stack walking on x86 is a tricky business and the madExcept code is very well honed.
That's the basic idea. If you want to learn more then you can obtain the source code of JclDebug for free. Or buy madExcept and get its source.
In a Delphi 7 project we installed FastMM. Soon after that we noticed one of the forms started to issue Abstract Error message on close. I have debugged this extensively and I can't find the reason so far. The usual reason for this error message doesn't seem to apply here. The application doesn't define abstract classes. I also searched the form for a possible use of TStrings or something like that. Most importantly, we didn't (well, we think we didn't) make any changes to this form. It just broke.
Are there some other possible causes for this error besides trying to call unimplemented method?
Is there some possibilty that FastMM has enabled some obscure bug in the application, that remained hidden until now?
If the answer to these questions is no, then I'll just continue to search for an unimplemented method call, relieved that I am not missing something else.
If there is memory corruption then all sort of errors can be raised and it is very difficult to find the cause.
To answer your questions: 1) Yes abstract error can also be caused by memory corruption, and 2) Yes enabling FastMM can make bugs visible that normally pass unnoticed (but should still be fixed).
Some general advice for finding memory errors:
Try "FullDebugMode" setting in FastMM.
Make sure everything you Create is matched with a Free.
Make sure nothing is freed more than once.
Make sure an object is not used after it has been freed (or before it has been created).
Turn on hints and warnings (and fix them when they occur).
"It just broke" - it was probably always broke but now you know.
I have seen problems when closing a form as part of a button event. The form gets destroyed and then the remainder of the button messages get dispatched to a no-longer existing button. The Release method avoids this by (from memory) posting a wm_close message back to the form
Answer to question 1 "Are there some other possible causes for this error besides trying to call unimplemented method?"
Yes. This is what caused in my case an Abstract Error:
TWinControl(Sender).Visible:= FALSE;
This worked when sender was a TButton but raised the error (of course) when the sender was something else (like TAction). It was obviously my fault. I should have used "as" instead of a hard typecast.
Answer to question 2: Yes. I have seen that happening too. We should be very clear that this doesn't mean that FastMM is buggy. The bug was 'dormant'. FastMM only triggered it.
Actually you should rely on FastMM even more to find your issue. Switch FastMM to full debug mode for this. It will help you with:
Make sure an object is not used after it has been freed (or before it
has been created)
Also, in a few cases, the whole project was screwed up and I got the Abstract error. Nothing worked until I deleted the DPROJ file. Just do a compare between your current DPROJ file and the one in your back and you will see how the IDE f**** up the file.
You MUST also fix ALL warnings the compiler shows! The compiler is serious about that. It wouldn't raise an warning without a valid reason. Fix that and you will probably fix your problem.
In this particular case I would also replace all .Free with FreeAndNil().
You could try to add u_dzAbstractHandler to your project. It should raise the abstract error where the method was called, so it is easier to debug it. Of course this only helps when the error occurs when running in the debugger.
https://osdn.net/projects/dzlib-tools/scm/svn/blobs/head/dzlib/trunk/src/u_dzAbstractHandler.pas
Could be that one of your abstract functions/procedures in the base class is not implemented;
try this :
e.g
type
TBaseClass = class (TObject)
public
procedure DoSomething; virtual; abstract; //not implemented procedure
end;
type
TInheritedClass = class (TBaseClass)
public
procedure DoSomething; override;
end;
//Implementation
procedure TInheritedClass.DoSomething;
begin
//your code
end;
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
It happens to me quite often that I call a function Foo and want to know what exceptions this function might throw. In order to find out I then look into the implementation of Foo, but that is not enough. Foo might indeed call a function Bar that raises an exception.
Sometimes I even miss Java's checked exception handling.
So it is obivous to me that it is necessary to document the exceptions each function can throw: the question is: how? Are there any best practices on how to document exceptions? How do you handle this problem?
I think this covers some part of the problem you became aware of
Cleaner, more elegant and wrong
Cleaner, more elegant and harder to recognize
Most Delphi applications are VCL applications. They do not require a checked exception, because the main message loop has a try/except block catching everything.
It can be good practice to document which exceptions can be explicitly raised by your code though.
I'd use XMLDoc for that (there are various questions on XMLDoc her on SO, and here is some documentation from Embarcadero).
Note however that underlying code can also raise exceptions. Depending on the influence you have on libraries, you can or cannot assure those are always the same. A different thing is the OS: depending on where you run, you can get different exceptions.
--jeroen
We use Javadoc style comments for documentation. We extract the info and generate the output with some simple text scripts. We have used DelphiCodeToDoc, too.
Documenting exceptions, we have mandated to use the #throws tag.
this is looking great for documenting code - Documentation Insight from DevJet.net
I use XMLDoc comments. It's basically adding a specialized type of comment to your code in the interface section, just above the property or method declarations. Here's a nonsensical (of course) example. If you add similar style comments in your code, they'll pop up in Code Insight when you invoke it while writing code, just like the VCL's documentation does.
type
{$REGION 'TMyClass description'}
/// <summary>TMyClass is a descendent of TComponent
/// which performs some function.</summary>
{$ENDREGION}
TMyClass=class(TComponent)
private
// your private stuff
FSomeProp: Boolean;
procedure SetSomeProp(Value: Boolean);
protected
// your protected stuff
public
{$REGION 'TMyClass constructor'}
/// <summary> TMyClass constructor.</summary>
/// <remarks>Creates an instance of TMyClass.</remarks>
/// <param>Owner: TObject. The owner of the instance of TMyClass</param>
/// <exception>Raises EMyObjectFailedAlloc if the constructor dies
/// </exception>
{$ENDREGION}
constructor Create(Owner: TObject); override;
published
{$REGION 'TMyClass.Someprop'}
/// <summary>Someprop property</summary>
/// <remarks>Someprop is a Boolean property. When True, the
/// thingamajig automatically frobs the widget. Changing this
/// property also affects the behavior of SomeOtherProp.</remarks>
{$ENDREGION}
property Someprop: Boolean read FSomeProp write SetSomeProp;
end;
I prefer to wrap these XMLDoc comments in regions, so they can be collapsed out of the way unless I want to edit them. I've done so above; if you don't like them, remove the lines with {$REGION } and {$ENDREGION}
I use PasDoc for documenting almost all of my Delphi projects. It includes a "raises" tag which does what you seem to be asking for.
Regards
- turino