-
Notifications
You must be signed in to change notification settings - Fork 23
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
Adding memoryUnsafe and memorySafe effects #314
Comments
Yes! Finally we're bringing more of Nim's effect system into regular use, I love it. |
That's a poor way of phrasing it, it always is an issue. The problem is whether tools like
What does that mean, memory safety is always important, but what is safe it defined by the language, not wether your target has an MPU. |
How is |
Probably, but communication is hard.
I agree that adding more friction for a situational needs is not a good solution. Which is why
This is subjective. I use FFI &
So let's define it.
The consequences of an unsafe memory access depends (among other things) on your OS and target.
I added |
Yes, but DrNim can detect "array index out of bounds" and can do everything that Nim's effect system can do. I encourage contributions to DrNim... Maybe we can discuss these things on IRC/gitter/whatever suits you. |
I haven't looked in details at DrNim but safety by formal verification does sound interesting. |
Personally, I don’t feel like memUnsafe/safe can be very useful, I’d rather have other effects like “writes” (whose discussion has stalled a lot https://nim-lang.org/araq/writetracking.html) |
I assume this is missing raw memory management like alloc, alloc0, allocShared, create, createShared, c_malloc, free, freeShared, dealloc, deallocShared. Also newSeqUninitialized, everything that creates an uninitialized ref and, ptr and ptr UncheckedArray. I agree with Araq though, this is might be cheap in terms of semantics but formal verification is what you want in embedded. See my RFC #222 first part. |
Er, no, it's shipping via |
I thought about that, but I think it's more relevant to mark the act of accessing memory as unsafe rather than the allocation / deallocation. i.e. I don't think a dangling pointer that you never access is an issue.
This RFC extend the existing effect system with notation that already exists and is documented. It's purely a semantic check with familiar syntax. It's a simple solution, easy to understand that shouldn't be a burden in maintenance (at least I hope). There is no doubt that formal verification is a better, more rigorous solution in the long-run. |
Well at least DrNim is a separate tool, so the complexity is "elsewhere" and doesn't affect Nim with more experimental features. More importantly though: I claim the additions are not "worth it", so every time you lose productivity you need to measure it and every time you win productivity because it found a bug. Then in the end we would have an objective measure. It's hard to do but right now we don't even have anectodes about how it helps/hurts. Now, this argues for "let's add it and see how it turns out" but in the past we never removed any new effect from Nim, I tried to remove some but failed. There always are voices which want to keep every little thing that we added, esp if it "could find a bug one day". |
Imagine if DrNim is just ship like Nimpretty, it would make |
This seems pretty harmless to me. We can always deprecate/transform them out of code later, and any discussion of DrNim by comparison seems disingenuous at best -- DrNim has far less support (good luck compiling it) and is practically invisible as far as users are concerned. Are the annotations needed even documented? Are there examples? Gate this behind yet another flag if you must; I'm sure @timotheecour would be happy to provide a PR to do so. |
What about: proc myUnsafeProc() {.memUnsafe.} =
discard
let indirect: proc () = myUnsafeProc # allowed?
proc mySafeProc() {.memSafe.} =
indirect() # loophole here?
|
Fair. So what you want for composition is type
SafeProc = concept c
c is proc
c.hasEffect not(memUnsafe) |
Merging code that is already planned to be removed is not a good practice, I agree.
From what I understand, DrNim should/will be able to deal with checking properties better than the current effect system can, so it's not absurd to compare it to an effect-based solution. DrNim being heavily in develoment shouldn't be a reason to not invest in it. If it has been decided to move towards formal verification and that DrNim is part of Nim's future, then efforts spent improving it are worth considering. Of course, remains the unanswered question of the timing : how long to implement this feature vs how long to stabilize DrNim ? |
[Citation Needed] ;-) In Nim I pretty often find myself resorting to
I'm interested in "unsafe" annotations less as a way to detect bugs, and more as a way of auditing modules I import and code I write, to try to constrain unsafe behaviors to limited areas. |
And you would run into less bugs if only they were inside an
When you audit code you can search for An alternative proposal would be a tag for not allowing direct calls into |
You certainly shouldn't cast or you would have a string that doesn't end with The short-term solution is to provide a conversion proc in sugar and the long-term solution is for all libraries that work on blobs to standardize on |
adding {.memSafe.}, {.memUnsafe.} would actually add a lot of complexity. Here are a few problems: under this RFC:
proc fn1() {.memSafe.} = discard
proc fn2() {.memUnsafe.} = discard
proc bar(fn: proc()) = fn()
So this forces you to have some kind of genericity in {.memSafe.} vs {.memUnsafe.}, but that has its own issues, eg for fwd declarations: proc bar[Fn](fn: Fn) # should you annotate as {.memSafe.} or {.memUnsafe.}?
proc fn1() {.memSafe.} = discard
proc fn2() {.memUnsafe.} = discard
proc bar[Fn](fn: Fn) = fn() and heuristics such as "if any argument is {.memUnsafe.}, mark it as {.memUnsafe.}" just don't cut it (too pessimistic). note that some of those problems affect other effects too, but the problem is exacerbated with memory safety. In all likelihood, the benefit you'd get would be limited (I doubt this would help catch bugs that couldn't be caught otherwise), especially in comparison with the costs involved. precedent: see D's analogous annotations @safe, @trusted, @System (https://dlang.org/spec/memory-safe-d.html#:~:text=Memory%20Safety%20for%20a%20program,never%20result%20in%20memory%20corruption.) which make the language significantly more complex for IMO limited benefit. |
That's function coloring. It is justified in many case because it helps read the codebase or ensure some degree of safety but too much coloring and you fall in http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/. That said, I think coloring for async/await or Having a type system is a form of coloring your functions already. We need a balance between convenience and overkill. |
From https://arxiv.org/pdf/2007.00752.pdf
Which supports my view, fwiw, not even in Rust it's easy to tell whether you used something "unsafe". Whatever that even means, of course eventually you use loads and stores into memory... |
The goal of this RFC is to add a
memUnsafe
effect to Nim to be able to trace unsafe operations in procs.This needs to be an effect a not a tag because it has to be applied by keyword of the language (
cast
) and pragmas (importc
,importcpp
,emit
etc.).What is "unsafe" ?
Unsafe operations can be narrowed down in Nim to :
cast
addr
,unsafeAddr
importc
,importcpp
,importjs
,importobjc
,emit
[]
or.
syntax (ideally speaking, hidden dereferencing might be hard to track)Description
memUnsafe
should not have any impact by default. No friction should be added for wrapping library or writing code when memory safety isn't an issue.memUnsafe
therefore relies onmemSafe
to disables compilations of anymemUnsafe
effects.To remove the
memUnsafe
effect,{.cast(memSafe).}
can be used exactly likegcSafe
.Thus we can make the above example compile :
This would be useful for any context where memory safety is required (embedded target without an MPU comes to mind).
The text was updated successfully, but these errors were encountered: