Skip to content

Compiler crash when using -use-single-module with manual call to _startup_runtime() #5128

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

Closed
khaledh opened this issue May 6, 2025 · 3 comments · Fixed by #5131
Closed

Comments

@khaledh
Copy link

khaledh commented May 6, 2025

Context

Background: I'm just starting with Odin for bare-metal development. In this context, I'm taking over the entry point, so I need to call _startup_runtime() and _cleanup_runtime() myself (based on entry_unix.odin). I've been using -target:freestanding_amd64_sysv when I encountered this bug, but I was able to reproduce it even without cross-compiling (as in the repro steps below).

The compiler crashes with malloc: *** error for object 0x600000d60258: pointer being freed was not allocated when compiling an individual module that bootstraps the runtime itself (using _startup_runtime()) and the flag -use-single-module is in use. If this flag is removed, it compiles fine. This also happens when using -o:size or -o:speed, but I think it's just because those optimization modes use -use-single-module by default.

  • Operating System: macOS Sequoia (15.4.1) (arm64)
  • Odin Version: dev-2025-04-nightly:d9f990d
  • Please paste odin report output:
	Odin:    dev-2025-04-nightly:d9f990d
	OS:      macOS Sequoia 15.4.1 (build 24E263, kernel 24.4.0)
	CPU:     Apple M3
	RAM:     16384 MiB
	Backend: LLVM 20.1.1

Expected Behavior

The compiler should produce a single .o file without crashing.

Current Behavior

The compiler crashes as shown below.

Failure Information (for bugs)

The crash message is:

    odin(67063,0x1fbd00c80) malloc: *** error for object 0x600000d60258: pointer being freed was not allocated
    odin(67063,0x1fbd00c80) malloc: *** set a breakpoint in malloc_error_break to debug

Steps to Reproduce

  1. Create an odin file with the following content:
    package xyz
    
    import "base:runtime"
    
    foreign {
        @(link_name="__$startup_runtime")
        _startup_runtime :: proc "odin" () ---
    
        @(link_name="__$cleanup_runtime")
        _cleanup_runtime :: proc "odin" () ---
    }
    
    @export
    _start :: proc "c" () {
        context = runtime.default_context()
        #force_no_inline _startup_runtime()
        #force_no_inline _cleanup_runtime()
    }
  2. Compile using:
    $ odin build nomain.odin -file -build-mode:obj -use-single-module -out:nomain.o
    odin(67063,0x1fbd00c80) malloc: *** error for object 0x600000d60258: pointer being freed was not allocated
    odin(67063,0x1fbd00c80) malloc: *** set a breakpoint in malloc_error_break to debug
    fish: Job 1, 'odin build nomain.odin -file -b…' terminated by signal SIGABRT (Abort)
    
    Sometimes I also get no output at all, the compiler just hangs.
@laytan
Copy link
Collaborator

laytan commented May 7, 2025

You can actually just call runtime._startup_runtime() directly, without the foreign block etc.

It shouldn't crash of course, will have to look into that.

@Kelimion
Copy link
Member

Kelimion commented May 7, 2025

If we fix up the example to directly call runtime._*_runtime, then it works with -use-single-module.

package scratch

import "base:runtime"

@export
_start :: proc "c" () {
	context = runtime.default_context()
	#force_no_inline runtime._startup_runtime()
	#force_no_inline runtime._cleanup_runtime()
}
> odin build scratch.odin -file -build-mode:obj -out:nomain.obj -use-single-module
> echo %ERRORLEVEL%
0
> dir *.obj
07/05/2025  14:34            26.542 nomain.obj

But, without it it litters an object file for each package and doesn't create nomain.obj, even though it exited normally.

> odin build scratch.odin -file -build-mode:obj -out:nomain.obj
> echo %ERRORLEVEL%
0
> dir *.obj
07/05/2025  14:36             1.732 nomainnomain-builtin.obj
07/05/2025  14:36            31.547 nomainnomain-runtime.obj
07/05/2025  14:36             1.084 nomainnomain-scratch.obj

However, the original example does indeed crash the compiler, creating no object files of any kind.

W:\Scratch>odin build scratch.odin -file -build-mode:obj -out:nomain.obj -use-single-module

W:\Scratch>echo %ERRORLEVEL%
-1073741819

@khaledh
Copy link
Author

khaledh commented May 7, 2025

You can actually just call runtime._startup_runtime() directly, without the foreign block etc.

Thanks, this works. I literally just started learning Odin yesterday 😅

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

Successfully merging a pull request may close this issue.

3 participants