lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Fri, May 31, 2019 at 9:36 PM Egor Skriptunoff
<egor.skriptunoff@gmail.com> wrote:
...
> A programmer must understand that Lua doesn't anchor function's arguments.
> Otherwise he could write a program similar to the following:
>
>    local ffi = require"ffi"
>    ffi.cdef"int MessageBoxA(void*, const char*, const char*, int)"
>
>    local function show_message(str, cap)
>       str = ffi.cast("const char *", str)
>       cap = ffi.cast("const char *", cap)
>
>       -- add some code here which may trigger GC
>
>       ffi.C.MessageBoxA(nil, str, cap, 0)
>    end
>
>    show_message("Hello "..os.getenv"USERNAME", "Greeting")
>
>
> Here FFI library is used to create cdata (specific type of userdata) which contains references not visible by GC.
> New value of local variable 'str' is actually a C pointer to Lua string passed as argument.
> For this pointer to be valid, original Lua string must exist.
> But in this program 'str' may become a dangling pointer before 'MessageBoxA' is invoked.
> The situation is tricky enough.
> The mistake is observable only when Lua string is dynamically created (such as "Hello "..username).
> Strings represented as literals (such as "Greeting") are anchored by the function's prototype, so they will not be GC-ed inside this function.

This "ffi.cast" stuff will bite you in much simpler constructs, even
without any function calls:

s=package.path.."x" -- Just looking for a known external strin..
s=ffi.cast("const char *", s)
-- trigger gc, use s

IMNSHO this kinds of functions have their use, but it should be
wrapped and hiden deep in the bowels of a library written with great
care to have proper anchoring around all usages. No funky pcalls
needed to core dump.

> Of course, this problem is not FFI-library specific.
> You can make similar mistake when using usual userdatum.
> FFI library just gives you wonderful possibility to create userdata-like objects without writing C code.

Yep, it's halfway between lua and C, and any programmer can dump core
there. That's why I think ffi should be treaten as the C/C++ compiler,
just leave it to the pros and wrap it in a lib. My userdata libraries
may have bugs and dump, but I treat any possibiilty of the user been
able to trigger a dump from lua as a high priority bug. I nearly
switched to luajit to make the lib using ffi, and in this case I would
have threated the "lua" code using ffi as the C code.

> That's why I've suggested to add phrase to the Lua manual to emphasize the fact that Lua doesn't anchor functions' arguments.

That would be nice. I nearly hit that ( I'll say it again, is was a
bug in my code ), but some comments around the pcall / etc..
descriptions may be nice ( I was thinking, the args are in the stack
until return, so no gc, so I can touch them a bit. I did not think the
args may be cleared from the stack before executing, or the args may
be called before pushing results and result creation may trigger a gc.
Then I thought about it and sent the email which triggered this
discussion. Then I decide to do the right thing and anchor them myself
( as I do with some other stuff, assume the worst when not finding
docs, worst it can happen then is I wasted a few cycles ) ).

Francisco Olarte.