Recent

Author Topic: Access Violation in TATransformations  (Read 1246 times)

PaulRowntree

  • Jr. Member
  • **
  • Posts: 73
    • Paul Rowntree
Access Violation in TATransformations
« on: November 15, 2019, 08:55:42 pm »
I just added a second Y axis to a Chart in a stable application, and it immediately threw an 'Access Violation' in TAutoScaleAxisTransformation.ClearBounds
Code: Pascal  [Select]
  1. procedure TAutoScaleAxisTransform.ClearBounds;
  2. begin
  3.   inherited ClearBounds;
  4.   with TAutoScaleTransformData(FDrawData) do begin
  5.     FMin := SafeInfinity;  *************************** fault is here
  6.     FMax := NegInfinity;
  7.     FOffset := 0.0;
  8.     FScale := 1.0;
  9.   end;
  10. end;      
from TAMath
Code: Pascal  [Select]
  1. function SafeInfinity: Double;
  2. begin
  3.   {$PUSH}{$R-}{$Q-}
  4.   Result := Infinity;   **************************************
  5.   {$POP}
  6. end;
  7.  
And finally, Math.Infinity is a const
Code: Pascal  [Select]
  1.     const
  2.        EqualsValue = 0;
  3.        LessThanValue = Low(TValueRelationship);
  4.        GreaterThanValue = High(TValueRelationship);
  5. {$push}
  6. {$R-}
  7. {$Q-}
  8.        NaN = 0.0/0.0;
  9.        Infinity = 1.0/0.0;  *******************************************
  10.        NegInfinity = -1.0/0.0;
  11. {$pop}
  12.            
       
This seems like odd code, and the executable certainly has issues.  If I accept the error, the program seems to continue correctly.
Is there something wrong in the underlying TAChart code?  Why is the infinity constant written in such a way?Thanks!This is on Win7, Laz v 1.8.4;  fpc 3.04
« Last Edit: November 15, 2019, 09:00:03 pm by PaulRowntree »
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

wp

  • Hero Member
  • *****
  • Posts: 6471
Re: Access Violation in TATransformations
« Reply #1 on: November 15, 2019, 10:13:34 pm »
What exactly are you doing? Just adding a second y axis does not require an AutoScaleAxisTransformation. So you must be doing more than "I just added a second Y axis to a chart". Please give exact steps so that I can reproduce. But I doubt that this is an error of TAChart. Multiple Y axes are used without this issue in numerous applications.

Why is the infinity constant written in such a way?
https://forum.lazarus.freepascal.org/index.php/topic,18970.msg107877.html#msg107877
« Last Edit: November 15, 2019, 11:01:14 pm by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

PaulRowntree

  • Jr. Member
  • **
  • Posts: 73
    • Paul Rowntree
Re: Access Violation in TATransformations
« Reply #2 on: November 15, 2019, 11:49:06 pm »
 I was following the instructions on the wiki : https://wiki.freepascal.org/TAChart_Tutorial:_Dual_y_axis,_Legend#Setting_up_a_second_y_axis
Did the basic addition of the second axis, and it did not show independent scales, exactly as predicted by the wiki page.  Moved on to the next step ...

I was "Setting up auto-scale axis transformations", and had not yet done the "Cleaning up" step to make the grid lines look right.  Code compiled correctly, gave access fault on execution.  Recompiled with debugging enabled to find the offending line.

So the steps followed were those on the wiki. 

It seems odd to use "1.0/0.0" to determine the largest double, hence my questions.Cheers!
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

PaulRowntree

  • Jr. Member
  • **
  • Posts: 73
    • Paul Rowntree
Re: Access Violation in TATransformations
« Reply #3 on: November 16, 2019, 08:31:43 am »
The error is caused by the FDrawData object not being assigned prior to the call to ClearBounds during code initialization.  The first assignment within the with statement triggers the access violation.  I am probably triggering a chart refresh before everything is fully configured down in the depths, and there is no data in the various Series.  The wiki tutorial populates the Series in FormCreate, avoiding the issue (I guess). 
However, ClearBounds is called from the owner TChartAxisTransformations class, not by my code, and there doesn't seem to be any checks on the pointers involved.
Q : Why wouldn't the FDrawData class be created in Create?

Adding the assign( FDrawData ) hack-fixes the access violation.
Code: Pascal  [Select]
  1. procedure TAutoScaleAxisTransform.ClearBounds;
  2. begin
  3.   inherited ClearBounds;
  4.   if not assigned( FDrawData ) then exit;      *****************
  5.  
  6.   with TAutoScaleTransformData(FDrawData) do begin
  7.  
  8.     FMax := NegInfinity;
  9.     FOffset := 0.0;
  10.     FMin := SafeInfinity;
  11.     FScale := 1.0;
  12.   end;
  13. end;
  14.  
  15.  
« Last Edit: November 16, 2019, 09:09:36 am by PaulRowntree »
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

wp

  • Hero Member
  • *****
  • Posts: 6471
Re: Access Violation in TATransformations
« Reply #4 on: November 16, 2019, 11:06:31 am »
Still, I cannot reproduce this. Please give EXACT step-by-step instructions (*), or upload a project in which the issue occurs such that I do not have to do anything but compile and run. I really want to fix this, but please understand that I will not modify code for reasons which I cannot reproduce.

In your first post you mention Laz 1.8.4. This is fairly old. Do you have the same issue with the current version? (However, I cannot reproduce it with 1.8.4 either). Make a secondary installation - this leaves your 1.8.4 untouched.

(*) I don't believe that the steps mentioned in reply #2 are exact because you don't have a data file, and you cannot download it because the url to the originator site seems to be invalid since some time.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

PaulRowntree

  • Jr. Member
  • **
  • Posts: 73
    • Paul Rowntree
Re: Access Violation in TATransformations
« Reply #5 on: November 16, 2019, 06:41:38 pm »
Hi wpThanks for keeping with me on this; I can appreciate how tough this is.  I erased one post that I made prior to finding the FDrawItem pointer.  In that post I wrote that I could not reproduce it on a clean project that just created some data in TLineSeries with a dual Y axis as per the tutorial, so I assume I am triggering this in my code somehow.  Then I started re-ordering the assignments inside the ClearBounds routine, and the first assignment always triggered the access fault (but only in my big application).  Then I saw that FDrawItem wasn't assigned just before the AV.Also in that post : the IDE registers an AV when I load the project.  I have not rebuilt the IDE with the modified ClearBounds code.

The steps for my clean program (that always works with 2 Y axes) and my big app were similar

1) I used 2 TLineSeries that are created in the IDE for the Chart, the data is assigned via AddXY().  In the test code this takes place in FormCreate, in the big app it hasn't happened yet.  In the big app the TLineSeries data is frequently Cleared and restocked as new data arrives.
2) In the big app FormCreate I trigger a rebuild of the Chart contents, which does the Clear/restock.  This is just eye candy to make the Chart look ready to go ... no data is present.  I still get the AV after commenting out the rebuild.

The modification to 2 axes in both cases was
a) add another Y axis, Alignment as calRight, set the AxisIndexY for the second LineSeries to be 2 for the new Y axis.
b) test : program runs, but the two axes are the same range, as predicted by tutorial.
c) Drop 2 TChartAxisTransform onto the chart, renamed to LeftAxisTransform & RightAxisTransform.  Opened the editor for each, and added a AutoScale element, which were then renamed to LeftAutoscaleTransform and RightAutoscaleTransform
Compile & runs correctly, but the axes remain on same range.  If I save, exit, rerun IDE there is no AV triggered during load.
d) Assigned the LeftAxisTransform and RightAxisTransforms to the Transformations property of the original and new Y axes with Chart.
Compiles fine, but triggers the AV.  Back in the IDE FDrawData is NIL. 

From what I can see, FDrawData is only assigned in the call to the base class TAxisTransform.SetChart().

Code: Pascal  [Select]
  1. procedure TAxisTransform.SetChart(AChart: TObject);
  2. begin
  3.   if GetDrawDataClass = nil then exit;
  4.   FDrawData := DrawData.Find(AChart, Self);
  5.   if FDrawData <> nil then exit;
  6.   FDrawData := GetDrawDataClass.Create(AChart, Self);
  7.   DrawData.Add(FDrawData);
  8. end;    

Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

wp

  • Hero Member
  • *****
  • Posts: 6471
Re: Access Violation in TATransformations
« Reply #6 on: November 16, 2019, 07:17:20 pm »
The steps (a)-(d) are exactly the same what I am doing...

Do I understand you correctly that this only happens in your big program? If yes, we have a problem because the problem is in your code (and I am not particularly fond of debugging "big" programs of other people ;)).

BTW, as I saw that the link to the data file in the tutorial project is not working any more I uploaded the two projects of the tutorials https://wiki.lazarus.freepascal.org/TAChart_Tutorial:_Userdefined_ChartSource and https://wiki.lazarus.freepascal.org/TAChart_Tutorial:_Dual_y_axis,_Legend to the folders "population1" and "population2", respectively, of "components/tachart/tutorials" of the trunk Lazarus installation, along with the data file that I had used for writing the tutorials. If you don't use trunk you can download the few files individually from https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/components/tachart/tutorials/population2/?root=lazarus&sortby=file#dirlist

Of course, I could insert the line "if not assigned( FDrawData ) then exit;" into TAutoscaleAxisTransform.ClearBounds. It certainly is not harmful, but the necessity for it might be caused by another bug somewhere else, and I would like to remove this bug first.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

PaulRowntree

  • Jr. Member
  • **
  • Posts: 73
    • Paul Rowntree
Re: Access Violation in TATransformations
« Reply #7 on: November 16, 2019, 07:51:20 pm »
Yes, unfortunately, only the big program.  And all that implies.
I have commented out everything in my main FormCreate that triggers a rebuild of the Chart, and the AV persists.  It doesn't seem to be my code then that is triggering the fault (I'll bet you have never heard that before ), and I wonder if there is something else in the Transformations linkage to the Axis or Chart that is causing this.  Prefilling some data into the LineSeries in FormCreate doesn't help, and the code seems to complete FormCreate without incident.
This may be irrelevant, but the AxisTransformation objects appear in the managed code section oddly.  They are inserted near the top of the list, and they add spaces after the entry.  Could this be a sign of an oddity?  It behaves the same way when I comment out the space.

