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