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
·
Base
·
Modules
·
Extensions
·
Distributions
·
Download
·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing · |