JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
44.97k stars 5.43k forks source link

Stackoverflow without stacktrace when `convert`ing large tuple #54570

Open Seelengrab opened 1 month ago

Seelengrab commented 1 month ago

MWE, since at least 1.8.5 (reproduces on master):

   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.8.5 (2023-01-08)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> t = Tuple(zeros(Int32, 1024*1024*4));

julia> sizeof(t)
16777216

julia> convert(NTuple{1024*1024*4,UInt32}, t);
ERROR: StackOverflowError:
Stacktrace:
 [1] top-level scope
   @ REPL[2]:1

julia> 

As observed here.

mkitti commented 1 month ago

On 1.10.0, this just segfaults for me. I will update later.


julia> versioninfo()
Julia Version 1.10.0
Commit 3120989f39b (2023-12-25 18:01 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (aarch64-linux-gnu)
  CPU: 6 × Cortex-A55
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, cortex-a55)
  Threads: 1 on 8 virtual cores

julia> t = Tuple(zeros(Int32, 1024*1024*4));

julia> convert(NTuple{1024*1024*4,UInt32}, t);

[15216] signal (11.1): Segmentation fault
in expression starting at REPL[2]:1
convert at ./essentials.jl:452
unknown function (ip: 0x746795e24b)
Allocations: 81932270 (Pool: 81932156; Big: 114); GC: 20
Segmentation fault
Seelengrab commented 1 month ago

1.10.1 doesn't segfault for me but I still get the stackoverflow. This suggests to me that this is some canary/return address being overwritten by accident, resulting in an empty stacktrace. I'll see if I can get an rr trace.

Seelengrab commented 1 month ago

rr trace is here: https://julialang-dumps.s3.amazonaws.com/reports/2024-05-24T15-42-56-Seelengrab.tar.zst

Seelengrab commented 1 month ago

Notably, printing a large struct containing such a tuple can work, so this suggests to me some more intricate problem:

julia> mutable struct LargeStruct
           size::UInt32
           data::NTuple{1024*1024*4,UInt32}
       end

julia> a = LargeStruct(1024*1024*4,Tuple(zeros(UInt32, 1024*1024*4)));

julia> show(stdout, a)
LargeStruct(0x00400000, (0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 [...]

(printing abbreviated here for obvious reasons)