On 02/28/2012 03:57 AM, Guido Winkelmann wrote: >> >> There's nothing in there between calling virDomainCreate() and >> virGetLastError(). There are no other threads, either. >> >> Anyway, I've fired up gdb now to see if I can find out where the error >> object gets lost. > > I found out what is happening here: > > I am using a C++ wrapper class for virDomainPtr, to make it fit better with > the RAII principles in that language. That means that, in the above code > snippet, even though it's not actually visible because it happens in the > constructor and destructor of a temporary object, the virDomainPtr for domain > gets copied once, virDomainRef() gets called on it, and after the attempt to > start the domain, virDomainFree() gets called. > > The problem is that virDomainFree() will unconditionally call > virResetLastError(). Correct. _Every_ call to a libvirt API resets last error, _on entry_. > > With that info, I could work around the problem, however, I still think that, > since virDomainFree() is a reference-counting free, it should only call > virResetLastError() when the reference count has actually reached 0. In fact, > it should probably even check whether the last error even belongs to the > domain being deleted. Not possible - it is not known on entry whether this is the last reference being freed. We've already fixed this sort of bug in libvirt itself in the past, where the code in daemon/remote.c wasn't properly passing errors back to the caller because the daemon glue code was calling intermediate functions like virDomainFree(). Your wrapper function that calls virDomainFree() on the temporary object needs to save the error beforehand and restore it afterwords. -- Eric Blake eblake@xxxxxxxxxx +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Attachment:
signature.asc
Description: OpenPGP digital signature