After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 741485 - Captured variable struct missing ref
Captured variable struct missing ref
Status: RESOLVED NOTGNOME
Product: vala
Classification: Core
Component: Code Generator
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Vala maintainers
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2014-12-13 17:16 UTC by Ted Gould
Modified: 2014-12-17 19:34 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Code that shows the problem (574 bytes, text/x-vala)
2014-12-13 17:16 UTC, Ted Gould
Details

Description Ted Gould 2014-12-13 17:16:44 UTC
Created attachment 292668 [details]
Code that shows the problem

It seems that the data structure setup to capture variables for callbacks gets created with a reference count of one, but then unref'd in the same function. Meaning it gets deallocated before the callback can get called.

I've attached a small bit of Vala code that shows this with the Pulse interface (where I found it), but I think that it happens with all callbacks used with captured variables that don't have a a destroy callback. For instance I also have an callback with timeout which adds an additional ref in the C code.

Here's the offending generated function:

void dopulse (const gchar* printout) {
	Block1Data* _data1_;
	const gchar* _tmp0_ = NULL;
	gchar* _tmp1_ = NULL;
	pa_glib_mainloop* loop = NULL;
	pa_glib_mainloop* _tmp2_ = NULL;
	pa_proplist* props = NULL;
	pa_proplist* _tmp3_ = NULL;
	pa_context* context = NULL;
	pa_mainloop_api* _tmp4_ = NULL;
	pa_context* _tmp5_ = NULL;
	pa_operation* _tmp6_ = NULL;
	pa_operation* _tmp7_ = NULL;
	g_return_if_fail (printout != NULL);
	_data1_ = g_slice_new0 (Block1Data);
	_data1_->_ref_count_ = 1;
	_tmp0_ = printout;
	_tmp1_ = g_strdup (_tmp0_);
	_g_free0 (_data1_->printout);
	_data1_->printout = _tmp1_;
	_tmp2_ = pa_glib_mainloop_new (NULL);
	loop = _tmp2_;
	_tmp3_ = pa_proplist_new ();
	props = _tmp3_;
	_tmp4_ = pa_glib_mainloop_get_api (loop);
	_tmp5_ = pa_context_new_with_proplist (_tmp4_, NULL, props);
	context = _tmp5_;
	_tmp6_ = pa_context_get_server_info (context, ___lambda4__pa_context_serverinfocb, _data1_);
	_tmp7_ = _tmp6_;
	_pa_operation_unref0 (_tmp7_);
	_pa_context_unref0 (context);
	_pa_proplist_free0 (props);
	_pa_glib_mainloop_free0 (loop);
	block1_data_unref (_data1_);
	_data1_ = NULL;
}

There needs to be an additional call to block1_data_ref() or remove the block1_data_unref() call.
Comment 1 Luca Bruno 2014-12-13 17:30:11 UTC
This is a problem of the pulseaudio bindings. What bindings are you using? We do not ship pulseaudio bindings.
Comment 2 Ted Gould 2014-12-13 17:39:17 UTC
Pulse ships their own VAPI file. I don't see any issue with it:

http://cgit.freedesktop.org/pulseaudio/pulseaudio/tree/vala/libpulse.vapi#n1039
Comment 3 Luca Bruno 2014-12-13 17:43:13 UTC
The parameter should probably have [CCode (scope = "async")]
Comment 4 Ted Gould 2014-12-13 17:47:53 UTC
I added that to the VAPI file and regenerated the attached Vala file and the issue is not fixed.
Comment 5 Luca Bruno 2014-12-13 18:13:59 UTC
If it doesn't add a further ref of the block then you are using an old valac version.
Comment 6 Luca Bruno 2014-12-13 18:14:25 UTC
Sorry, also add the "owned" keyword.
Comment 7 Ted Gould 2014-12-15 15:21:25 UTC
I used the owned keyword and that didn't change the generation of the C file for me. I'm using valac 0.26.1.
Comment 8 Ted Gould 2014-12-15 15:23:33 UTC
Oh, I also tried in Valac 0.24 and the bug also occurs in that version of the compiler. It seems to be a long standing bug.
Comment 9 Luca Bruno 2014-12-15 15:55:56 UTC
I've changed the libpulse.vapi to:

public Operation? get_server_info([CCode (scope = "async")] owned ServerInfoCb cb);

And I get:

_tmp6_ = pa_context_get_server_info (context, ___lambda4__pa_context_serverinfocb, block1_data_ref (_data1_));

Perhaps you aren't referring to your own modified libpulse.vapi correctly.
Comment 10 Luca Bruno 2014-12-17 19:34:10 UTC
Closing. It's ok from Vala. The pulseaudio bindings need a fix. Please reopen if needed.