Maximum Inheritance Level

I wrote the source file with 1000 classes inheriting from the above:

class Program { static void Main(string[] args) { Class700 class700 = new Class700(); } } class Class1 { public Class1() { } } class Class2 : Class1 { public Class2() { } } class Class3 : Class2 { public Class3() { } } class Class4 : Class3 { public Class4() { } } class Class5 : Class4 { public Class5() { } } //class ClassN : ClassN-1 { public ClassN() { } } where N = 2 to N = 1000 

I get a StackOverflow exception in Class700 , however this changes every time I run it, but usually it's around 700.

Can someone explain why at level 700, StackOverflow and why does it change every time I run the program?

I am using Windows 8.1 Enterprise 64 bit.

+5
source share
1 answer

Seeing that this is a 700 bomb, it’s hard to explain, but we certainly don’t look at the real code. You will only get something similar in the case of auto-generated code, of course, no one will ever write something like this manually.

But yes, SOE is certainly possible with such code. Invisible to the eye, but the constructor of the derived class always calls the constructor of its base class. If you do not write it yourself, then the compiler will automatically generate this call. All the way to the System.Object constructor.

How much stack space is required for the constructor is what you can see with the debugger. Just select the code for the two classes, create a Class2 object and set breakpoints for the Class2 and Class1 classes. You want the Debug + Windows + registers to write the value of the ESP register, the stack pointer, when they hit breakpoints. RSP in 64-bit mode.

By doing the same with your code snippet, I get 0x024C012C and 0x024C00E4, the difference is 72 bytes. By extrapolating this to 700 classes, this will require 700 x 72 = 50,400 bytes. Not close to SOE, your program is bombed when it consumes one megabyte in 32-bit code, 4 megabytes when compiled with a target platform forced to x64. Jitter has overhead, and a number you cannot guess until you subtract the difference.

You can increase the stack size using the Editbin.exe / STACK option. Or create a Thread, use a constructor that allows you to set the size of the stack.

And yes, this will not happen again well, this is normal. The CLR implements several methods of protection against malicious programs, one of which launches the stack in a random place. It is harmful for malware to use .NET code with a buffer overflow attack. This is a pretty unlikely threat to .NET code as a whole, and not to a lot of the code that stackalloc uses, but countermeasure is very cheap to implement.

+5
source

Source: https://habr.com/ru/post/1203063/


All Articles