Tensegritics / ClojureDart

Clojure dialect for Flutter and Dart
1.38k stars 88 forks source link

Printing cyclic data structure causes stack overlow #297

Closed kennytilton closed 7 months ago

kennytilton commented 7 months ago

Bug description Printing cyclic data structure causes stack overflow, with prn, println, or dart:core/print.

Does your problem persist after clj -M:cljd clean && flutter clean?

Yes.

Steps to reproduce the behavior: Run:

    (let [a (atom nil)
            b (atom {:me :b
                           :a a})]
       (reset! a {:me :a :b b})
       (println :a a @a :b @b))```

```Launching flutter run
Launching lib/main.dart on iPhone 14 Pro Max in debug mode...
Running pod install...                                           1,287ms
Upgrading Pods-Runner.release.xcconfig
Upgrading Pods-Runner.profile.xcconfig
Upgrading Pods-Runner.debug.xcconfig
Running Xcode build...                                          
Xcode build done.                                           39.7s
[ERROR:flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.mm(42)] Using the Impeller rendering backend.
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Stack Overflow
#0      new _List.filled (dart:core-patch/array.dart:96:3)
#1      aresize (package:matrix/cljd-out/cljd/core.dart:19397:47)
#2      BitmapNode.inode_assoc_transient (package:matrix/cljd-out/cljd/core.dart:4975:15)
#3      TransientHashMap.$_assoc$BANG_$2 (package:matrix/cljd-out/cljd/core.dart:16613:12)
#4      $_map_lit (package:matrix/cljd-out/cljd/core.dart:4022:62)
#5      Atom.$_print$1 (package:matrix/cljd-out/cljd/core.dart:4454:36)
#6      print_map.<anonymous closure> (package:matrix/cljd-out/cljd/core.dart:35299:38)

Expected behavior The print output should appear in the console without a stack overflow, down to a certain limited level, after which an ellipsis is rendered to indicate the truncation.

Additional context This is a longstanding issue, not a regression.

Something else your template might ask about: I just upgraded my project to the latest CLJD SHA.

kennytilton commented 7 months ago

The solution CL uses is to have a print-level dyno bound by default to some low level, and to track print "depth" each time a reference is followed recursively.