|
|
Experimental Physics and
| ||||||||||||||
|
|
Hi All,
I write a simple CA program to read waveform data. If I monitor less than 41 waveform PVs(100 elements of float type and 25Hz scan rate), it works fine. If I monitor 42 or more(modify "CH_NUM" in archive.c), then segmentation fault occured. I used gdb to debug it.
(gdb) bt
#0 ca_element_count (pChan=0x31346677) at ../oldChannelNotify.cpp:634
#1 0x0000000000400fe3 in main (argc=<value optimized out>, argv=<value optimized out>) at archive.c:138
(gdb) where
#0 ca_element_count (pChan=0x31346677) at ../oldChannelNotify.cpp:634
#1 0x0000000000400fe3 in main (argc=<value optimized out>, argv=<value optimized out>) at archive.c:138
(gdb) l
629 /*
630 * ca_element_count ()
631 */
632 arrayElementCount epicsShareAPI ca_element_count ( chid pChan )
633 {
634 epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
635 return pChan->io.nativeElementCount ( guard );
636 }
637
638 /*
It seems that there is something wrong with "ca_element_count" and "epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );"
Then I used fixed count number 100 instead of using "ca_element_count", segment fault as well.
(gdb) bt
#0 ca_create_subscription (type=16, count=100, pChan=0x31346677, mask=5, pCallBack=0x401250 <monitor>, pCallBackArg=0x7fffc71f9470, monixptr=0x0) at ../oldChannelNotify.cpp:560
#1 0x0000000000400fd9 in main (argc=<value optimized out>, argv=<value optimized out>) at archive.c:141
(gdb) l
555 if ( mask & ~maskMask ) {
556 return ECA_BADMASK;
557 }
558
559 try {
560 epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
561 try {
562 // if this stalls out on a live circuit then an exception
563 // can be forthcoming which we must ignore (this is a
564 // special case preserving legacy ca_create_subscription
I guess there is something to do with "epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );" However, I don't know whether my code having bug or something else wrong. Any help will be appreciate
I'm using RedHat 6.5_x64 and EPICS base 3.14.12.1
Cheers
Xuan Wu
IHEP#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cadef.h>
#include <signal.h>
#define epicsAlarmGLOBAL
#include <alarm.h>
#define CH_NUM 42
#define MAX_STRING 40
#define TIME_OUT 5.0
FILE *fp;
void SetQuit(int sig)
{
fclose(fp);
printf("\nWarning!!!Stop signal is sent\n");
exit(0);
}
typedef struct
{
chid channel;
struct dbr_time_float *data;
} epicsFloatPV;
const char *channel_state_str[4] = {
"not found",
"connection lost",
"connected",
"closed"
};
void printFloatPV(const epicsFloatPV* pv)
{
char timeString[32];
const dbr_float_t * pValue;
int i;
unsigned int count;
if (ca_state(pv->channel) != cs_conn)
{
printf("%s <%s>\n",
ca_name(pv->channel),
channel_state_str[ca_state(pv->channel)]);
return;
}
epicsTimeToStrftime (timeString, sizeof(timeString), "%Y-%m-%d %H:%M:%S.%06f", &pv->data->stamp);
count = ca_element_count(pv->channel);
// printf("%s %s", ca_name(pv->channel), timeString);
fprintf(fp, "%s %s %d", ca_name(pv->channel), timeString, count);
pValue = &pv->data->value;
for(i=0; i<count; i++)
{
// printf(" %f", pValue[i]);
fprintf(fp, " %f", pValue[i]);
}
fprintf(fp, "\n");
if (pv->data->severity != NO_ALARM)
{
printf(" <%s %s>\n",
epicsAlarmSeverityStrings[pv->data->severity],
epicsAlarmConditionStrings[pv->data->status]);
}
}
static void monitor(struct event_handler_args args)
{
if (args.status != ECA_NORMAL)
{
/* Something went wrong. */
SEVCHK(args.status, "monitor");
return;
}
/* Let's have a look at the type of the data.
* It should be one of the types that we have requested.
* */
switch (args.type)
{
case DBR_TIME_FLOAT:
{
epicsFloatPV *pv = args.usr;
memcpy(pv->data, args.dbr, dbr_size_n(args.type, args.count));
printFloatPV(pv);
break;
}
default:
printf ("%s unsupported data type\n", ca_name(args.chid));
}
}
int main(int argc, char **argv)
{
int stat;
epicsFloatPV pv[CH_NUM];
int index;
char chName[MAX_STRING][CH_NUM];
struct sigaction act;
act.sa_handler = SetQuit;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGINT, &act, 0); //signal Ctrl+c
if((fp = fopen("data", "a+")) == NULL)
{
printf("can't open data file\n");
exit(0);
}
/* Initialize */
stat=ca_context_create(ca_disable_preemptive_callback);
if(stat != ECA_NORMAL)
{
printf("ca_context_create failed:\n%s\n",ca_message(stat));
exit(1);
}
/* Search */
for(index=0; index<CH_NUM; index++)
{
sprintf(chName[index], "wf%d", index+1);
stat=ca_create_channel(chName[index],NULL,NULL,CA_PRIORITY_DEFAULT,&pv[index].channel);
if(stat != ECA_NORMAL)
{
printf("ca_create_channel failed:\n%s\n",ca_message(stat));
exit(1);
}
}
SEVCHK(ca_pend_io(TIME_OUT), "ca_search");
for(index=0; index<CH_NUM; index++)
{
pv[index].data = malloc(dbr_size_n(DBF_FLOAT, ca_element_count(pv[index].channel)));
ca_create_subscription(DBR_TIME_FLOAT, ca_element_count(pv[index].channel), pv[index].channel, DBE_VALUE|DBE_ALARM, monitor, &pv[index], NULL);
// pv[index].data = malloc(dbr_size_n(DBF_FLOAT, 100));
// ca_create_subscription(DBR_TIME_FLOAT, 100, pv[index].channel, DBE_VALUE|DBE_ALARM, monitor, &pv[index], NULL);
}
SEVCHK(ca_flush_io(), "ca_add_event");
/* Process search */
/*stat=ca_pend_io(TIME_OUT);*/
stat=ca_pend_event(0);
if(stat != ECA_NORMAL)
{
printf("ca_pend_io timed out for search after %g sec\n", TIME_OUT);
exit(1);
}
/* Clear the channel */
for(index=0; index<CH_NUM; index++)
{
stat=ca_clear_channel(pv[index].channel);
if(stat != ECA_NORMAL)
{
printf("ca_clear_channel failed:\n%s\n",ca_message(stat));
}
// after ca_clear_channel, no monitor should come any more. So now we can free the buffer.
free(pv[index].data);
}
/* Exit */
ca_context_destroy();
// fclose(fp);
printf("\nDone\n");
return(0);
}
Attachment:
Makefile Attachment:
test.db
| ||||||||||||||
| ANJ, 17 Dec 2015 |
·
Home
·
News
·
About
·
Talk
·
Base
·
Modules
·
Extensions
·
· Distributions · Download · Documents · Links · Licensing · |