Thread overview
GtkD crash
Feb 21, 2020
mark
Feb 21, 2020
Ron Tarrant
Feb 21, 2020
mark
Feb 22, 2020
Ron Tarrant
February 21, 2020
I'm porting a simple game to GtkD to learn the library and more about D.

Unfortunately, I've hit a show-stopping crash.

I have a subclass of ApplicationWindow which has this method:

    private void onChangeState(int score, Board.State state) {
        import std.format: format;

        string message;
        if (state == Board.State.GAME_OVER)
            message = format("%,d Game Over", score);
        else if (state == Board.State.USER_WON) {
            if (score > highScore) {
                message = format("%,d New High Score!", score);
                highScore = score; // TODO save highScore
            } else
                message = format("%,d You Won!", score);
        } else // still playing
            message = format("%,d/%,d", score, highScore);
        statusLabel.setText(message); // BUG
    }

This method gets passed to another widget which calls it whenever the game's state or score changes.

If the BUG line is commented out, the program runs fine (well, except that the Label always shows "0/0").

But if the BUG line is uncommented (as above), it crashes:

$ dub
Performing "debug" build using /home/mark/opt/ldc2-1.20.0-linux-x86_64/bin/ldc2 for x86_64.
gtk-d:gtkd 3.9.0: target for configuration "library" is up to date.
gravitate ~master: target for configuration "application" is up to date.
To force a rebuild of up-to-date targets, run again with --force.
Running ./gravitate
onChangeState 0 PLAYING
Program exited with code -11

Here's what it looks like in gdb (slightly edited):

$ gdb gravitate
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
[snip]
This GDB was configured as "x86_64-linux-gnu".
[snip]
Reading symbols from gravitate...done.
(gdb) run
Starting program: /home/mark/app/gravitate/d/gravitate
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff6e02700 (LWP 7017)]
[New Thread 0x7ffff6601700 (LWP 7018)]
[New Thread 0x7ffff5e00700 (LWP 7019)]
[New Thread 0x7ffff55ff700 (LWP 7020)]
[New Thread 0x7ffff4dfe700 (LWP 7021)]
[New Thread 0x7fffdffff700 (LWP 7022)]
[New Thread 0x7fffdf7fe700 (LWP 7023)]
[New Thread 0x7fffce3a5700 (LWP 7024)]
[New Thread 0x7fffcdba4700 (LWP 7025)]
onChangeState 0 PLAYING

Thread 1 "gravitate" received signal SIGSEGV, Segmentation fault.
0x0000555555704cc1 in gamewindow.GameWindow.onChangeState(int, board.Board.State) (this=0x7ffff7ecf700, score=0,
    state=board.Board.PLAYING) at gamewindow.d:182
182	        statusLabel.setText(message);
(gdb) bt
warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
[ + several more like these ]

#0  0x0000555555704cc1 in gamewindow.GameWindow.onChangeState(int, board.Board.State) (this=0x7ffff7ecf700, score=0, state=board.Board.PLAYING) at gamewindow.d:182
warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
#1  0x0000555555728246 in board.Board.newGame() (this=0x7fffcc92d000) at board.d:60
warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
#2  0x0000555555704bb8 in _D5board5Board6__ctorMFDFiEQzQv5StateZvZCQBnQBk (warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
this=0x7fffcc92d000, warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
onChangeState=...)
    at board.d:42
warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
#3  0x0000555555703fc0 in warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
gamewindow.GameWindow.makeWidgets()warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
 (warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
this=0x7ffff7ecf700)warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
 at gamewindow.dwarning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x555555703fbf in read in psymtab, but not in symtab.)
:58
warning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
#4  0x0000555555703a2c in warning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
_D10gamewindow10GameWindow6__ctorMFC3gtk11ApplicationQnZCQCdQBuwarning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
 (warning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
this=0x7ffff7ecf700, warning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
application=0x7ffff7ed3360)warning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
 at gamewindow.dwarning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
warning: (Internal error: pc 0x555555703a2b in read in psymtab, but not in symtab.)
:31
#5  0x000055555572d73f in _D3app4mainFAAyaZ__T12__dgliteral2TC3gio11ApplicationQnZQBkMFQBaZv (GioApplication=0x7ffff7ed3360)
    at app.d:13
#6  0x000055555590bed4 in _D7gobject8DClosureQj__T17d_closure_marshalTDFC3gio11ApplicationQnZvZQBtUPSQCv1c5types8GClosurePSQDrQwQw6GValuekQrPvQcZv (closure=0x555555bfd8e0, return_value=0x0, n_param_values=1, param_values=0x7ffff7ef49c0, invocation_hint=0x7fffffffd6f0 "\b", marshal_data=0x0) at DClosure.d:122
#7  0x00007ffff419410d in g_closure_invoke () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#8  0x00007ffff41a705e in  () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#9  0x00007ffff41af715 in g_signal_emit_valist () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#10 0x00007ffff41b012f in g_signal_emit () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#11 0x00007fffd747cb95 in  () at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#12 0x00007fffd747cda6 in g_application_run () at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#13 0x00005555558d3005 in _D3gio11ApplicationQn3runMFAAyaZi (this=0x7ffff7ed3360, argv=...) at Application.d:931
#14 0x000055555572d6c0 in D main (args=...) at app.d:15
(gdb)


February 21, 2020
On Friday, 21 February 2020 at 08:55:43 UTC, mark wrote:

>         statusLabel.setText(message); // BUG

Where is statusLabel instantiated?

Other than that, I see nothing wrong here.

February 21, 2020
Thanks for your question, it led me to focus on the Label and now I've solved the problem.

I thought that onChangeState was never called before the Label was constructed, but it turns out it is called before. So now I use:

	if (statusLabel !is null)
	    statusLabel.setText(message);

Now it works.

Thanks!
February 22, 2020
On Friday, 21 February 2020 at 13:36:58 UTC, mark wrote:

> I thought that onChangeState was never called before the Label was constructed

That's one of the 'features' (wink wink) of GtkD. It's possible to call the function as a class function (uninstantiated, in other words) or as an object function (instantiated). There are times when it's handy to have either at your disposal.

> Now it works.
>
> Thanks!