[signals] usage of any_cast

Hi, We just stumbled across a small problem with Boost.Signals, while playing with the symbol visibility features of gcc-3.4 and gcc-4. That feature is still buggy, but it unveiled some strange code. Somehow gcc failed to turn the type info of the types stored by any into a visible symbol, which is required for using boost::signals across shared libraries. So there are multiple type info objects and the dynamic_casts within signal failed, and the application crashed with a seg fault, since no one expected the cast to fail The code is in signal_template.hpp: template<typename Pair> R operator()(const Pair& slot) const { F* target = const_cast<F*>(any_cast<F>(&slot.second)); return (*target)(BOOST_SIGNALS_BOUND_ARGS); } I dont see why any_cast is used here at all. The type safety is guranteed by the interface of Boost.Signals, so I doubt that someone will be able to abuse the library. I believe the author of that code had the same in mind, since he did not test target != 0 before invoking the target. So in my opinion a simple reinterpret_cast should suffice here. It would also fix our issue, although that one is caused by gcc. Regards Andreas Pokorny

Hi Andreas, On Oct 12, 2005, at 10:57 AM, Andreas Pokorny wrote:
We just stumbled across a small problem with Boost.Signals, while playing with the symbol visibility features of gcc-3.4 and gcc-4. That feature is still buggy, but it unveiled some strange code.
We've stumbled into this as well.
The code is in signal_template.hpp:
template<typename Pair> R operator()(const Pair& slot) const { F* target = const_cast<F*>(any_cast<F>(&slot.second)); return (*target)(BOOST_SIGNALS_BOUND_ARGS); }
I dont see why any_cast is used here at all. The type safety is guranteed by the interface of Boost.Signals, so I doubt that someone will be able to abuse the library. I believe the author of that code had the same in mind, since he did not test target != 0 before invoking the target. So in my opinion a simple reinterpret_cast should suffice here. It would also fix our issue, although that one is caused by gcc.
You're right. Our options are: 1) Fix any_cast to compare typeid().name() instead of type_info objects 2) Make an unsafe_any_cast that doesn't do the check 3) Switch signals to use void*'s For 1.33.1, I like #2 best because it affects the least amount of code. For 1.34.0 and beyond, #1 is probably our best bet so that others don't run into the same problem. Doug

Hi Doug, On Wed, Oct 12, 2005 at 01:43:36PM -0500, Doug Gregor <dgregor@cs.indiana.edu> wrote:
I dont see why any_cast is used here at all. The type safety is guranteed by the interface of Boost.Signals, so I doubt that someone will be able to abuse the library. I believe the author of that code had the same in mind, since he did not test target != 0 before invoking the target. So in my opinion a simple reinterpret_cast should suffice here. It would also fix our issue, although that one is caused by gcc.
You're right. Our options are:
1) Fix any_cast to compare typeid().name() instead of type_info objects 2) Make an unsafe_any_cast that doesn't do the check 3) Switch signals to use void*'s
For 1.33.1, I like #2 best because it affects the least amount of code. For 1.34.0 and beyond, #1 is probably our best bet so that others don't run into the same problem.
Hm #1 does not sound good, it would make the cast even slower. I do not see a reason for dynamic typing here at all. #3 sounds good to me. Regards Andreas Pokorny

On Oct 12, 2005, at 4:28 PM, Andreas Pokorny wrote:
Hi Doug,
On Wed, Oct 12, 2005 at 01:43:36PM -0500, Doug Gregor <dgregor@cs.indiana.edu> wrote:
I dont see why any_cast is used here at all. The type safety is guranteed by the interface of Boost.Signals, so I doubt that someone will be able to abuse the library. I believe the author of that code had the same in mind, since he did not test target != 0 before invoking the target. So in my opinion a simple reinterpret_cast should suffice here. It would also fix our issue, although that one is caused by gcc.
You're right. Our options are:
1) Fix any_cast to compare typeid().name() instead of type_info objects 2) Make an unsafe_any_cast that doesn't do the check 3) Switch signals to use void*'s
For 1.33.1, I like #2 best because it affects the least amount of code. For 1.34.0 and beyond, #1 is probably our best bet so that others don't run into the same problem.
Hm #1 does not sound good, it would make the cast even slower. I do not see a reason for dynamic typing here at all. #3 sounds good to me.
So long as we're careful about deallocating the memory at the right time, sure; boost::any makes that kind of thing very, very easy. Doug
participants (3)
-
Andreas Pokorny
-
Doug Gregor
-
Jody Hagins