Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Violation Exception during access of field of Object

I'm encountering a realy strange behaviour when using Linq in my .Net Core 2.0, ASP.Net react project:

When accessing a field of an object which gets instantiated inside an Linq "Select" selector, it throws an "Access Violation Exception"

Steps to reproduce (hopefully):

  • Visual Studio 2017, 15.7.4
  • Create new ASP.Net Core 2.0 Project
  • Choose "React" template
  • alter the SampleDataController.cs as follows:

    [HttpGet("[action]")]
    
    public string Objects()
    {
        var rng = new Random();
        var ret = Enumerable.Range(1, 5).Select(index => 
            new TableDef("User")
                .AddField(new StringField("ID", Guid.NewGuid().ToString()))
                .AddField(new StringField("Name", "User " + index.ToString()))
        );
    
        return "[" +
                ret.Select(x => x.ToJSONString()).Aggregate((current, next) => current + ", " + next) +
            "]";
    }
    
  • With the following Classes:

    public class TableDef
    {
        public string ID { get; private set; } = Guid.NewGuid().ToString();
        public string LockedBy { get; private set; } = "";
        public string Name { get; private set; }
        public FieldDef[] Fields { get; private set; }
    
        public TableDef(string name)
        {
            Name = name;
            Fields = new FieldDef[0];
        }
    
        public TableDef AddField(FieldDef field)
        {
            field.Parent = this;
            var flds = this.Fields;
            Array.Resize(ref flds, flds.Length + 1);
            flds[flds.Length - 1] = field;
            this.Fields = flds;
            return this;
        }
    
        public string ToJSONString()
        {
            return @" { ""TableDef"": {"" 
                ""DefID"": """ + ID + @""", 
                ""DefName"": """ + Name + @""", 
                ""DefLockedBy"": """ + LockedBy + @"""}, " + 
                    Fields
                        .Select(x => ('"' + x.Name + @""" : """ + x.Value + '"'))
                        .Aggregate((current, next) => current + ", " + next) +
                "}";
        }
    }
    
    
    
    public abstract class FieldDef 
    {
        public string ID { get; protected set; } = Guid.NewGuid().ToString();
        public string Name { get; protected set; }
        public abstract string Value { get; set; }        
        public abstract string DefaultValue { get; set;  }
        public Boolean ReadOnly { get; protected set; } = false;
        public Boolean IsDirty { get; set; } = false;
        public TableDef Parent {
            get { return Parent; }
            set {
                this.Parent = value;
                ID = Parent.Name.Replace(" ", "") + "_" + Name.Replace(" ", "");
            }
        }
    }
    
    
    public class StringField : FieldDef
    {
        public override string Value {
            get { return (IsDirty) ? Value : DefaultValue; }
            set { this.Value = value; }
        }
        public override string DefaultValue { get; set; }
    
        public StringField(string name, string defaultValue)
        {
            Name = name;
            DefaultValue = defaultValue;
        }
    
        public StringField(string name, string defaultValue, Boolean readOnly)
        {
            Name = name;
            DefaultValue = defaultValue;
            ReadOnly = readOnly;
        }
    }
    

When running the code and clicking on the "fetch data" link, the application dies (at least in my case) completely without even an error in Visual studio. The debugging just ends, leaving me with the following debug output:

The program '[20584] dotnet.exe: Program Trace' has exited with code 0 (0x0).
The program '[20584] dotnet.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'.
The program '[20584] dotnet.exe: Managed (CoreCLR)' has exited with code -1 (0xffffffff).

When commenting the line field.Parent = this; in public TableDef AddField(FieldDef field) the code runs smoothly. What may be worth noting is, that the program dies, even though I put a Breakpoint on this line. As this takes 2 or 3 seconds, I managed to read some variables from the field in the "Auto" intermediate window in the debugger, and they look perfectly fine. As soon as i try to access the parent field, the application dies though.

I'm pretty sure it's some inheritance stuff falsly interpreted by myself.

Any help is much appreciated. Thanks.

like image 777
wolfjuli Avatar asked Mar 06 '23 20:03

wolfjuli


1 Answers

Ok, I found the problem. The access violation happens because of an stack overflow, which is in my opinion counter intuitive (which is why I'm posting it here)

How Stack over flow exception occurs when property sets value to Itself

As i have an implementation of the getter and setter, I can't use the Property as "field" anymore (opposing to the "default implentation" when just specifying { get; set; }

One need to use separate variable when implementing getters and setters:

private TableDef _parent;
public TableDef Parent {
    get { return _parent; }
    set {
        this._parent = value;
        ID = Parent.Name.Replace(" ", "") + "_" + Name.Replace(" ", "");
    }
} 

Imho it's counter intuitive, because the compiler can "create" such a code, but as programmer you can't.

like image 127
wolfjuli Avatar answered May 10 '23 19:05

wolfjuli