[Bug 696] New: Reimplementation of ctype functions causes program crash if other OSS package uses them in static constuctors

https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=696

Summary: Reimplementation of ctype functions causes program
crash if other OSS package uses them in static
constuctors
Product: RTT
Version: rtt-trunk
Platform: All
OS/Version: GNU/Linux
Status: NEW
Severity: blocker
Priority: P3
Component: Real-Time Toolkit (RTT)
AssignedTo: orocos-dev [..] ...
ReportedBy: kiwi [dot] net [..] ...
CC: orocos-dev [..] ...
Estimated Hours: 0.0

Using OpenCV and RTT v1.10 in Ubuntu Jaunty. Programs were crashing prior to
main() occuring. After mountains of head scratching, we figured out that the
`src/os/rtctype.cpp` file that re-implemented the isalpha(), etc, functions was
causing problems.

Our solution was to move aside the `src/os/rtctype.cpp` file and rebuild the
library. The file is not needed in Ubuntu Hardy with target=gnulinux.

As part of OpenCV's startup, it registers some types and as part of that is
uses isalpha(). It was picking up RTT's isalpha() function instead of using the
O/S's implementation, except that RTT's static constructor had not yet
initialized the table used by its re-implemented isalpha().

Output from failing program was
{{{
sroderick@xxx:~/software/orocos$ ./bug-opencv
rtt isalpha o
c=o No No No
rtt isalpha o
OpenCV Error: Bad argument (Type name should start with a letter or _) in
cvRegisterType, file ../../../opencv/opencv/src/cxcore/cxpersistence.cpp, line
4595
Segmentation fault
}}}

The "rtt isalpha o" was from the following debug line we added to rtctype.cpp
to show that its isalpha() was being called with the 'o' character.
{{{
inline int isalpha( int c )
{
printf("rtt isalpha %c\n", c); // debug line
return values[ c ] & alpha;
}
}}}

The "c=o No No No" is from OpenCV's (trunk-svn as of this morning)
src/cxcore/cxpersistence.cpp::cvRegisterType() function, with debug printing of
{{{
c = _info->type_name[0]; // original line

#define YESNO(b) (b?"Yes":"No")
printf("c=%c %s %s %s\n",
c, YESNO(isalpha(c)), YESNO(islower(c)), YESNO(isdigit(c)));
}}}

isalpha() should retrun "Yes, Yes, No" but returns "No No NO" as the table
isn't yet initialized.

The overall problem is that RTT's isalpha() types show up as weak symbols, and
are linked to opencv at runtime instead of the glibc symbols.

So the question is, why are these re-implemented within RTT? According to the
SVN log they have been here since day one of Orocos, so I'm very surprised they
haven't caused this issue before. We have *not* noticed this problem in Mac OS
X, Centos, nor Ubuntu Gutsy and Hardy.

[Bug 696] Reimplementation of ctype functions causes program cra

https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=696

Peter Soetens <peter [..] ...> changed:

What |Removed |Added
----------------------------------------------------------------------------
CC| |peter [..] ...
Resolution| |FIXED
Status|NEW |RESOLVED

--- Comment #2 from Peter Soetens <peter [..] ...> 2009-08-25 09:36:19 ---
(In reply to comment #1)
> The following test file demonstrates the problem on our Jaunty system.
> {{{
> int main(int argc, char* argv[])
> {
> return 0;
> }
> }}}
>
> Yes, that simple file is enough for us! If you link with only one of CV or RTT,
> everything is fine, otherwise when linking with both then the problem occurs.

I removed rtctype and the rt_exception files (will backport to 1.8.x). They
were from the old 'in kernel' days where these symbols were missing. They
managed to stay anyway because they weren't causing any trouble.

I should have removed them proactively.

Peter

[Bug 696] Reimplementation of ctype functions causes program cra

On Aug 25, 2009, at 03:36 , Peter Soetens wrote:

> https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=696
>
>
> Peter Soetens <peter [..] ...> changed:
>
> What |Removed |Added
> ----------------------------------------------------------------------------
> CC| |peter [..] ...
> Resolution| |FIXED
> Status|NEW |RESOLVED
>
>
>
>
> --- Comment #2 from Peter Soetens <peter [..] ...>
> 2009-08-25 09:36:19 ---
> (In reply to comment #1)
>> The following test file demonstrates the problem on our Jaunty
>> system.
>> {{{
>> int main(int argc, char* argv[])
>> {
>> return 0;
>> }
>> }}}
>>
>> Yes, that simple file is enough for us! If you link with only one
>> of CV or RTT,
>> everything is fine, otherwise when linking with both then the
>> problem occurs.
>
> I removed rtctype and the rt_exception files (will backport to
> 1.8.x). They
> were from the old 'in kernel' days where these symbols were missing.
> They
> managed to stay anyway because they weren't causing any trouble.

When we finally figured this out (and it took quite a while), we were
stunned that this hasn't occurred before. Must be some recent change
in glibc or dl in Jaunty that triggered it, is the only thing that we
can think of.
S

[Bug 696] Reimplementation of ctype functions causes program cra

https://www.fmtc.be/bugzilla/orocos/show_bug.cgi?id=696

--- Comment #1 from S Roderick <kiwi [dot] net [..] ...> 2009-08-24 22:11:08 ---
The following test file demonstrates the problem on our Jaunty system.
{{{
int main(int argc, char* argv[])
{
return 0;
}
}}}

Yes, that simple file is enough for us! If you link with only one of CV or RTT,
everything is fine, otherwise when linking with both then the problem occurs.

Build with
{{{
g++ -o bug-opencv bug-opencv.cpp \
/path/to/lib/liborocos-rtt-gnulinux.so \
/path/to/opencv/lib/libcxcore.so.3
}}}

The offending 'isalpha' weak symbol is shown in the following
{{{
sroderick@xxx:~/nrc/build/transport/components/tests$ nm -C
/home/sroderick/nrc/install/lib/liborocos-rtt-gnulinux.so | grep isa
0075c81c T RTT::StateMachine::disableEvents(RTT::StateInterface*)
00898b0a W RTT::ActivityInterface::disableRun(RTT::RunnableInterface*)
0089923e T RTT::Logger::disallowRealTime()
00886fc2 t RTT::disableAll(RTT::detail::EventCatcher*)
009ed985 W bool boost::spirit::impl::isalpha_<char>(char)
U isalnum@@GLIBC_2.0
008ccce0 W isalpha

sroderick@xxx:~/nrc/build/transport/components/tests$ nm -C
/home/sroderick/software/install/opencv/lib/libcxcore.so | grep isa
U isalnum@@GLIBC_2.0
U isalpha@@GLIBC_2.0
001d32d0 T isamax_
}}}