Either I'm confused or the gc is

H. S. Teoh hsteoh at quickfur.ath.cx
Sun Nov 15 15:05:17 UTC 2020


On Sun, Nov 15, 2020 at 01:43:14PM +0000, donallen via Digitalmars-d wrote:
> With the help of an excellent suggestion by Steve Schveighoffer, I
> finally identified this problem yesterday. It was my error, not D's.
[...]
> void bind_text(sqlite3_stmt* stmt, int index, const char[] the_text)
> {
>     if (sqlite3_bind_text(stmt, index, toStringz(the_text), -1, null)
> != sqlite_ok)
>     {
>         stderr.writeln("bind_text failed");
>         auto db = sqlite3_db_handle(stmt);
>         stderr.writeln("Error: %s", fromStringz(sqlite3_errmsg(db)));
>         exit(EXIT_FAILURE);
>     }
> }
[...]
> The culprit is the call to toStringz. The documentation for that
> function give some good advice that I failed to follow:
> "Important Note: When passing a char* to a C function, and the C
> function keeps it around for any reason, make sure that you keep a
> reference to it in your D code. Otherwise, it may become invalid
> during a garbage collection cycle and cause a nasty bug when the C
> code tries to use it."

Ouch.  I'm dismayed that I missed this when I last looked at this code
(which I believe you did post here). ;-)  Passing a GC-allocated string
to C code without retaining a reference somewhere on the D side is a
known gotcha when interfacing with C.  In fact, I'm almost certain I ran
into this very problem with toStringz myself in the past, yet I still
failed to notice it when I looked at your code.

In any case, I'm glad that this means you'll be around here more. ;-)


--T


More information about the Digitalmars-d mailing list