July 29, 2019
On Monday, 29 July 2019 at 08:17:34 UTC, Federico Santamorena wrote:
> On Monday, 29 July 2019 at 01:46:27 UTC, Exil wrote:
>> On Sunday, 28 July 2019 at 18:32:24 UTC, Federico Santamorena wrote:
>>> [...]
>>
>> Where is the "D object" allocated? Haven't seen anyone mention it, but the way the GC works, it has to know about the memory it needs to scan to look for an object.
>>
>> So if you pass an object allocated with the GC then pass it to GTK, the GC isn't going to know about the memory GTK has allocate. The kind of problem can happen that you mention, it deallocates the object because it doesn't think it is used anymore.
>
> I even tried GC.disable().
>
> The void* pointer still gets corrupted

Can you print the raw pointer value of context/userObj at different points to see when the corruption occurs?

Print "context" here: https://github.com/yatima1460/Drill/blob/576b4b691ea5357e5271115433eb11d4c0beeae7/Source/Frontend/GTK/Main.d#L585

Print "context" here:
https://github.com/yatima1460/Drill/blob/576b4b691ea5357e5271115433eb11d4c0beeae7/Source/Frontend/GTK/Main.d#L384

Print "userObject" here:
https://github.com/yatima1460/Drill/blob/576b4b691ea5357e5271115433eb11d4c0beeae7/Source/Backend/Context.d#L187

Print "userObject" here:
https://github.com/yatima1460/Drill/blob/576b4b691ea5357e5271115433eb11d4c0beeae7/Source/Backend/Context.d#L195

Then print "userObject" here:
https://github.com/yatima1460/Drill/blob/576b4b691ea5357e5271115433eb11d4c0beeae7/Source/Frontend/GTK/Main.d#L304

It looks like you're using printf so "%p" should work to print the pointer.
July 29, 2019
On Monday, 29 July 2019 at 08:35:20 UTC, Jonathan Marler wrote:
>
> Can you print the raw pointer value of context/userObj at different points to see when the corruption occurs?
>
> Print "context" here: https://github.com/yatima1460/Drill/blob/576b4b691ea5357e5271115433eb11d4c0beeae7/Source/Frontend/GTK/Main.d#L585
>
> Print "context" here:
> https://github.com/yatima1460/Drill/blob/576b4b691ea5357e5271115433eb11d4c0beeae7/Source/Frontend/GTK/Main.d#L384
>
> Print "userObject" here:
> https://github.com/yatima1460/Drill/blob/576b4b691ea5357e5271115433eb11d4c0beeae7/Source/Backend/Context.d#L187
>
> Print "userObject" here:
> https://github.com/yatima1460/Drill/blob/576b4b691ea5357e5271115433eb11d4c0beeae7/Source/Backend/Context.d#L195
>
> Then print "userObject" here:
> https://github.com/yatima1460/Drill/blob/576b4b691ea5357e5271115433eb11d4c0beeae7/Source/Frontend/GTK/Main.d#L304
>
> It looks like you're using printf so "%p" should work to print the pointer.

GC disabled:

activate context:0x7ffca2d0c4f8
gtk_search_changed context:0x7ffca2d0c4f8
startCrawling userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
startCrawling foreach loop userObject:0x7ffca2d0c4f8
resultFound result:0x7fc843559c60 userObject:0x7fc8435414d0
(drill-search-gtk:12395): GLib-CRITICAL **: 12:40:07.937: g_async_queue_push: assertion 'queue' failed

GC enabled:

activate context:0x7ffe9369c298
gtk_search_changed context:0x7ffe9369c298
startCrawling userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
startCrawling foreach loop userObject:0x7ffe9369c298
resultFound result:0x7f4f2625bb00 userObject:0x7f4f2628d440
(drill-search-gtk:12223): GLib-CRITICAL **: 12:38:54.729: g_async_queue_push: assertion 'queue' failed

As you can see the queue pointer inside the context is invalid because the context itself is now invalid and GLib notifies it
GC on or off does not make any difference, and the corruption happens at resultFound
I also want to add that I replaced the struct FileInfo with a pointer and it still happens


https://github.com/yatima1460/Drill/commit/5653c831b03d657a0c8073d5b011934f02ac8b65

July 29, 2019
You pass &context to Crawler, that's wrong pointer.
July 29, 2019
On Monday, 29 July 2019 at 11:01:10 UTC, Kagamin wrote:
> You pass &context to Crawler, that's wrong pointer.

You are the absolute madman it was so obvious yet so hidden.

I wonder how this can be avoided, I didn't use Variant because it does not support shared(), but maybe that was my sin.

What do you think about the idea of the compiler emitting a warning when the pointer to a void* pointer is assigned?

I can't think of a good reason to have a void* pointer to a void* pointer and actually never used one in code.

Maybe someone has a counterargument to this proposal?




July 29, 2019
Use delegates for callbacks to prevent this.
July 29, 2019
struct DrillGtkContext
{
    static extern(C)
    void gtk_search_changed(GtkEditable* widget, ref DrillGtkContext context)
    {
        context.onSearchChanged();
    }
    void onSearchChanged()
    {
        ...
        startCrawling(drillConfig, searchString, &resultFound);
    }
    void resultFound(immutable(FileInfo) result)
    {
        ...
        queue.g_async_queue_push(f);
    }
}

...
DrillContext* startCrawling(
    in const(DrillConfig) config,
    in immutable(string) searchValue,
    scope void delegate(immutable(FileInfo)) resultCallback)
{
    ...
    new Crawler(..., c.callback);
}
July 29, 2019
On Monday, 29 July 2019 at 12:18:51 UTC, Kagamin wrote:
> struct DrillGtkContext
> {
>     static extern(C)
>     void gtk_search_changed(GtkEditable* widget, ref DrillGtkContext context)
>     {
>         context.onSearchChanged();
>     }
>     void onSearchChanged()
>     {
>         ...
>         startCrawling(drillConfig, searchString, &resultFound);
>     }
>     void resultFound(immutable(FileInfo) result)
>     {
>         ...
>         queue.g_async_queue_push(f);
>     }
> }
>
> ...
> DrillContext* startCrawling(
>     in const(DrillConfig) config,
>     in immutable(string) searchValue,
>     scope void delegate(immutable(FileInfo)) resultCallback)
> {
>     ...
>     new Crawler(..., c.callback);
> }

Oooooh I see, I recently switched from C to D and this is a lot cleaner

I thought you couldn't use D things like "ref" in extern(C)
July 29, 2019
On Monday, 29 July 2019 at 12:18:51 UTC, Kagamin wrote:
> struct DrillGtkContext
> {
>     static extern(C)
>     void gtk_search_changed(GtkEditable* widget, ref DrillGtkContext context)
>     {
>         context.onSearchChanged();
>     }
>     void onSearchChanged()
>     {
>         ...
>         startCrawling(drillConfig, searchString, &resultFound);
>     }
>     void resultFound(immutable(FileInfo) result)
>     {
>         ...
>         queue.g_async_queue_push(f);
>     }
> }
>
> ...
> DrillContext* startCrawling(
>     in const(DrillConfig) config,
>     in immutable(string) searchValue,
>     scope void delegate(immutable(FileInfo)) resultCallback)
> {
>     ...
>     new Crawler(..., c.callback);
> }


Thanks to all in this thread, recently all the problems I am having with D are because D is actually superior to C and some assumptions I still have because of C should be uninstalled from my brain

Thanks.

July 29, 2019
On Monday, 29 July 2019 at 12:42:37 UTC, Federico Santamorena wrote:
> I thought you couldn't use D things like "ref" in extern(C)

It's not recommended for proper C bindings, as interoperability can be tricky, so they are kept close to original C source. Also to port C code and examples invocation should be as close to C code as possible. I would say your use of UFCS with gtk functions is probably not a good idea, it's difficult to recognize them as gtk functions this way, I had a suspicion something smart is going on there.
July 29, 2019
On Monday, 29 July 2019 at 13:27:51 UTC, Kagamin wrote:
> On Monday, 29 July 2019 at 12:42:37 UTC, Federico Santamorena wrote:
>> I thought you couldn't use D things like "ref" in extern(C)
>
> It's not recommended for proper C bindings, as interoperability can be tricky, so they are kept close to original C source. Also to port C code and examples invocation should be as close to C code as possible. I would say your use of UFCS with gtk functions is probably not a good idea, it's difficult to recognize them as gtk functions this way, I had a suspicion something smart is going on there.

I see.

I still actually want to push the idea that a void* pointer to a void* pointer should be a warning emitted by the compiler.

Or even better a new flag emitting warnings for fishy void* pointers manipulation.

Ideas about this?