Skip to content

Evaluating a recursive function concurrently crashes the process #7284

Description

@philrz
$ super -version && super -c "
fn walk(n): (
  values {n}
  | values n <= 0 ? [] : [{a: n, b: n * 2, c: 'x', d: [n, n], e: {f: n}}, ...walk(n - 1)]
)
fork
( values walk(200) | unnest this )
( values walk(200) | unnest this )
( values walk(200) | unnest this )
( values walk(200) | unnest this )"

Version: v0.3.0-372-g217a042d8

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0xb5c1a68]

goroutine 23 [running]:
github.com/brimdata/super/runtime/vam/expr.(*UDF).Call(0x32ad71390140, {0x32ad7118e920, 0x1, 0x32ad70ca7b60?})
	/Users/phil/work/super/runtime/vam/expr/udf.go:43 +0x4c8
github.com/brimdata/super/vector.Apply(0x2, 0x32ad711bed88, {0x32ad7118e920, 0x1, 0x1})
	/Users/phil/work/super/vector/apply.go:62 +0x3e5
github.com/brimdata/super/runtime/vam/expr.(*Call).Eval(0x32ad70dae5a0, {0xd1b5e10, 0x32ad71191590})
	/Users/phil/work/super/runtime/vam/expr/eval.go:67 +0x19c
github.com/brimdata/super/runtime/vam/expr.(*ArrayExpr).Eval(0x32ad711914a0, {0xd1b5e10, 0x32ad71191590})
	/Users/phil/work/super/runtime/vam/expr/arrayexpr.go:41 +0x1c8
github.com/brimdata/super/runtime/vam/expr.(*conditional).eval(0x32ad70eea700, {0x32ad70da8640?, 0xd1b5b70?, 0x32ad70ca7aa0?})
	/Users/phil/work/super/runtime/vam/expr/conditional.go:48 +0x21f
github.com/brimdata/super/vector.Apply(0x2, 0x32ad711bf0b0, {0x32ad70da8640, 0x2, 0x2})
	/Users/phil/work/super/vector/apply.go:62 +0x3e5
github.com/brimdata/super/runtime/vam/expr.(*conditional).Eval(0x32ad70eea700, {0xd1b5e10, 0x32ad71191590})
	/Users/phil/work/super/runtime/vam/expr/conditional.go:28 +0x199
github.com/brimdata/super/runtime/vam/op.(*Values).Pull(0x32ad71191500, 0x0)
	/Users/phil/work/super/runtime/vam/op/values.go:34 +0x102
github.com/brimdata/super/runtime/vam/op.(*Subquery).bodyPull(0x32ad70c502d0)
	/Users/phil/work/super/runtime/vam/op/subquery.go:84 +0x27
github.com/brimdata/super/runtime/vam/op.(*Subquery).Eval(0x32ad70c502d0, {0xd1b5e10, 0x32ad70d9e6c0})
	/Users/phil/work/super/runtime/vam/op/subquery.go:78 +0x2a8
github.com/brimdata/super/runtime/vam/op.(*Subquery).Eval(0x32ad70ece750, {0xd1b5e10, 0x32ad70d9e6c0})
	/Users/phil/work/super/runtime/vam/op/subquery.go:66 +0x205
github.com/brimdata/super/runtime/vam/expr.(*UDF).Call(0x32ad70f4c7d0, {0x32ad70f47cb0, 0x1, 0x32ad70f8c150?})
	/Users/phil/work/super/runtime/vam/expr/udf.go:43 +0x4db
github.com/brimdata/super/vector.Apply(0x2, 0x32ad70e77638, {0x32ad70f47cb0, 0x1, 0x1})
	/Users/phil/work/super/vector/apply.go:62 +0x3e5
github.com/brimdata/super/runtime/vam/expr.(*Call).Eval(0x32ad70f4cd20, {0xd1b5e10, 0x32ad70d9e390})
	/Users/phil/work/super/runtime/vam/expr/eval.go:67 +0x19c
github.com/brimdata/super/runtime/vam/expr.(*ArrayExpr).Eval(0x32ad70bb81e0, {0xd1b5e10, 0x32ad70d9e390})
	/Users/phil/work/super/runtime/vam/expr/arrayexpr.go:41 +0x1c8
github.com/brimdata/super/runtime/vam/expr.(*conditional).eval(0x32ad7106b540, {0x32ad70f08e60?, 0xd1b5b70?, 0x32ad70f8c060?})
	/Users/phil/work/super/runtime/vam/expr/conditional.go:48 +0x21f
github.com/brimdata/super/vector.Apply(0x2, 0x32ad70e77960, {0x32ad70f08e60, 0x2, 0x2})
	/Users/phil/work/super/vector/apply.go:62 +0x3e5
github.com/brimdata/super/runtime/vam/expr.(*conditional).Eval(0x32ad7106b540, {0xd1b5e10, 0x32ad70d9e390})
	/Users/phil/work/super/runtime/vam/expr/conditional.go:28 +0x199
github.com/brimdata/super/runtime/vam/op.(*Values).Pull(0x32ad70bb8240, 0x0)
	/Users/phil/work/super/runtime/vam/op/values.go:34 +0x102
github.com/brimdata/super/runtime/vam/op.(*Subquery).bodyPull(0x32ad70ece750)
	/Users/phil/work/super/runtime/vam/op/subquery.go:84 +0x27
github.com/brimdata/super/runtime/vam/op.(*Subquery).Eval(0x32ad70ece750, {0xd1b5e10, 0x32ad70d9e270})
	/Users/phil/work/super/runtime/vam/op/subquery.go:78 +0x2a8
github.com/brimdata/super/runtime/vam/expr.(*UDF).Call(0x32ad70f4c7d0, {0x32ad709f8350, 0x1, 0x32ad70f8c018?})
	/Users/phil/work/super/runtime/vam/expr/udf.go:43 +0x4db
github.com/brimdata/super/vector.Apply(0x2, 0x32ad70d18dc0, {0x32ad709f8350, 0x1, 0x1})
	/Users/phil/work/super/vector/apply.go:62 +0x3e5
github.com/brimdata/super/runtime/vam/expr.(*Call).Eval(0x32ad70f4ceb0, {0xd1b5da0, 0x32ad70f2e400})
	/Users/phil/work/super/runtime/vam/expr/eval.go:67 +0x19c
github.com/brimdata/super/runtime/vam/op.(*Values).Pull(0x32ad70bb8450, 0x0)
	/Users/phil/work/super/runtime/vam/op/values.go:34 +0x102
github.com/brimdata/super/runtime/vam/op.(*Unnest).Pull(0x32ad70bb84b0, 0x0)
	/Users/phil/work/super/runtime/vam/op/unnest.go:30 +0x35
github.com/brimdata/super/runtime/vam/op.(*combineParent).run(0x32ad70eeac00)
	/Users/phil/work/super/runtime/vam/op/combine.go:109 +0x3c
created by github.com/brimdata/super/runtime/vam/op.(*Combine).Pull.func1 in goroutine 1
	/Users/phil/work/super/runtime/vam/op/combine.go:42 +0x35
panic: runtime error: invalid memory address or nil pointer dereference

Details

Repro is with super commit 217a042.

This crash was uncovered while helping an advisor with prototyping their "paged API" use case. They'd already created a recursive function that was working to their satisfaction, but then wanted to invoke it in parallel branches of a fork. If for some reason that wasn't possible, they expressed intent to do it with join instead, but it turns out this problem affects queries that have parallelism in general: fork, join, switch, and SQL UNION ALL. As I learned, it's not limited to queries that ask for parallelism, since the optimizer introduces it on its own, so a plain linear pipeline like this one crashes too:

$ seq 500 | awk '{print "{k:" $1%7 "}"}' |
  super -s -c "
fn walk(n): (
  values {n}
  | values n <= 0 ? [] : [{a: n, b: n*2, c: 'x'}, ...walk(n - 1)]
)
where k == 3 | values walk(20) | unnest this | count()" -

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x83b5a68]

goroutine 61 [running]:
github.com/brimdata/super/runtime/vam/expr.(*UDF).Call(0x72095deec30, {0x72095c7baf0, 0x1, 0x72095f17cb0?})
	/Users/phil/work/super/runtime/vam/expr/udf.go:43 +0x4c8
...

I used Claude to help create the simplified repro, and as it was doing that it uncovered what it believes are two races that contribute to this crash and other insights into possible fixes, so I've made its full write-up available in a Gist.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions