Zulip Chat Archive
Stream: lean4
Topic: Segmentation Fault Splitting Files
Eric Paul (Aug 27 2024 at 21:04):
I am getting a segmentation fault when I split my code into two files.
It goes away when I put all the code into a single file.
Unfortunately I don't have a MWE or code to share, so I am just wondering if someone has experienced something similar before.
I'm not doing any FFI and have no dependencies.
Eric Paul (Aug 28 2024 at 00:11):
Actually it seems like many changes I make are causing segfaults.
Is there any general guidance for debugging this or typical suspects in Lean?
Chris Bailey (Aug 28 2024 at 01:10):
Your OS, lean version, editor info, and lean extension/plugin version would probably help.
Eric Paul (Aug 28 2024 at 01:14):
Good point, thanks for help!
Here's some information (I'm working on a mwe right now too).
OS: macOS Monterey Version 12.3
Lean version: Lean (version 4.10.0, x86_64-apple-darwin22.6.0, commit c375e19f6b65, Release)
Editor info: VS Code Version 1.92.2
Lean plugin version: v0.0.176
Julian Berman (Aug 28 2024 at 01:22):
Does it segfault even at the CLI?
Eric Paul (Aug 28 2024 at 01:24):
I'm not sure I know exactly what you mean, but this is when it happens:
I get a segfault when I run the following:
lake build; ./.lake/build/bin/test2
And get this output:
Build completed successfully.
zsh: segmentation fault ./.lake/build/bin/test2```
Julian Berman (Aug 28 2024 at 01:25):
OK -- so it happens when you run lake build
and then your executable?
Julian Berman (Aug 28 2024 at 01:26):
(If so the VSCode bits probably aren't relevant, which is what I was trying to eliminate)
Julian Berman (Aug 28 2024 at 01:26):
If you rm -rf .lake
and then lake build
, does it still segfault then?
Eric Paul (Aug 28 2024 at 01:33):
When I do that I still get a segfault.
Here's a MWE:
I type
lake new test
cd test
- Modify
Main.lean
to have the following contents
import Lean.Data
def update (_ : Nat × Nat) (_ : Array String) (w : Lean.HashMap (Nat × Nat) (Array String)) :=
w.insert (0,0) #[]
def test (x : String) (y : Lean.Xml.Element) (z : Lean.HashMap (Nat × Nat) (Array String)): Option (String × (Option String) × (Option String) × (Option String) × (Lean.HashMap (Nat × Nat) (Array String))) := do
let m : Lean.Xml.Element ←
(Array.filter
(fun _ => false)
(#[y]))[0]?
let a := ((toString m).split (· = '\n')).getD 0 ""
let b : Option String := none
let c : Option String := none
let d : Option String := do pure $ ""
pure $ (a, b, c, d, update (0, x.length) #["", s!"{x}"] z)
def main : IO Unit := do
IO.println "hi"
lake build
./.lake/build/bin/test
Chris Bailey (Aug 28 2024 at 02:11):
I get the same segfault on an intel mac on 4.10.0 and 4.11.0-rc2; it has something to do with the string interpolation (s!"{x}"
)
Chris Bailey (Aug 28 2024 at 02:13):
Ok it has to be an array of length > 1 and include the string interpolation.
Julian Berman (Aug 28 2024 at 02:13):
It's quite fragile.
Julian Berman (Aug 28 2024 at 02:13):
I've minimized to...
import Lean.Data
def update (_ : Nat × Nat) (_ : Array String) (w : Lean.HashMap (Nat × Nat) (Array String)) :=
w.insert (0,0) #[]
def test (x : String) (y : Lean.Xml.Element) (z : Lean.HashMap (Nat × Nat) (Array String)): Option (String × (Option String) × (Option String) × String × (Lean.HashMap (Nat × Nat) (Array String))) := do
pure $ (
((toString (← (Array.filter (fun _ => true) #[y])[0]?)).split (· = '0')).getD 0 "",
none,
"",
"",
update (x.length, x.length) #[s!"{x}", s!"{x}"] z
)
def main : IO Unit := pure ()
Julian Berman (Aug 28 2024 at 02:13):
The backtrace has gmp things in it. EDIT: maybe not.
Eric Paul (Aug 28 2024 at 02:14):
Yes, its fragility is what made me take so long in making a mwe. It seemed like every tiny change made a large difference.
Eric Paul (Aug 28 2024 at 02:15):
Thanks again for the interest and help!
This segfault has been destroying me
Chris Bailey (Aug 28 2024 at 02:16):
@Julian Berman Out of curiosity, what OS/lean version are you on
Julian Berman (Aug 28 2024 at 02:23):
Further:
import Lean.Data.HashMap
mutual
inductive Foo
| Foo (bar : Bar)
inductive Bar
| Foo (foo : Foo)
| Baz (baz : String)
end
mutual
def eToString : Foo → String
| Foo.Foo c => cToString c
def cToString : Bar → String
| Bar.Foo e => eToString e
| Bar.Baz c => c
end
instance : ToString Foo := ⟨eToString⟩
instance : ToString Bar := ⟨cToString⟩
def update (_ : Nat × Nat) (_ : Array String) (w : Lean.HashMap (Nat × Nat) (Array String)) :=
w.insert (0,0) #[]
def test (x : String) (y : Foo) (z : Lean.HashMap (Nat × Nat) (Array String)): Option (String × (Option String) × (Option String) × String × (Lean.HashMap (Nat × Nat) (Array String))) := do
pure $ (
((toString (← (Array.filter (fun _ => true) #[y])[0]?)).split (· = '0')).getD 0 "",
none,
"",
"",
update (x.length, x.length) #[s!"{x}", s!"{x}"] z
)
def main : IO Unit := pure ()
Julian Berman (Aug 28 2024 at 02:24):
@Chris Bailey Also macOS -- 14.6.1 (23G93) + lean 4.11.0-rc2
Julian Berman (Aug 28 2024 at 02:25):
@Eric Paul I suspect what any of us have (including what you started with) is probably good enough to file a bug on the lean4 tracker, they mostly care that it doesn't have Mathlib in it I think.
Eric Paul (Aug 28 2024 at 02:27):
Sounds good, I can file an issue
Eric Paul (Aug 28 2024 at 02:42):
Here's the issue https://github.com/leanprover/lean4/issues/5188
Henrik Böving (Aug 28 2024 at 07:54):
Debugged and workaround available at the issue.
Eric Paul (Aug 28 2024 at 13:45):
The fix works, my code is running once again!
Thank you so much for the quick inspection and fix
Last updated: May 02 2025 at 03:31 UTC