Is Fil-C now using Claude for dev?
I have used Kimi K2.6-code and GLM 5.2, but only for things that are easy to verify. I did not use any LLMs for the longjmp/ucontext work.
11–20 of 32 posts
Is Fil-C now using Claude for dev?
I have used Kimi K2.6-code and GLM 5.2, but only for things that are easy to verify. I did not use any LLMs for the longjmp/ucontext work.
No complaints about this in particular, but code that uses setjmp/longjmp often has a risk profile that's way bigger than memory safety alone. If you're stuck with them then by all means, mitigate all you can.
You might find that Fil-C prevents those too. It’s pretty strict. You can only use longjmp to pop stack like an exception would
> For example, Boost uses ucontext as part of its fiber implementation. Maybe for the incredibly slow fallback, it does. Boost context and Boost fiber has ABI support for *nix / MacOS / Windows for x86_64 and ARM/ARM64. The overhead for a fiber switch using this support is about as heavy as a virtual function call. In comparison, ucontext is very heavy. I wrote my own fiber library for C. I got the idea from an old i…
It's heavy because it switches the signal masks.
Indeed, Fil-C's ucontext logic does this today, because I'm relying on glibc, and that's what glibc does.
But it would be straightforward to teach the internal Fil-C zfiber_context API to not save the sigmasks. It would just mean using some other backend for setcontext/swapcontext. Considering that there are multiple open source projects (including Boost!) that have code that does this, it would be easy to set that up.
But I'm taking baby steps here. And the first step is just to provide a memory safe wrapper around these quite dangerous APIs. Probably the next step is to just write a lot more tests to try to break it. Then, later, I can worry about adding alternative backends to expose the sigmask-free version of this that Boost (and most others) want.
> For example, Boost uses ucontext as part of its fiber implementation. Maybe for the incredibly slow fallback, it does. Boost context and Boost fiber has ABI support for *nix / MacOS / Windows for x86_64 and ARM/ARM64. The overhead for a fiber switch using this support is about as heavy as a virtual function call. In comparison, ucontext is very heavy. I wrote my own fiber library for C. I got the idea from an old i…
> In comparison, ucontext is very heavy It's heavy because it switches the signal masks. Indeed, Fil-C's ucontext logic does this today, because I'm relying on glibc, and that's what glibc does. But it would be straightforward to teach the internal Fil-C zfiber_context API to not save the sigmasks. It would just mean using some other backend for setcontext/swapcontext. Considering that there are multiple open source…
To do this, I disable signals on threads that are fiber threads, and instead rely on a signal thread to intercept signals and alert the appropriate fibers.
This is an article I wish I could have read many months ago. > Hence, the most basic safety issue with setjmp is that if we call it and then return from the function that had called it, the context saved by setjmp is not valid to longjmp to. > longjmp is only safe if it's called at a time when the stack frame used by setjmp could not have possibly been overwritten, since that is the only way to guarantee that the reg…
What about languages with pass by reference?
This is an article I wish I could have read many months ago. > Hence, the most basic safety issue with setjmp is that if we call it and then return from the function that had called it, the context saved by setjmp is not valid to longjmp to. > longjmp is only safe if it's called at a time when the stack frame used by setjmp could not have possibly been overwritten, since that is the only way to guarantee that the reg…
You can work around the pointer relocation issue by always coping the stack back onto the main stack. So you’re always running on the same range of stack in memory and saved stacks are always elsewhere
This is an article I wish I could have read many months ago. > Hence, the most basic safety issue with setjmp is that if we call it and then return from the function that had called it, the context saved by setjmp is not valid to longjmp to. > longjmp is only safe if it's called at a time when the stack frame used by setjmp could not have possibly been overwritten, since that is the only way to guarantee that the reg…
> What ruins this for C is the existence of pointers. Stacks aren't freely relocatable since pointers into the stack could exist. Other languages don't have this problem What about languages with pass by reference?
Base pointers are trivially relocatable. Just set the base pointer and it's done. This is how my language supports stack expansion: just reallocate the memory, overwrite base pointers, elements always dereference base plus offset, done. The heap is also implemented this way. All objects are indexes into a massive object array, and the base pointer is implicit.
https://www.matheusmoreira.com/articles/lone-lisp-heap
Absolute pointer references are not easily relocatable. You'd need to rewrite every single pointer. I've never seen anyone actually do this in C since it'd hit the same problem conservative garbage collectors do: you might rewrite an integer variable that just happens to look like a pointer.
If you're audacious enough you can try to somehow remap the stacks in the exact same spot they used to be at in order to not invalidate the pointers to begin with:
https://langdev.stackexchange.com/a/4242
https://www.microsoft.com/en-us/research/wp-content/uploads/...
Some languages like Go manage to do it because they just know where all the pointers are in most circumstances. They tend to choke only on foreign code they can't introspect into.
This is an article I wish I could have read many months ago. > Hence, the most basic safety issue with setjmp is that if we call it and then return from the function that had called it, the context saved by setjmp is not valid to longjmp to. > longjmp is only safe if it's called at a time when the stack frame used by setjmp could not have possibly been overwritten, since that is the only way to guarantee that the reg…
I’ve used the copy-stack trick before! It’s really great! You can work around the pointer relocation issue by always coping the stack back onto the main stack. So you’re always running on the same range of stack in memory and saved stacks are always elsewhere
https://langdev.stackexchange.com/a/4242
https://www.microsoft.com/en-us/research/wp-content/uploads/...
> How does he do it? By simply always restoring the continuation to exactly the place it was captured from, of course!
Pretty awesome. Gets around the problem by not relocating at all. I haven't read the full paper, to be honest. I just assumed it'd require defensive copying in case the stacks overlapped in memory.
Alexis King does outline the safety constraints that Fil-C would care about:
> references to stack-allocated data must not be shared across continuation chunk boundaries, as both capture and restore may relocate portions of the stack, making all references to stack-allocated memory in the relocated portions temporarily dangling
No complaints about this in particular, but code that uses setjmp/longjmp often has a risk profile that's way bigger than memory safety alone. If you're stuck with them then by all means, mitigate all you can.
What misuse are you imagining that isn’t a memory safety problem? You might find that Fil-C prevents those too. It’s pretty strict. You can only use longjmp to pop stack like an exception would