[Kde-pim] SEGV reading Akonadi::Attribute from retrieveItem

Daniel Vrátil dvratil at redhat.com
Wed May 28 11:15:55 BST 2014


On Wednesday 28 of May 2014 11:53:29 Jesús Pérez wrote:
> Hi, I'm learning to develop Akonadi resources.

Hi Jesús,

> 
> Everything is going well until I set a custom attribute in collection
> and I try to read this attribute in retrieveItem() getting a
> segmentation violation for trying to access a null pointer.
> 
> This is how I did it:
> 
> I extend Akonadi::Attribute class to implement my custom property.
> Then, I register my custom attribute in resource constructor:
> 
> testResource::testResource( const QString &id )
> 
>   : ResourceBase( id )
> 
> {
>   // ...
>   AttributeFactory::registerAttribute<TestAttribute>();
> }
> 
> When retrieving collections, I set this attribute to collection:
> 
> void testResource::retrieveCollections()
> {
>   Collection c;
>   // ...
>   TestAttribute *attr = new TestAttribute("value1");
>   c.addAttribute(attr);
> }
> 
> I've checked that I can successfully read this value from retrieveItems:
> 
> void testResource::retrieveItems( const Akonadi::Collection &collection )
> {
>   TestAttribute *attr = collection.attribute<TestAttribute>();

You should *always* check whether attr != 0, even when you expect it not to be 
;-)

>   QByteArray attr_value = attr->serialized();
>   qDebug("retrieveItems value: %s", attr_value.constData());
>   // ...
> }
> 
> But when trying to get attribute from retrieveItem, it gives a null
> pointer. So trying to read any class attribute will give a SEGV:
> 
> bool testResource::retrieveItem( const Akonadi::Item &item, const
> QSet<QByteArray> &parts )
> {
>   TestAttribute *attr =
>   item.parentCollection().attribute<TestAttribute>(); // NULL pointer
>   QByteArray attr_value = attr->serialized(); // SEGV

That's why you should always check for a null pointer :-)

The problem here is that the Item you get in this method does not have a full 
parent Collection. The collection you get from parentCollection() only has ID 
set, nothing else (name, remoteId etc. will return empty values).

If you need to have access to item's parent collection attributes, you need to 
retrieve the collection manually.

>   qDebug("retrieveItem value: %s", attr_value.constData());
> }
> 
> I've also tried copying attribute from collection to item in
> retrieveItems and then read item attribute in retrieveItem with same
> result:
> 
> void testResource::retrieveItems( const Akonadi::Collection &collection )
> {
>   TestAttribute *attr = collection.attribute<TestAttribute>();
>   // ...
>   foreach (Akonadi::Item item, itemList)
>     item.addAttribute(attr);
>   // ...
> }
> 
> bool testResource::retrieveItem( const Akonadi::Item &item, const
> QSet<QByteArray> &parts )
> {
>   TestAttribute *attr = item.attribute<TestAttribute>(); // NULL pointer
>   QByteArray attr_value = attr->serialized(); // SEGV

This is either because in retrieveItems(), 
collection.attribute<TestAttribute>() returned a null pointer too, or because 
the item passed to this method is not fetched with attributes. For performance 
reasons, it's possible to specify what all parts of Item (or Collection) you 
want to fetch from Akonadi server, I think attributes for items are disabled 
by default.


Cheers,
Dan

>   qDebug("retrieveItem value: %s", attr_value.constData());
> }
> 
> In both cases, I've checked with akonadiconsole that attribute is
> successfully set, so the problem seems to be accessing to it from
> retrieveItem.
> 
> I've made a full test project by taking sample agent available at
> http://techbase.kde.org/Development/Tutorials/Akonadi/Resources and
> adding custom attribute:
> 
> http://anongit.chuso.net/testresource/tree/testresource.cpp#n48
> 
> Also, the second case adding attribute to item:
> 
> http://anongit.chuso.net/testresource/tree/testresource.cpp?h=attribute-on-i
> tems#n48
> 
> What am I doing wrong? Am I trying to do something that is not possible to
> do? _______________________________________________
> KDE PIM mailing list kde-pim at kde.org
> https://mail.kde.org/mailman/listinfo/kde-pim
> KDE PIM home page at http://pim.kde.org/

-- 
Daniel Vrátil | dvratil at redhat.com | dvratil on #kde-devel, #kontact, #akonadi
KDE Desktop Team
Associate Software Engineer, Red Hat

GPG Key: 0xC59D614F6F4AE348
Fingerprint: 4EC1 86E3 C54E 0B39 5FDD B5FB C59D 614F 6F4A E348
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: This is a digitally signed message part.
URL: <http://mail.kde.org/pipermail/kde-pim/attachments/20140528/110aa41d/attachment.sig>
-------------- next part --------------
_______________________________________________
KDE PIM mailing list kde-pim at kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
KDE PIM home page at http://pim.kde.org/


More information about the kde-pim mailing list