Oracle.jl icon indicating copy to clipboard operation
Oracle.jl copied to clipboard

Startup issue on recent macOS on M3

Open cdegroot opened this issue 11 months ago • 13 comments

(Note, I don't have a mac myself, I still need to whip up a mini on AWS to reproduce, this is what colleagues have witnessed).

On macOS on a recent Macbook (thus on Apple's ARM chips), it seems like some of the ODPI structs have different sizes. The initialization check finds a discrepancy between the expected size for the OraData (48 bytes) and the actual size (64 bytes).

Given that OraDataBuffer does seem to pass the check, the only reasonable hypothesis is some extremely aggressive alignment on mac.

In any case, I mostly am putting this out there in case anyone else sees this and to figure out whether we're the first to use Oracle.jl on mac/ARM? It sounds unlikely...

(more to follow, but probably not until next year)

(.venv) ➜  src git:(eng-2485) ✗ julia oracle_example.jl
ERROR: LoadError: InitError: AssertionError: OraData should have sizeof 48 bytes. Found 64 bytes.
Stacktrace:
  [1] __init__()
    @ Oracle ~/.julia/packages/Oracle/4DDzj/src/Oracle.jl:45

cdegroot avatar Dec 20 '24 14:12 cdegroot

I'm also running into this error.

felipenoris avatar Dec 28 '24 21:12 felipenoris

What compiler / options are being used to compile ODPI-C?

cjbj avatar Jan 06 '25 00:01 cjbj

What compiler / options are being used to compile ODPI-C?

Please refer to https://github.com/felipenoris/Oracle.jl/blob/129fb75909e3da03ca3061f64660efae420e440e/deps/build.jl#L100.

I also noticed this same error on Linux using Julia nightly.

felipenoris avatar Jan 06 '25 00:01 felipenoris

What gcc / clang versions?

Before getting too deep into this, can you update ODPI-C from 4.2.1 to the current release 5.4.1?

cjbj avatar Jan 06 '25 00:01 cjbj

Is using @repr(C) in src/types.jl for only arm architecture feasable? something like (not verified though.. )


# Determine if the platform is ARM
const IS_ARM = Sys.MACHINE in ("aarch64", "arm")

# Define OraData conditionally
if IS_ARM
    @repr(C) struct OraData
        is_null::Int32        # 4 bytes
        value::OraDataBuffer  # 40 bytes
    end
else
    struct OraData
        is_null::Int32        # 4 bytes
        value::OraDataBuffer  # 40 bytes
    end
end

# Verify the size of OraData
println("Size of OraData: ", sizeof(OraData))
@assert sizeof(OraData) == 48

or Does it work with manual padding?:


struct OraData
    is_null::Int32          # 4 bytes
    padding::Int32          # 4 bytes, ensures 8-byte alignment
    value::OraDataBuffer    # 40 bytes
end

sudarshan12s avatar Jan 07 '25 04:01 sudarshan12s

@cjbj 5.4.1 has the same issue, but if I prep a patch (have mac access now) I'll bump while we're at it. C compiler is default on macOS

Apple clang version 16.0.0 (clang-1600.0.26.6)
Target: arm64-apple-darwin24.2.0
Thread model: posix

@sudarshan12s I'll probably go with just changing the size expectation on aarch64 for now and then see what other structs have similar alignment optimizations. Where does @repr() come from by the way? I'm not a Julia specialist, can't find any references to it.

cdegroot avatar Jan 07 '25 20:01 cdegroot

Did some toying around and concluded that the size difference is real and it's dangerous to override the check. My reasoning:

  • If Julia allocates an OraData, it'll allocate too much. That's fine.
  • If Julia passes an OraData by value to C, it will write too much data (Julia thinks 64 bytes, C thinks 48 bytes), which is bad.
  • If Julia fetches an OraData by value from C, it will copy too much data. On 64 bit platforms, that poses a small risk (as segments are likely to be on 64 byte boundaries anyway) but it's not what you want.

So the only real solution is to define the Julia struct in a way that it matches the C struct, alas. No cheap fixes :). In Julia's internals, there's a MAX_ALIGN that seems to be in play here which is much larger on aarch64 than on x64. It's used in a lot of places so hard to figure out how this exactly works but that definition matches the observed difference.

cdegroot avatar Jan 08 '25 00:01 cdegroot

@cjbj 5.4.1 has the same issue, but if I prep a patch (have mac access now) I'll bump while we're at it. C compiler is default on macOS

Apple clang version 16.0.0 (clang-1600.0.26.6)
Target: arm64-apple-darwin24.2.0
Thread model: posix

@sudarshan12s I'll probably go with just changing the size expectation on aarch64 for now and then see what other structs have similar alignment optimizations. Where does @repr() come from by the way? I'm not a Julia specialist, can't find any references to it.

My Mistake, I overlooked this. repr(C) seems to be for Rust . I am also not familiar with Julia, I was too trying to see if Julia has way to disable padding and enforce fixed layout or follow C layout with FFI as you mentioned.. Does this happen only with dpiData(having union) or with other structures too?

sudarshan12s avatar Jan 08 '25 07:01 sudarshan12s

Seems to be only this one. And I haven't found an easy way around it yet :)

(enough I could hack, probably, but this smells like something's off in Julialand. I guess I'll have to venture out there and find a forum or something)

cdegroot avatar Jan 08 '25 19:01 cdegroot

Asked on Julia Forum, https://discourse.julialang.org/t/unexpected-struct-size-on-aarch64-macos-m/124608

And answered there. The tl&dr is that primitive types and structs get different alignment, so OraDataBuffer needs to become a struct reflecting the size of the C-side union.

cdegroot avatar Jan 09 '25 20:01 cdegroot

@felipenoris I'm still without macOS access but it looks like we've gotten to the bottom of this on the forum? I think I can brew up a PR that changes the primitive type in a struct and maybe (not sure how) one that makes the macOS build uses aarch64 binaries/compilation, but I can't really locallly test it. Or do you have other ideas?

cdegroot avatar Jan 15 '25 16:01 cdegroot

I'm still without macOS access

https://github.com/mxschmitt/action-tmate

giordano avatar Jan 15 '25 16:01 giordano

https://github.com/mxschmitt/action-tmate

Heh, nice work-around. I asked work for a Mac Mini instead :-)

cdegroot avatar Jan 16 '25 18:01 cdegroot