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

Making a dynamic array with capacity and allocator but no length and returning it as a slice causes a compiler segmentation fault #4390

Open
amjoshuamichael opened this issue Oct 17, 2024 · 1 comment

Comments

@amjoshuamichael
Copy link

amjoshuamichael commented Oct 17, 2024

Context

Odin: dev-2024-10
OS: Arch Linux, Linux 6.11.3-arch1-1
CPU: Intel(R) Core(TM) i9-14900HX
RAM: 15693 MiB
Backend: LLVM 18.1.8

EDIT:

While doing some testing with this bug, which seems to only occur on linux, I've been able to replicate the bug on the following configuration:

Odin: dev-2024-10:af9ae4897
OS: macOS Sequoia 15 (build: 24A335, kernel: 24.0.0)
CPU: Apple M2 Max
RAM: 32768 MiB
Backend: LLVM 18.1.8

[END OF EDIT]

Expected Behavior

Should throw an error complaining that I haven't specified the length of the dynamic array, like so:

Error: Parameter 'len' of type 'int' is missing in procedure call 
       list := make([dynamic]u8, cap = 2, allocator = context.allocato ... 
	       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ... 

This is the behavior when you don't return the dynamic array as a slice.

Current Behavior

Compiler segfaults.

Failure Information (for bugs)

Here's an lldb backtrace on my machine:

frame #0: 0x0000555555627082 odin`check_stmt_internal(CheckerContext*, Ast*, unsigned int) [inlined] base_type(t=0x0000000000000000) at types.cpp:912:10
frame #1: 0x0000555555627082 odin`check_stmt_internal(CheckerContext*, Ast*, unsigned int) [inlined] is_type_array(t=<unavailable>) at types.cpp:1460:6
frame #2: 0x0000555555627082 odin`check_stmt_internal(CheckerContext*, Ast*, unsigned int) [inlined] check_return_stmt(ctx=0x00007fffdbbffbe0, node=0x00007fffd8235790) at check_stmt.cpp:2574:39
frame #3: 0x0000555555626a05 odin`check_stmt_internal(ctx=0x00007fffdbbffbe0, node=0x00007fffd8235790, flags=<unavailable>) at check_stmt.cpp:2651:3
frame #4: 0x000055555561909f odin`check_stmt_list(CheckerContext*, Slice<Ast*> const&, unsigned int) [inlined] check_stmt(ctx=0x00007fffdbbffbe0, node=0x00007fffd8235790, flags=<unavailable>) at check_stmt.cpp:672:2
frame #5: 0x000055555561904a odin`check_stmt_list(ctx=0x00007fffdbbffbe0, stmts=0x00007fffd8235840, flags=<unavailable>) at check_stmt.cpp:108:3
frame #6: 0x000055555561747f odin`check_proc_info(Checker*, ProcInfo*, PtrMap<Ast*, ExprInfo*>*) [inlined] check_proc_body(ctx_=0x00007fffdbbffaa0, token=Token @ 0x00007fffdbbffb90, decl=0x00007fffd8238fd0, type=0x00007fffd82644e0, body=0x00007fffd8235800) at check_decl.cpp:1886:3
frame #7: 0x00005555556171e3 odin`check_proc_info(c=0x00007fffd82319b0, pi=0x00007fffbc4129a0, untyped=<unavailable>) at checker.cpp:5877:26
frame #8: 0x0000555555615eff odin`check_proc_info_worker_proc(data=0x00007fffbc4129a0) at checker.cpp:6053:6
frame #9: 0x0000555555739aa3 odin`internal_thread_proc(void*) [inlined] thread_pool_thread_proc(thread=<unavailable>) at thread_pool.cpp:191:4
frame #10: 0x0000555555739a54 odin`internal_thread_proc(arg=<unavailable>) at threading.cpp:564:2
frame #11: 0x00007fffef8a339d libc.so.6`___lldb_unnamed_symbol3666 + 941
frame #12: 0x00007fffef92849c libc.so.6`___lldb_unnamed_symbol4097 + 7

The error occurs here.

   909 			if (t == nullptr) {
   910 				break;
   911 			}
-> 912 			if (t->kind != Type_Named) {
   913 				break;
   914 			}
   915 			if (t == t->Named.base) {

Steps to Reproduce

Here's a minimal program that produces the bug when I run odin build . on my machine.

package oh_no;

main :: proc() {
    numbers := make_numbers();
}

make_numbers :: proc() -> []u8 {
    list := make([dynamic]u8, cap = 2, allocator = context.allocator)
    return list[:];
}

Failure Logs

signal SIGSEGV: address not mapped to object (fault address: 0x0)

Note: I've been loving Odin so far! Thank you to all the contributors for helping to build such a great language.

@tf2spi
Copy link

tf2spi commented Oct 20, 2024

I think I've found the approximate source of the problem.

check_value_decl_stmt (ctx=0x7fffe5c1f7e0, node=0x7fffc9795640, mod_flags=32)
    at src/check_stmt.cpp:2086
2086                    if (e->type == nullptr) {
(gdb) p init_type
$15 = (Type *) 0x0
(gdb) list
2082                    }
2083                    e->flags |= EntityFlag_Visited;
2084
2085                    e->state = EntityState_InProgress;
2086                    if (e->type == nullptr) {
2087                            e->type = init_type;
2088                            e->state = EntityState_Resolved;
2089                    }
2090                    ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix, ac.link_suffix);
2091
(gdb) p *e
$24 = {kind = Entity_Variable, id = 3021, flags = std::atomic<unsigned long> = { 1 },
  state = std::atomic<EntityState> = { EntityState_InProgress }, token = {kind = Token_Ident,
    flags = 0 '\000', string = {
      text = 0x7fffc9793398 "list := make([dynamic]u8, cap = 2, allocator = context.allocator)\n    return list[:];\n}\n", len = 4}, pos = {file_id = 28, offset = 104, line = 8,
      column = 5}}, scope = 0x7fffcc7b9560, type = 0x0,
// More stuff below

init_type is nullptr here when it probably shouldn't for this local variable.

tf2spi added a commit to tf2spi/Odin that referenced this issue Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants