ITADN

null pointer is not 0 when calling into a dynamically linked library with the self-hosted compiler

#26035Openagagniere 创建于 2025-11-24
bugarch-x86_64miscompilationbackend-self-hosted
A
agagnierecommented
### Zig Version `0.16.0-dev.1442`, `0.15.2` ### Steps to Reproduce and Observed Behavior On linux amd64, compile: ```zig const std = @import("std"); const c = @cImport({ @cInclude("grpc/grpc.h"); }); pub fn main() !void { const s: c.grpc_slice = .{ .refcount = null, .data = .{ .inlined = .{ .length = 5, .bytes = "Hello\x00\x00_____-----_____\x00".*, } }, }; const d: c.gpr_timespec = .{ .tv_sec = 1, .clock_type = c.GPR_TIMESPAN }; _ = c.grpc_channel_create_call( @ptrFromInt(0xDeadBeef), null, 0, @ptrFromInt(0xCafeBabe), s, &s, d, null, ); } ``` ```console $ zig build-exe minrep.zig -l grpc -fno-llvm # possibly -L ... -I ... $ ldd minrep libgrpc.so.51 => [...]/libgrpc.so.51 (0x00007f69da200000) [...] ``` Then using gdb, stop at the first line of the called function ```console $ gdb minrep (gdb) break grpc_channel_create_call$plt Breakpoint 1 at 0x101d020 (gdb) run Breakpoint 1, 0x000000000101d020 in grpc_channel_create_call$plt () (gdb) step grpc_channel_create_call (channel=0x7fffffffd7e0, parent_call=0x10870f0 <os.linux.x86_64.restore_rt>, propagation_mask=32767, completion_queue=0x7fffffffd958, method=..., host=0x20, deadline=..., reserved=0x7fffffffd810) at src/core/lib/surface/channel.cc:104 104 gpr_timespec deadline, void* reserved) { (gdb) step 105 GRPC_CHECK(!reserved); (gdb) info args channel = 0xdeadbeef parent_call = 0x0 propagation_mask = 0 completion_queue = 0xcafebabe method = [...] host = 0x11a3040 <__anon_26790> deadline = {tv_sec = 1, tv_nsec = 0, clock_type = GPR_TIMESPAN} reserved = 0x7fffffffdac8 ``` we can see that `reserved` is not 0 (Note: I built libgrpc locally to get the debug symbols) ### Expected Behavior Using the LLVM backend results in the expected behavior: ```console $ zig build-exe minrep.zig -L ~/Clones/grpc/libs/dbg -l grpc -I ~/Clones/grpc/include/ -fllvm $ gdb minrep (gdb) break grpc_channel_create_call Breakpoint 1 at 0x11290c0 (gdb) run Breakpoint 1, grpc_channel_create_call (channel=0xdeadbeef, parent_call=0x0, propagation_mask=0, completion_queue=0xcafebabe, method=..., host=0x100d700 <__anon_27427>, deadline=..., reserved=0x0) at src/core/lib/surface/channel.cc:104 104 gpr_timespec deadline, void* reserved) { (gdb) step 105 GRPC_CHECK(!reserved); (gdb) info args channel = 0xdeadbeef parent_call = 0x0 propagation_mask = 0 completion_queue = 0xcafebabe method = [...] host = 0x100d700 <__anon_27427> deadline = {tv_sec = 1, tv_nsec = 0, clock_type = GPR_TIMESPAN} reserved = 0x0 ``` Here `reserved` in 0
0 条评论