Code: Pascal  [Select]
  1.   TForm1 = class(TForm)
  2.     AddTimeStampNotes_ctl: TButton;
  3.     LeftAxisTransformations: TChartAxisTransformations;
  4.     LeftAxisAutoScaleTransform: TAutoScaleAxisTransform;
  5.     RightAxisTransformations: TChartAxisTransformations;
  6.  
  7.     PlotPresetsCtl: TComboBox;
  8.     GroupBox4: TGroupBox;
  9.     ProposedEstFactors_series: TLineSeries;
  10.     ProposedEstimatorFactors_Ctl: TValueListEditor;
  11.     EstimatorData_series: TLineSeries;
  12.     IncomingDataHandler_ctl: TComboBox;
  13.     FakeDataCtl: TButton;
  14.     ClearEstimatorCtl: TButton;
  15.     GreenSeries: TLineSeries;
  16.     CustomGreenCtl: TComboBox;
  17.     GraphStatisticsCtl: TButton;
  18.     EstimatorChart: TChart;
  19.     InstalledEstFactors_Series: TLineSeries;
  20.     EGunMode_lbl: TLabel;
  21.     Label1: TLabel;
  22.     Label2: TLabel;
  23.     Label23: TLabel;
  24.     GraphOriginIndexCtl: TFloatSpinEdit;
  25.     GraphOriginNowCtl: TButton;
  26.     GraphSetOriginCtl: TButton;
  27.     RightAxisAutoScaleTransform: TAutoScaleAxisTransform;
  28.  
  29.     Timebase_gb: TRadioGroup;
  30.     TimeAtStandbyAction: TAction;
  31.     BiasAction: TAction;
  32.  
« Last Edit: November 16, 2019, 08:35:36 pm by PaulRowntree »
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

wp

  • Hero Member
  • *****
  • Posts: 6471
Re: Access Violation in TATransformations
« Reply #8 on: November 16, 2019, 08:04:57 pm »
I think you must strip down your big application to something manageable by me which you can upload here. Replace your real data by dummy data: a math function, or just "random" - this automatically removes file reading, data calculation etc. Remove all unnecessary configurations and forms. Keep the eyes open when you do this because when suddenly the program behaves normally you removed the buggy part! Usually when I do this for my own applications I find the bug myself.

This may be irrelevant, but the AxisTransformation objects appear in the managed code section oddly.  They are inserted near the top of the list, and they add spaces after the entry.  Could this be a sign of an oddity?  It behaves the same way when I comment out the space.
It does not occur for me. Does it happen also when you re-open the IDE and insert another transformation for a test? Maybe the IDE has a "hick-up" from some other issue.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

PaulRowntree

  • Jr. Member
  • **
  • Posts: 73
    • Paul Rowntree
Re: Access Violation in TATransformations
« Reply #9 on: November 16, 2019, 09:29:59 pm »
OK, will try.  It doesn't seem to matter if it is left or right side, and setting Autoscale.Enabled to false prevents the AV.  But will do as you suggest and keep stripping, and report back if I find it.

Thanks wp!
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

PaulRowntree

  • Jr. Member
  • **
  • Posts: 73
    • Paul Rowntree
Re: Access Violation in TATransformations
« Reply #10 on: November 16, 2019, 10:44:27 pm »
OK, it is due to a TChartNavPanel that is linked to the Chart.  Break the link (ChartNavPanel.Chart set to (none) ) there are no AV errors, and the one axis autoscales independently of the other according to the linked LineSeries.

Progress.
« Last Edit: November 16, 2019, 10:51:35 pm by PaulRowntree »
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

wp

  • Hero Member
  • *****
  • Posts: 6471
Re: Access Violation in TATransformations
« Reply #11 on: November 16, 2019, 11:47:30 pm »
Ah, thanks - that was the missing piece. Now I can reproduce the issue and have something to investigate.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

PaulRowntree

  • Jr. Member
  • **
  • Posts: 73
    • Paul Rowntree
Re: Access Violation in TATransformations
« Reply #12 on: November 17, 2019, 12:04:55 am »
Excellent.  Thanks wp for your persistence ... it is ok to go to crazytown, as long as you have company on the trip.
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

wp

  • Hero Member
  • *****
  • Posts: 6471
Re: Access Violation in TATransformations
« Reply #13 on: November 17, 2019, 12:36:41 pm »
I applied your fix from response #3 finally (r62255). Another solution would have been to call Prepare in TChart.Loaded but your fix certainly is not harmful while calling Prepare could have side-effects.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

PaulRowntree

  • Jr. Member
  • **
  • Posts: 73
    • Paul Rowntree
Re: Access Violation in TATransformations
« Reply #14 on: November 17, 2019, 08:23:25 pm »
Thanks wp!  That is easiest to implement here as a patch as well.
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems