Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't crash when printing a recursive structure #2882

Closed

Conversation

thexa4
Copy link
Contributor

@thexa4 thexa4 commented Feb 24, 2021

Fixes #1598

local foo to lexicon().
set foo["self"] to foo.

print foo.

Will now print "...recurse..." for the self value instead of crashing KSP. Other serializers will end with an exception instead of a crash.

@Dunbaratu
Copy link
Member

@thexa4 I just tested this and still got the stack overflow with this example program:

local aaa is list(1,2,3).
local bbb is list(100,200,aaa,400).
aaa:add(bbb). // this causes recursion since bbb contains aaa at position [2].
print "does this crash?".
print aaa.
print "it never gets here.".

That crashed KSP instantly, with this:

StackOverflowException: The requested operation caused a stack overflow.
  at (wrapper managed-to-native) System.Object.__icall_wrapper_ves_icall_object_new_specific(intptr)
  at kOS.Safe.Serialization.SafeSerializationMgr.Dump (kOS.Safe.Serialization.IDumper dumper, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) [0x00015] in <284f6740e8dd46a481f1ab5fe385b64a>:0 
  at kOS.Safe.Serialization.SafeSerializationMgr.DumpValue (System.Object value, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) [0x00068] in <284f6740e8dd46a481f1ab5fe385b64a>:0 
  at kOS.Safe.Serialization.SafeSerializationMgr+<>c__DisplayClass7_0.<DumpValue>b__0 (System.Object v) [0x00000] in <284f6740e8dd46a481f1ab5fe385b64a>:0 
  at System.Linq.Enumerable+SelectListIterator`2[TSource,TResult].ToList () [0x0002a] in <fbb5ed17eb6e46c680000f8910ebb50c>:0 
  at System.Linq.Enumerable.ToList[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x0001f] in <fbb5ed17eb6e46c680000f8910ebb50c>:0 
  at kOS.Safe.Serialization.SafeSerializationMgr.DumpValue (System.Object value, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) [0x000b7] in <284f6740e8dd46a481f1ab5fe385b64a>:0 
  at kOS.Safe.Serialization.SafeSerializationMgr.Dump (kOS.Safe.Serialization.IDumper dumper, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) [0x00061] in <284f6740e8dd46a481f1ab5fe385b64a>:0 

[ ... Here I truncated the output.  Because it recurses, this repeated a long time. ...]

@thexa4
Copy link
Contributor Author

thexa4 commented Mar 10, 2021

Ah, sorry, it seems I only tested the single depth recursion. Will fix.

@thexa4
Copy link
Contributor Author

thexa4 commented Mar 27, 2021

While looking at #2894 I noticed that this incorrectly marks all strings as recursive. Fix is in progress.

@mlheur
Copy link
Contributor

mlheur commented Apr 11, 2021

I'm trying to test the PR, see if it resolves my issue. It does not.
What I've done:

  1. uninstall kOS from my game data.
  2. download KOS-bugfix-infinite-recursion-crash.zip from thexa4's fork.
  3. extract that.
  4. copy [C:\Games\KSP 1.11.1\KSP_x64_Data\Managed\*.*] to [...\KOS-bugfix-infinite-recursion-crash\Resources\].
  5. open [...\KOS-bugfix-infinite-recursion-crash\src\kOS.sln] in VS2019 Community Edition.
  6. rebuild solution Ctrl-Alt-F7. Fifteen warnings, mostly "somevar isn't used".
  7. Check date modified is now for [...\KOS-bugfix-infinite-recursion-crash\Resources\GameData\kOS\Plugins\kOS*.dll].
  8. copy [...\KOS-bugfix-infinite-recursion-crash\Resources\GameData\*] to [C:\Games\KSP 1.11.1\GameData\].
  9. Open KSP, launch ship, run code listed in my post self-bound delegates CTD. #2918. With the wait removed, CTD on calling print the_object.
[EXC 12:11:28.756] StackOverflowException: The requested operation caused a stack overflow.
	kOS.Safe.Encapsulation.StringValue.Dump () (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.Dump (kOS.Safe.Serialization.IDumper dumper, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.DumpValue (System.Object value, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr+<>c__DisplayClass7_1.<DumpValue>b__0 (System.Object v) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	System.Linq.Enumerable+SelectListIterator`2[TSource,TResult].ToList () (at <fbb5ed17eb6e46c680000f8910ebb50c>:0)
	System.Linq.Enumerable.ToList[TSource] (System.Collections.Generic.IEnumerable`1[T] source) (at <fbb5ed17eb6e46c680000f8910ebb50c>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.DumpValue (System.Object value, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.Dump (kOS.Safe.Serialization.IDumper dumper, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.Serialize (kOS.Safe.Serialization.IDumper serialized, kOS.Safe.Serialization.IFormatWriter formatter, System.Boolean includeType, System.Boolean allowTruncatedRecursion) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.ToString (kOS.Safe.Serialization.IDumper dumper) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Encapsulation.Lexicon.ToString () (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Encapsulation.KOSDelegate.ToString () (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Encapsulation.UserDelegate.ToString () (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.DumpValue (System.Object value, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr+<>c__DisplayClass7_1.<DumpValue>b__0 (System.Object v) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	System.Linq.Enumerable+SelectListIterator`2[TSource,TResult].ToList () (at <fbb5ed17eb6e46c680000f8910ebb50c>:0)
	System.Linq.Enumerable.ToList[TSource] (System.Collections.Generic.IEnumerable`1[T] source) (at <fbb5ed17eb6e46c680000f8910ebb50c>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.DumpValue (System.Object value, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.Dump (kOS.Safe.Serialization.IDumper dumper, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.Serialize (kOS.Safe.Serialization.IDumper serialized, kOS.Safe.Serialization.IFormatWriter formatter, System.Boolean includeType, System.Boolean allowTruncatedRecursion) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.ToString (kOS.Safe.Serialization.IDumper dumper) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Encapsulation.Lexicon.ToString () (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Encapsulation.KOSDelegate.ToString () (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Encapsulation.UserDelegate.ToString () (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.DumpValue (System.Object value, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr+<>c__DisplayClass7_1.<DumpValue>b__0 (System.Object v) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	System.Linq.Enumerable+SelectListIterator`2[TSource,TResult].ToList () (at <fbb5ed17eb6e46c680000f8910ebb50c>:0)
	System.Linq.Enumerable.ToList[TSource] (System.Collections.Generic.IEnumerable`1[T] source) (at <fbb5ed17eb6e46c680000f8910ebb50c>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.DumpValue (System.Object value, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.Dump (kOS.Safe.Serialization.IDumper dumper, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.Serialize (kOS.Safe.Serialization.IDumper serialized, kOS.Safe.Serialization.IFormatWriter formatter, System.Boolean includeType, System.Boolean allowTruncatedRecursion) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.ToString (kOS.Safe.Serialization.IDumper dumper) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Encapsulation.Lexicon.ToString () (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Encapsulation.KOSDelegate.ToString () (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Encapsulation.UserDelegate.ToString () (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.DumpValue (System.Object value, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr+<>c__DisplayClass7_1.<DumpValue>b__0 (System.Object v) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	System.Linq.Enumerable+SelectListIterator`2[TSource,TResult].ToList () (at <fbb5ed17eb6e46c680000f8910ebb50c>:0)
	System.Linq.Enumerable.ToList[TSource] (System.Collections.Generic.IEnumerable`1[T] source) (at <fbb5ed17eb6e46c680000f8910ebb50c>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.DumpValue (System.Object value, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.Dump (kOS.Safe.Serialization.IDumper dumper, System.Boolean includeType, System.Boolean allowTruncatedRecursion, System.Collections.Generic.List`1[T] seenList) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.Serialize (kOS.Safe.Serialization.IDumper serialized, kOS.Safe.Serialization.IFormatWriter formatter, System.Boolean includeType, System.Boolean allowTruncatedRecursion) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)
	kOS.Safe.Serialization.SafeSerializationMgr.ToString (kOS.Safe.Serialization.IDumper dumper) (at <1c1a8b3318a64b7787b45fc960c254ee>:0)

@thexa4
Copy link
Contributor Author

thexa4 commented Apr 11, 2021

Thanks for testing it, I'll try to reproduce and fix it somewhere this week / next weekend.

@mlheur
Copy link
Contributor

mlheur commented Apr 12, 2021

Thank you for working on the patch. I looked at the diff, that's pretty much what I would've tried but have no experience with C#. With the insight I've gained from you I was able to make my code work, after eliminating all attempts to print and run haskey on my 'object'. Thanks again and let me know if there's more I can do to help.

@thexa4
Copy link
Contributor Author

thexa4 commented Jul 20, 2021

Closed in favor of #2910

@thexa4 thexa4 closed this Jul 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Printing self referencing lexicon crashes KSP
3 participants