[Error] panic: switch on corrupt value | Working with pointers in Zig

Hi, I’m learning Zig and currently practicing by building a http server. I’m running into an issue which I think is memory-related but I have no clue what it is or how to debug that. I’m coming from a JavaScript background so pardon me if I don’t use the right words to describe the problem.

I’m using Libxev (as a libuv alternative) and using the TCP API it provides. I am able to receive connections but don’t know how to concurrently handle/accept multiple connections/requests.
Here’s the link to GitHub gist that shows my code. It is supposed to use the eventloop to process multiple connections but I get an error panic: switch on corrupt value. My guess is that I might have messed up how I use pointers.

Hi @pmbanugo, welcome to Ziggit.
I took a look at your code (briefly). I’m not seeing anything on first glance that would cause the issue. Does it give you a stacktrace at all?
You may want to run it with a debugger and get a backtrace that way to pin down where it is coming from.

var next_completion: xev.Completion = undefined;
    conn.accept(ev_loop, &next_completion, void, null, onAcceptConnection);

If you do have a pointer problem, this might be it. You’re giving accept a pointer to a stack value, which goes out of scope after you return the disarm.

Thanks for the response. I think that is the issue and every other alternatives I tried likely used stack value that went out of scope. I used this new knowledge to see how I can solve it, with help from LLM and I got it working, but it’s a bit more code and I need to reason about it and understand how to avoid such problems. Thanks!

Probably the simplest change is to pass a pointer to “completion” to your server function from main. That way the xev.Completion struct will remain in-scope (and allocated on the stack) for the lifetime of your server.

Edit to clarify you would move the declaration of completion to main, and then pass a pointer to that main xev.Completion struct to sever().

I haven’t found a way to run with debugger yet. I just debug.print and figure out the flow. I need to figure out a better way to debug Zig code

Here’s the code that got it working for me. Thanks for all your help

1 Like

My typical workflow for something like this is the following:

zig build
# Assuming your exe name is `exe`
lldb zig-out/bin/exe
# Or to use gdb
gdb zig-out/bin/exe

Then set a breakpoint on the function I want to look at.
If it’s a case like this where I have a panic, I will run it with the debugger, and get a bt backtrace. That pinpoints where in my code I need to look.

1 Like