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

thread 'tokio-runtime-worker' has overflowed its stack #24325

Open
begoon opened this issue Jun 24, 2024 · 8 comments
Open

thread 'tokio-runtime-worker' has overflowed its stack #24325

begoon opened this issue Jun 24, 2024 · 8 comments
Labels
bug Something isn't working correctly cli related to cli/ dir high priority

Comments

@begoon
Copy link

begoon commented Jun 24, 2024

Version: Deno 1.44.4

I have a complex CLI application to generate PDF's with pdfkit and a few extra libraries.

After the latest Deno update:

deno --version
deno 1.44.4 (release, aarch64-apple-darwin)
v8 12.6.228.9
typescript 5.4.5

everything crashes no matter what with:

cd src/pdf && \
        deno run -A --watch \
        pdf-cli.ts
Watcher Process started.

thread 'tokio-runtime-worker' has overflowed its stack
fatal runtime error: stack overflow

I'm puzzled about how to raise a bug report because I don't know how to supply a simple, reproducible test case.

Also, when I run this project AS IS but with Bun, it works as expected, with no crashes.

Any advice?

I have also realised that in the dockerfile, there is a version of Deno which I didn't upgrade. The application DOES work with that version:

deno --version
deno 1.43.1 (release, aarch64-apple-darwin)
v8 12.4.254.12
typescript 5.4.3

I have downgraded my main CLI deno to 1.43.1, and... the crash is gone.

Something had been broken between 1.43.1 and 1.44.4.

@begoon
Copy link
Author

begoon commented Jun 24, 2024

I have bisected the releases and found that the last working release for me is 1.43.5.

In 1.43.6, the application starts crashing because of the error above.

@satyarohith satyarohith added bug Something isn't working correctly cli related to cli/ dir labels Jun 25, 2024
@yazan-abdalrahman
Copy link
Contributor

Hello, can you explain how I can re-produce this bug?

What's the script in pdf-cli.ts?
image

@begoon
Copy link
Author

begoon commented Jun 25, 2024

I have isolated the code causing the crash.

I have attached a single file, called crash.ts.

1.43.5 works okay with this file:

// deno upgrade --version 1.43.5
Downloading https://github.com/denoland/deno/releases/download/v1.43.5/deno-aarch64-apple-darwin.zip
Deno is upgrading to version 1.43.5
Archive:  /var/folders/yt/48q9hkh95x7fg1ps8sr95wd40000gn/T/.tmpV6kgiH/deno.zip
  inflating: deno                    
Upgraded successfully

// deno run -A src/pdf/crash.ts 

Warning Sloppy imports are not recommended and have a negative impact on performance.

1.43.6 crashes.

// deno upgrade --version 1.43.6
Downloading https://github.com/denoland/deno/releases/download/v1.43.6/deno-aarch64-apple-darwin.zip
Deno is upgrading to version 1.43.6
Archive:  /var/folders/yt/48q9hkh95x7fg1ps8sr95wd40000gn/T/.tmpi9CFkS/deno.zip
  inflating: deno                    
Upgraded successfully

// deno run -A src/pdf/crash.ts 
Warning Sloppy imports are not recommended and have a negative impact on performance.

thread 'tokio-runtime-worker' has overflowed its stack
fatal runtime error: stack overflow
zsh: abort      deno run -A src/pdf/crash.ts

crash.ts is attached.
crash.zip

@begoon
Copy link
Author

begoon commented Jun 25, 2024

I have checked on linux/amd64 too. The behaviour is the same. It crashes on 1.43.6, but 1.43.5 works.

deno --version
deno 1.43.6 (release, x86_64-unknown-linux-gnu)
v8 12.4.254.13
typescript 5.4.5

@yazan-abdalrahman
Copy link
Contributor

yazan-abdalrahman commented Jul 1, 2024

Hi @begoon, @dsherret, @bartlomieju

I've spent some time debugging the recent stack overflow issue we encountered while running our Deno script. After thorough investigation, I couldn't pinpoint any recursive asynchronous operations causing the problem. Instead, it appears that the issue stemmed from insufficient stack memory, exacerbated by recent updates in Deno's behavior complexity.

