[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-guile-ncurses] GC bug (?) with menu's
From: |
Mike Gran |
Subject: |
Re: [Bug-guile-ncurses] GC bug (?) with menu's |
Date: |
Thu, 12 Apr 2018 10:33:19 -0700 |
User-agent: |
Mutt/1.9.2 (2017-12-15) |
On Thu, Apr 12, 2018 at 04:45:18PM +0200, Thomas Danckaert wrote:
> Hi,
>
> I'm writing a guile-ncurses program where I want to update a menu (using
> guile-ncurses 2.2). This mostly works, but when refreshing the menu
> repeatedly, the program eventually segfaults. I've attached a small example
> to illustrate the problem:
>
> If you run the attached example, pressing 'r' updates the menu (here it just
> updates a counter in front of the menu items). If you keep pressing 'r',
> the program eventually segfaults. When exactly it happens is unpredictable,
> but shouldn't take more than a few seconds if you just hold down the 'r'
> key. I assume the unpredictability is due to the garbage collector.
>
> From the gdb stacktrace (and my limited understanding of the gc mechanisms),
> it seems that the list of menu items is somehow getting gc'ed prematurely:
>
> [New Thread 0x7ffecf65a700 (LWP 27338)]
> 11: Choice 2 Item 2
> Program received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 0x7ffecf65a700 (LWP 27338)]
> gc_free_menu (x=0x83bc60) at menu_type.c:403
> 403 pitem_store[i]->left = NULL;
>
> Is this a bug in the Guile-ncurses gc code, or am I making a wrong
> assumption in my code?
That's a bug, alright.
The work around is to not let your menu items be garbage collected
while the menu exists. Create a variable that holds onto your list
of menu items that has the same lifetime as the menu itself.
>
> Thanks!
>
> Thomas
>
> ps Is there a mailing list for more general questions about guile-ncurses,
> or should I just post to the guile-user list?
Well, this e-mail gets to me, the maintainer. I'm on guile-user, too. And
in the IRC, I'm spk121. So whatever works.
> (use-modules (srfi srfi-1)
> (ice-9 format)
> (ncurses curses)
> (ncurses menu))
>
> (define stdscr (initscr))
> (cbreak!)
> (noecho!)
> (keypad! stdscr #t)
> (define my-menu-win (newwin 10 40 4 4))
> (keypad! my-menu-win #t)
>
> (define (make-menu i)
> (let* ((names (map
> (lambda (s) (string-append (format #f "~d: " i) s))
> '("Choice 1" "Choice 2" "Choice 3" "Choice 4" "Exit")))
> (descriptions '("Item 1" "Item 2" "Item 3" "Item 4" "")))
> (new-menu (map (lambda (name desc) (new-item name desc))
> names descriptions))))
>
> (with-throw-handler #t
> (lambda ()
> (let draw-menu ((i 0))
> (let* ((my-menu (make-menu (+ 1 i))))
>
> ;; Set the main window and subwindow
> (set-menu-win! my-menu my-menu-win)
> (set-menu-sub! my-menu (derwin my-menu-win 6 38 3 1))
>
> ;; Set the menu mark string
> (set-menu-mark! my-menu " * ")
>
> ;; Post the menu
> (post-menu my-menu)
> (refresh my-menu-win)
>
> ;; Process the up and down arrow keys. Break the loop if F1 is
> ;; pressed. Ignore other keys.
> (let loop ((c (getch my-menu-win)))
> (cond
>
> ;; Move down the menu when down arrow is pressed and then loop.
> ((eqv? c KEY_DOWN)
> (begin
> (menu-driver my-menu REQ_DOWN_ITEM)
> (loop (getch my-menu-win))))
>
> ;; Move up the menu when the up arrow is pressed and then loop.
> ((eqv? c KEY_UP)
> (begin
> (menu-driver my-menu REQ_UP_ITEM)
> (loop (getch my-menu-win))))
>
> ((eqv? c #\r)
> (begin
> (unpost-menu my-menu)
> (draw-menu (+ 1 i))))
>
> ((not (eqv? c (key-f 1)))
> (loop (getch stdscr)))
> ))))
> )
> (lambda (key . parameters)
> (endwin)))
>
> (endwin)
>
Thanks,
- Mike Gran