Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[XForms] Segfault after fl_finish and fix

1 view
Skip to first unread message

Steven G. Messervey

unread,
Oct 4, 2016, 2:12:34 AM10/4/16
to xforms-de...@nongnu.org
Hello,
From my understanding, if you call fl_finish in a callback, fl_do_forms
should return.
Instead, tt segfaults.

Debian Wheezy 64-bit on x86_64.


Simple program to demonstrate the issue:
#include <forms.h>

void callback(FL_OBJECT *obj, long data) {
fl_finish();
}

int main(int argc, char **argv) {
FL_FORM *form;
FL_OBJECT *btn;

fl_initialize(&argc, argv, "TEST", 0, 0);
form = fl_bgn_form(FL_UP_BOX,320,120);
btn = fl_add_button(FL_NORMAL_BUTTON,40,70,80,30,"Click me");
fl_set_object_callback(btn,callback,0);
fl_end_form();

fl_show_form(form, FL_PLACE_MOUSE, FL_TRANSIENT, "FOO");
fl_do_forms();

return 0;
}

My proposed fix:
In lib/events.c - fli_object_qread():
replace all occurrences of fli_context = <some value>; with:
if (fli_context)
fli_context = <some_value>.

After applying the fix and recompiling, the above program works.

I discovered it while making XForms bindings to javascript (Duktape).

Thanks,
Steve M.


Jens Thoms Toerring

unread,
Oct 4, 2016, 3:26:40 AM10/4/16
to Development with and of XForms
Hi Steve,

On Mon, Oct 03, 2016 at 09:12:18PM -0400, Steven G. Messervey wrote:
> From my understanding, if you call fl_finish in a callback, fl_do_forms
> should return.
> Instead, tt segfaults.

I guess it never was intended to be callled from a callback
that returns but only just before exiting the application
(e.g. from an atexit() handler.

Since fl_finish() destroys everything related to XForms
(deleting all objects and forms and freeing memory for
them) calling it from a callback sounds a bit like cut-
ting off the branch you're sitting on since your within
an XForms callback whose proper working depends on
XForms;-) But since you can do it I agree that at least
an attempt should be made to handle that as far as pos-
sible.

> Debian Wheezy 64-bit on x86_64.
>
> Simple program to demonstrate the issue:
> #include <forms.h>
>
> void callback(FL_OBJECT *obj, long data) {
> fl_finish();
> }
>
> int main(int argc, char **argv) {
> FL_FORM *form;
> FL_OBJECT *btn;
>
> fl_initialize(&argc, argv, "TEST", 0, 0);
> form = fl_bgn_form(FL_UP_BOX,320,120);
> btn = fl_add_button(FL_NORMAL_BUTTON,40,70,80,30,"Click me");
> fl_set_object_callback(btn,callback,0);
> fl_end_form();
>
> fl_show_form(form, FL_PLACE_MOUSE, FL_TRANSIENT, "FOO");
> fl_do_forms();
>
> return 0;
> }

Indeed, that segfaults.

> My proposed fix:
> In lib/events.c - fli_object_qread():
> replace all occurrences of fli_context = <some value>; with:
> if (fli_context)
> fli_context = <some_value>.
>
> After applying the fix and recompiling, the above program works.

I've got to think about this since it's at a rather low level
point and I don't see all possible consequences at the moment.
We've got to make sure that not e.g. a now free'd object
(but for which there's still a pointer) gets accessed. At a
quick glance we've got to bail out immediately when after a
call of an objects callback it's obvious that fl_finish()
has been invked in there. What that involves is still a bit
unclear to me, though. I guess I will need some time to
consider all the possible consequences.

> I discovered it while making XForms bindings to javascript (Duktape).

Sounds like an interesting project!

Best regards, Jens
--
\ Jens Thoms Toerring ________ j...@toerring.de
\_______________________________ http://toerring.de

Steven G. Messervey

unread,
Oct 4, 2016, 11:17:42 AM10/4/16
to j...@toerring.de, Development with and of XForms
Hello Jens,
Yes, I see what you are saying.
I got hung up on a line from the manual:
"The most important function for doing the actual interaction with forms is

FL_OBJECT *fl_do_forms(void);

It starts the main loop of the program and returns only when either the
state of an object changes that has no callback bound to it or fl_finish()
is called in a callback. In the first case the address of the object is
returned, in the latter NULL."

(xforms_38.html#Part-V-Overview-of-Main-Functions, a little after the
discussion of fl_hide_form).

This behavior works for me, because the interpreter stops interpreting once
fl_do_forms is called;
I need it to return so the interpreter can process an exit call and do other
cleanup (close shared libraries, close files, etc.).

Thanks,
Steve M.


Jens Thoms Toerring

unread,
Oct 4, 2016, 11:57:34 AM10/4/16
to Steven G. Messervey, xforms-de...@nongnu.org
Hi Steven,

On Tue, Oct 04, 2016 at 11:16:26AM -0400, Steven G. Messervey wrote:
> Yes, I see what you are saying.
> I got hung up on a line from the manual:
> "The most important function for doing the actual interaction with forms is
>
> FL_OBJECT *fl_do_forms(void);
>
> It starts the main loop of the program and returns only when either the
> state of an object changes that has no callback bound to it or fl_finish()
> is called in a callback. In the first case the address of the object is
> returned, in the latter NULL."
>
> (xforms_38.html#Part-V-Overview-of-Main-Functions, a little after the
> discussion of fl_hide_form).

Thanks for bringing this to my attention since this is obviously
untrue! I think the expectation was that the callback calls exit()
after fl_finish(). As you've found out the hard way things go
badly wrong when hoping for it to make fl_do_forms() return
NULL. My gut feelung at the moment is the proper fix is to check
after each call of obj->object_callback() if XForms is still
alive (e.by by checking fli_context for NULL or fl_display for
None) and, if not, immediatel return, similar to what you
proposed, but at every such call.

> I need it to return so the interpreter can process an exit call and do other
> cleanup (close shared libraries, close files, etc.).

I see. That sounds like a perfectly reasonable use of that
feature. Please give me a bit of time to think this through,
at the moment my workload is a bit on the high side...

Best ergards, Jens

Steven G. Messervey

unread,
Oct 5, 2016, 10:49:54 AM10/5/16
to j...@toerring.de, xforms-de...@nongnu.org

-----Original Message-----
From: Jens Thoms Toerring [mailto:j...@toerring.de]
Sent: Tuesday, October 04, 2016 11:57 AM
To: Steven G. Messervey <nuke...@yahoo.com>; xforms-de...@nongnu.org
Subject: Re: [XForms] Segfault after fl_finish and fix

I understand, that's huge change.
The local patch I made works well enough for my immediate use case, so I am
in no rush.

Thanks,
Steve M.


0 new messages