To address this, I explored increasing the stack memory allocation, which successfully resolved the issue on my WindowsPowerShell . Here's the command I used:

$env:RUST_MIN_STACK=9999999999 ;
this for increase stack size try to increase the stack size until it work

see example:
image

for linux the equivalent command for environments would be
export RUST_MIN_STACK=9999999999

@yazan-abdalrahman
Copy link
Contributor

Hi @begoon, @dsherret, @bartlomieju

I've spent some time debugging the recent stack overflow issue we encountered while running our Deno script. After thorough investigation, I couldn't pinpoint any recursive asynchronous operations causing the problem. Instead, it appears that the issue stemmed from insufficient stack memory, exacerbated by recent updates in Deno's behavior complexity.

To address this, I explored increasing the stack memory allocation, which successfully resolved the issue on my WindowsPowerShell . Here's the command I used:

$env:RUST_MIN_STACK=9999999999 ; this for increase stack size try to increase the stack size until it work

see example: image

for linux the equivalent command for environments would be export RUST_MIN_STACK=9999999999

and it worked when I tried it on Ubuntu without rust.

image

@yazan-abdalrahman
Copy link
Contributor

@lucacasonato

Hello, my conclusion is that the issue is a memory issue, so what should we do?
I believe we can add a flag to indicate the stack size of a thread, which would alleviate the issue if we didn't need to use env. RUST_MIN_STACK
but env. RUST_MIN_STACK it resolves the issue

image

@nathanwhit
Copy link
Member

Hello! I looked into this and the cause is an overflow in swc's resolver transform, you can see this from the backtrace:

Backtrace
frame #0: 0x00000001014023fc deno`OUTLINED_FUNCTION_6399 + 4
    frame #1: 0x000000010126977c deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_expr::h144833a51f384f9c + 28
    frame #2: 0x00000001012699a0 deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_expr::h144833a51f384f9c + 576
    <repeats for 3847 lines>
    frame #3849: 0x00000001012699a0 deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_expr::h144833a51f384f9c + 576
    frame #3850: 0x00000001012699a0 deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_expr::h144833a51f384f9c + 576
    frame #3851: 0x00000001012699a0 deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_expr::h144833a51f384f9c + 576
    frame #3852: 0x00000001012699a0 deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_expr::h144833a51f384f9c + 576
    frame #3853: 0x00000001012699a0 deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_expr::h144833a51f384f9c + 576
    frame #3854: 0x00000001012699a0 deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_expr::h144833a51f384f9c + 576
    frame #3855: 0x0000000101269dfc deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_object_lit::h0f7e263a305fac74 + 324
    frame #3856: 0x00000001012699f0 deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_expr::h144833a51f384f9c + 656
    frame #3857: 0x0000000101269dfc deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_object_lit::h0f7e263a305fac74 + 324
    frame #3858: 0x00000001012699f0 deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_expr::h144833a51f384f9c + 656
    frame #3859: 0x000000010126c870 deno`swc_ecma_visit::visit_mut_var_declarators::h4d727e26ae807b9a + 60
    frame #3860: 0x000000010126b12c deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_var_decl::h0015df53982443c0 + 40
    frame #3861: 0x000000010126b60c deno`swc_ecma_visit::visit_mut_module_items::hb666b1afac57ec7e + 536
    frame #3862: 0x000000010126b3c4 deno`_$LT$swc_ecma_transforms_base..resolver..Resolver$u20$as$u20$swc_ecma_visit..VisitMut$GT$::visit_mut_module_items::h65186121c5335ac6 + 356
    frame #3863: 0x000000010047b238 deno`_$LT$swc_ecma_visit..Folder$LT$V$GT$$u20$as$u20$swc_ecma_visit..Fold$GT$::fold_program::h21c53df4d6ee7c9e + 68
    frame #3864: 0x000000010047b5c4 deno`_$LT$swc_ecma_ast..module..Program$u20$as$u20$swc_ecma_visit..FoldWith$LT$V$GT$$GT$::fold_with::h8009075f52177431 + 856
    frame #3865: 0x0000000100496624 deno`deno_ast::transpiling::fold_program::h322f01473dc57f71 + 3224
    frame #3866: 0x00000001004df7b4 deno`deno_ast::transpiling::transpile::hfddfb5000f782f11 + 256
    frame #3867: 0x00000001004df268 deno`deno_ast::transpiling::_$LT$impl$u20$deno_ast..parsed_source..ParsedSource$GT$::transpile::h69e7bfb372b7563f + 340
    frame #3868: 0x00000001001fea60 deno`deno::emit::EmitParsedSourceHelper::transpile::hdd54dbbc6834d005 + 68
    frame #3869: 0x000000010010074c deno`tokio::runtime::task::raw::poll::hd4fa1a1a0119c459 + 160
    frame #3870: 0x00000001012e95c0 deno`std::sys_common::backtrace::__rust_begin_short_backtrace::h19cf7b946178ce3c + 400
    frame #3871: 0x00000001012e9304 deno`core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::ha9ce68b6d6219635 + 148
    frame #3872: 0x00000001011e1d3c deno`std::sys::pal::unix::thread::Thread::new::thread_start::h50a0ef5291b272f3 + 52
    frame #3873: 0x0000000182f7ef94 libsystem_pthread.dylib`_pthread_start + 136

The immediate cause (in your code) is the very large string concatenation

            "AAEAAAASAQAABAAgR0RFRrRCsIIAAir4AAACYkdQT1Or8IZpAAItXAAAZS5H" +
            "U1VCeoGFdwACkowAABWQT1MvMpl2sYAAAhh4AAAAYGNtYXDG7lFtAAId8AAA" +
            "BoJjdnQgBg4uPQACJ2gAAABaZnBnbYP7I6sAAiR0AAABvGdhc3AACAATAAIq" +
            "7AAAAAxnbHlm1d+kywAAASwAAfh4aGRteHmPiKEAAhjYAAAFGGhlYWT9R9JX" +
            "AAID5AAAADZoaGVhDUgS1wACGFQAAAAkaG10eN7XI9kAAgQcAAAUOGxvY2HG" +
            // <continues for ~3864 more lines

That effectively creates one big expression with thousands of subexpressions (each + creates a subexpression). When swc tries to visit this, it does one recursive function call per subexpression. Since there are so many subexpressions, that leads to a very deep call stack, which causes the stack overflow.


I'd recommend using escaped newlines or a template string instead of the string concatenation.

Escaped newlines (note the backslash at the end of each line, and the fact that the following line is not indented):

            "AAEAAAASAQAABAAgR0RFRrRCsIIAAhNYAAACYkdQT1Or8IZpAAIVvAAAZS5H\
U1VCeoGFdwACeuwAABWQT1MvMpl2sdgAAgEYAAAAYGNtYXDG7lFtAAIGkAAA\
BoJjdnQgBg0uPQACEAgAAABaZnBnbYP7I6sAAg0UAAABvGdhc3AACAATAAIT\
TAAAAAxnbHlmVocNBQAAASwAAeEYaGRteI6hoLIAAgF4AAAFGGhlYWT9DdJS\
// etc
ADAAmACbADEA0ADQADUAAQABAEoAAQADAEoAVwCV"

Or a template string, with a helper to strip out the newlines and leading whitespace

const stripIndent = (s: string) => s.split("\n").map((l) => l.trimStart()).join("");

// later

stripIndent( `AAEAAAASAQAABAAgR0RFRrRCsIIAAhNYAAACYkdQT1Or8IZpAAIVvAAAZS5H
            U1VCeoGFdwACeuwAABWQT1MvMpl2sdgAAgEYAAAAYGNtYXDG7lFtAAIGkAAA
            BoJjdnQgBg0uPQACEAgAAABaZnBnbYP7I6sAAg0UAAABvGdhc3AACAATAAIT
            TAAAAAxnbHlmVocNBQAAASwAAeEYaGRteI6hoLIAAgF4AAAFGGhlYWT9DdJS
            ADAAmACbADEA0ADQADUAAQABAEoAAQADAEoAVwCV`)
 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctly cli related to cli/ dir high priority
Projects
None yet
Development

No branches or pull requests

5 participants