Boost logo

Boost Users :

Subject: [Boost-users] [Boost.serialization] unexpected bad_cast exception while deserializing some arbitrary instances (e.g.: ar & data) ...
From: Francois Mauger (mauger_at_[hidden])
Date: 2009-05-26 12:08:34


Hi serializers!

Let me present my problem:

I have a class, named 'io_factory', that enables to deserialize
an arbitrary object from a text (or XML) archive using the
following '__load_text' template method:

-8<---------------------------------------------------------------------

     class io_factory
     {
       ...

       template <typename Data>
       void __load_text (boost::archive::text_iarchive & ar_,
                        Data & data_)
       {
        Data & b = data_;
        std::cerr << "DEVEL: io_factory::__load_text: archive class name='"
                  << typeid (ar_).name () << "'"
                  << std::endl;
        std::cerr << "DEVEL: io_factory::__load_text: class name='"
                  << typeid (b).name () << "'"
                  << std::endl;
        try
          {
            /* Here I may experience an unexpected exception
              * only in very special circumstances:
              */
            ar_ >> b;
            std::cerr << "DEVEL: io_factory::__load_text: deserialization is ok."
                      << std::endl;
          }
        catch (std::exception & x)
          {
            std::cerr << "DEVEL: io_factory::__load_text: EXCEPTION="
                      << x.what ()
                      << std::endl;
        
          }
        std::cerr << "DEVEL: io_factory::__load_text: done"
                  << std::endl;
       }
       ...
    };

-8<---------------------------------------------------------------------

I wrote a shared library that makes use of this template code segment.
Using a test program, as I try to deserialize an instance of
some 'nemo3::ana_event' class from a Boost text archive file,
it prints:

-8<---------------------------------------------------------------------
DEVEL: io_factory::__load_text: archive class
name='N5boost7archive13text_iarchi
veE'
DEVEL: io_factory::__load_text: class name='N5nemo39ana_eventE' <= ok
'nemo3::ana_event'
DEVEL: io_factory::__load_text: deserialization is ok. <==== IT WORKS!
DEVEL: io_factory::__load_text: done
-8<---------------------------------------------------------------------

This is fine! My object is properly loaded from the file.
My test program works as expected.

Well, now, I also have a Python module that wraps some C++ code
and the 'io_factory' class. I use Boost.Python to do that.

When I run my Python program, importing this wrapper module, to
deserialize the same Boost text archive file from the python shell; it
prints:

-8<---------------------------------------------------------------------
...
DEVEL: io_factory::__load_text: archive class
name='N5boost7archive13text_iarchiveE'
DEVEL: io_factory::__load_text: class name='N5nemo39ana_eventE'
DEVEL: io_factory::__load_text: EXCEPTION=std::bad_cast <= OOOOPS!
DEVEL: io_factory::__load_text: done
...
-8<---------------------------------------------------------------------

As you can see, there is a nasty 'std::bad_cast' thrown exception from
the "ar_ >> b;" statement. This code works perfectly in the first case,
now something is broken and I cannot figure out what!

I am really confused by this issue. I already used
exactly the same approach within another library (also based on
Boost.serialization and Boost.Python) and I never met any problem.
More, I also have a smaller python script that uses the same
wrapper module with the same input archive file and it works:
I can read all the instances I stored in my archive file!
If I use an XML archive, the problem is exactly the same: it works in
the first case, not in the last one.

I do not understand where this 'bad_cast' exception comes from.
For me it as nothing to do with:
- the format of the archive (I know the archive file is ok as the test
program store/load is properly)
- the wrapping within Python (I can make it run ok within a sample
python script)

I really need a hint that could help me to understand this issue.
It seems this problem looks like a side-effect (?)
anyway the deep reason is outside of the scope of my code and my knowledge.

My config is:

* OS:
   Ubuntu Linux 8.04

* Linux Kernel:
   $ uname -a
   Linux mauger-laptop 2.6.24-24-generic #1 SMP Wed Apr 15 15:54:25 UTC
2009 i686 GNU/Linux

* Boost:
   $ boost-config --version
   1_38_0

* gcc:
   $ g++ --version
   g++ (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu3)

* Python 2.5

I'd really appreciate your comments.
I'm afraid I cannot send a small sample code that could reproduce
this 'bug' in a simpler way as it comes only at a quite high level on
top of 3 big shared libraries + Boost + Python.
My attempt to isolate some critical code to see this side-effect
within "Boost.serialization only" or "Boost.Python only" failed.
More it confirms that the code works as expected (hum... or seems to
work...).

Thanks a lot for your help.

regards

frc

--
François Mauger
Département de Physique - Université de Caen Basse-Normandie
courriel/e-mail: mauger_at_[hidden]
tél./phone: 02 31 45 25 12 / (+33) 2 31 45 25 12
fax:        02 31 45 25 49 / (+33) 2 31 45 25 49
Adresse/address:
   Laboratoire de Physique Corpusculaire de Caen (UMR 6534)
   ENSICAEN
   6, Boulevard du Marechal Juin
   14050 CAEN Cedex
   FRANCE

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net