SEGV calling ca_context_create from file scope constructor
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
EPICS Base |
Fix Released
|
High
|
Andrew Johnson |
Bug Description
From Margaret Votava,
We are trying to understand a problem with a DESY/DOOCS utility. It generates a segmentation fault within ca_task_initialize (stack trace below). The
epicsMutex ca_client_
constructor is not being called in all OS platform/Compiler combinations.
In particular, a failing combination is
Linux 2.6.8-22.0.2/gcc v3.4.3 (red hat)
Linux 2.6.1/gcc v3.2.3 (red hat)
but works in Solaris with Solaris compiler.
We believe that this is a linker problem.
Has anyone seen before or have any clues of how to fix?
Thank you kindly,
Margaret
### epics code ###
(gdb) where
#0 epicsMutexLock (pmutexNode=0x0)
at ../../.
#1 0x006add15 in epicsMutex::lock (this=0x0)
at ../../.
#2 0x00ca19cb in ca_client_context (this=0x8d8ce08,
enablePreem
premptiveCa
at ../access.cpp:204
#4 0x00c8835e in ca_task_initialize () at ../access.cpp:180
### doocs code ####
#5 0x00a3e9f5 in epics_init ()
at
/home/votava/
#6 0x00a464b5 in EqCall (this=0x8d8cc88)
at
/home/votava/
#7 0x00e05837 in __static_
(__initialize_p=1,
__priority=
at
/home/votava/
#8 0x00e05917 in global constructors keyed to ea ()
at
/home/votava/
#9 0x00e36819 in __do_global_
from
/home/votava/
#10 0x00d45add in _init ()
from
/home/votava/
#11 0x00271318 in _dl_init_internal () from /lib/ld-linux.so.2 #12 0x002657ff in _dl_start_user () from /lib/ld-linux.so.2
Additional information:
The issue you have discovered occurs only when calling ca_context_create (a.k.a. ca_task_initialize) from your C++ file scope object's constructor.
The static variable "ca_client_
Which file scope constructor runs first is very C++ compiler implementation dependent.
Let me know if the attached patch resolves your troubles.
Jeff
cvs diff -u -wb -i -- ca_client_
Index: ca_client_
=======
RCS file: /net/phoebus/
retrieving revision 1.9.2.18
diff -c -u -w -b -i -r1.9.2.18 ca_client_
cvs diff: conflicting specifications of output style
--- ca_client_
+++ ca_client_
@@ -47,6 +47,7 @@
{
epicsThrea
caClientCa
+ delete ca_client_
}
// runs once only for each process
@@ -54,13 +55,14 @@
{
caClientCa
assert ( caClientCallbac
+ ca_client_
epicsAtExit ( cacExitHandler,0 );
}
extern epicsThreadPriv
cacService * ca_client_
-epicsMutex ca_client_
+epicsMutex * ca_client_
ca_client_
ca_
@@ -77,9 +79,7 @@
epicsThrea
- {
- // this wont consistently work if called from file scope constructor
- epicsGuard < epicsMutex > guard ( ca_client_
+ epicsGuard < epicsMutex > guard ( *ca_client_
if ( ca_client_
& ca_client_
@@ -88,7 +88,6 @@
else {
}
- }
this->sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
if ( this->sock == INVALID_SOCKET ) {
@@ -734,8 +733,9 @@
void ca_client_
{
- // this wont consistently work if called from file scope constructor
- epicsGuard < epicsMutex > guard ( ca_client_
+ epicsThreadOnce ( & cacOnce, cacOnceFunc, 0 );
+
+ epicsGuard < epicsMutex > guard ( *ca_client_
if ( ca_client_
throw std::logic_error
( "CA in-memory service already installed and can't be replaced");
Index: oldAccess.h
=======
RCS file: /net/phoebus/
retrieving revision 1.47.2.14
diff -c -u -w -b -i -r1.47.2.14 oldAccess.h
cvs diff: conflicting specifications of output style
--- oldAccess.h 19 Oct 2004 20:48:51 -0000 1.47.2.14
+++ oldAccess.h 17 Feb 2006 22:07:21 -0000
@@ -286,6 +286,9 @@
void operator delete ( void * );
};
+extern "C" void cacOnceFunc ( void * );
+extern "C" void cacExitHandler ( void *);
+
struct ca_client_context : public cacContextNotify
{
public:
@@ -412,8 +415,10 @@
ca_client_context ( const ca_client_context & );
ca_client_context & operator = ( const ca_client_context & );
+ friend void cacOnceFunc ( void * );
+ friend void cacExitHandler ( void *);
static cacService * pDefaultService;
- static epicsMutex defaultServiceI
+ static epicsMutex * pDefaultService
};
int fetchClientContext ( ca_client_context * * ppcac );
Original Mantis Bug: mantis-239
http://
I susequently installed this patch to reduce the scope of the previously mentioned patch.
Saved settings for D:\users\ hill\R3. 14.dll_ hell_fix\ epics\base successfully... context. cpp (in directory D:\users\ hill\R3. 14.dll_ hell_fix\ epics\base\ src\ca\ ) context. cpp ======= ======= ======= ======= ======= ======= ======= ======= ==== epicsmgr/ cvsroot/ epics/base/ src/ca/ ca_client_ context. cpp,v context. cpp context. cpp 17 Feb 2006 22:31:42 -0000 1.9.2.19 context. cpp 17 Feb 2006 22:38:36 -0000
cvs diff -u -wb -i -- ca_client_
Index: ca_client_
=======
RCS file: /net/phoebus/
retrieving revision 1.9.2.19
diff -c -u -w -b -i -r1.9.2.19 ca_client_
cvs diff: conflicting specifications of output style
--- ca_client_
+++ ca_client_
@@ -78,7 +78,7 @@
}
epicsThrea dOnce ( & cacOnce, cacOnceFunc, 0 ); context: :pDefaultServic eInstallMutex ); context: :pDefaultServic e ) {
this- >pServiceContex t.reset (
this- >pServiceContex t.reset ( new cac ( this->mutex, this->cbMutex, *this ) );
-
+ {
epicsGuard < epicsMutex > guard ( *ca_client_
if ( ca_client_
@@ -88,6 +88,7 @@
else {
}
+ }
this->sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
if ( this->sock == INVALID_SOCKET ) {
***** CVS exited normally with code 1 *****