변수 값이 변합니다???
글쓴이: uamyd5279 / 작성시간: 월, 2005/06/27 - 11:58오전
이게 원래 변하지 말아야 하는데 값이 변하네요..
qcnt값이요.. 그냥 한 3000이 넘어 버립니다.
어디가 잘못된건지 찾을 수가 없네요...ㅜ.ㅜ
<메인> ... qcnt = dGet_MSQ_key(); if( qcnt < 0 ){ dAppLog( LOG_CRI,"Failed in dGet_MSQ_key" ); exit(0); } memset( &stSub, 0x00, sizeof( st_Sub_AType2 ) ); while(1) { tNow = time(NULL); if(tNow >= tPast + STS_CHECK_LIMIT) { dMax = 0; for(i = 0; i < qcnt; i++) { dMsq_id = msgget(arMSQ_key[i], 0666|IPC_CREAT|IPC_EXCL); if( dMsq_id < 0 ){ if( errno == EEXIST ){ dMsq_id = msgget(arMSQ_key[i], 0); if(dMsq_id < 0) { dAppLog(LOG_DEBUG, "%d Failed in msgget MSQ_KEY=[%s:%d], [%s:%d]", i, arMSQ_Name[i],arMSQ_key[i],strerror(errno),errno); continue; } } else{ dAppLog(LOG_INFO, "%d Failed in msgget MSQ_KEY=[%s:%d], [%s:%d]", i, arMSQ_Name[i],arMSQ_key[i],strerror(errno),errno); continue; } } else{ dAppLog(LOG_DEBUG,"%d ERROR first used here MSQ_KEY=[%s:%d]", i, arMSQ_Name[i],arMSQ_key[i]); dRet = msgctl(dMsq_id, IPC_RMID, 0 ); if( dRet < 0 ){ dAppLog(LOG_CRI,"Failed in delete_MSGQ =[%s:%d]",arMSQ_Name[i], arMSQ_key[i]); exit(1); } continue; } dRet = msgctl(dMsq_id, IPC_STAT, &buf); if(dRet < 0) { dAppLog(LOG_WARN, "Failed in msgctl MSQ_KEY=[%s(%d)], [%s]", arMSQ_Name[i],arMSQ_key[i],strerror(errno)); continue; } check = ((buf.msg_qnum)*100.0)/(maxofnum); if(dMax < check * 100.0){ dMax = check * 100.0; } if(check > 0) { dAppLog(LOG_DEBUG, "MSQ_KEY=[%s(%5d)], [%d]/[%5.2f]=[%5.2f]", arMSQ_Name[i],arMSQ_key[i], buf.msg_qnum, maxofnum, check); } if(check > 90) { dAppLog(LOG_CRI, "MSQ_KEY=[%s(%d)], Over 90!!!!", arMSQ_Name[i],arMSQ_key[i]); for(i = 0; i < maxofnum * 0.1; i++) { if((msgrcv(dMsq_id,(st_MsgQ *)&stMsg, sizeof(st_MsgQ) - sizeof(long), 0, IPC_NOWAIT)) < 0) { dRet = msgctl(dMsq_id, IPC_RMID, &buf); if(dRet < 0) { dAppLog(LOG_CRI, "Failed in remove MSQ!! MSQ_KEY=[%s(%d)], [%s]", arMSQ_Name[i],arMSQ_key[i],strerror(errno)); continue; } } } } } tPast = tNow; } usleep(10); }
int dGet_MSQ_key() { FILE *fa; char szBuf[1024]; int lidx; int qcnt; fa = fopen( "./QLIST", "r" ); if( fa == NULL ){ dAppLog(LOG_CRI,"dGet_MSQ_key : %s File open cannat [%s]", DATA_HOME"RsrcList", strerror(errno) ); return -1; } qcnt = lidx = 0; while( fgets( szBuf, 1024, fa ) != NULL ){ lidx++; if( szBuf[0] != '#' ){ dAppLog(LOG_CRI,"dGet_MSQ_key : %s File [%d] row Format Unsuitable", DATA_HOME"RsrcList", lidx ); fclose( fa ); return -2; } if( szBuf[1] == '#' ) continue; else if( szBuf[1] == 'E' ) break; else if( szBuf[1] == 'Q' ){ sscanf( &szBuf[2], "%s %d",arMSQ_Name[qcnt], &arMSQ_key[qcnt] ); qcnt++; } else{ dAppLog(LOG_CRI,"dGet_MSQ_key : Unvalid File Format[%s]", DATA_HOME"RsrcList" ); return -1; } } return qcnt; }/* Get message key */
메세지큐 파일은 다음과 같습니다.
################################## ## 1. Key of Message Queue ## ## Key_label Key_value ## ## /* NTAM */ ## #Q S_MSGQ_TMF_TOT 3000 ## #Q S_MSGQ_CHSMD 3010 #Q S_MSGQ_DBMNG 3011 #Q S_MSGQ_ALMD 3012 #Q S_MSGQ_COND 3013 #Q S_MSGQ_MMCD 3014 #Q S_MSGQ_FSTATD 3015 ## #E
메인에서 왜 qcnt값이 변하는지 알 수가 없습니다...ㅜ.ㅜ
도ㅇ
Forums:
[quote]qcnt++;[/quote] 함수에서 증가시키시고 리
함수에서 증가시키시고 리턴 받으 시던데요
입력 화일에
이 조건이 3000이 넘나요 ???
---------------------------------------
blog : http://myohan.egloos.com
[quote]이 조건이 3000이 넘나요 ???[/quote]
안넘습니다. MAX값이 64이며, 실제로는 43~5개에 불과합니다.
자세한 설명을 제가 적지 않았는데요..
증상이 dbx로 잡아보면
어느 순간
3000개 이상 증가를 합니다.
qcnt값을 참조하는 부분은 한 부분 밖에 없는데, 그나마 그것도 참조하는 것일 뿐인데.
왜 값이 변하는 것인지 알 수가 없네요...
"For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life"-John 3:16
이 부분이 의심이 갑니다.[code:1] qcnt = lid
이 부분이 의심이 갑니다.
대신
으로 변경해 보세요.
또한
qcnt = dGet_MSQ_key();
반환하는 Type과 qcnt의 Type이 같은지도 확인해 보시는 것이 좋겠습니다.
[quote="lovewar"]이 부분이 의심이 갑니다.[code
많은 관심 감사드립니다. ㅜ.ㅜ
하지만, 제가 궁금한건 중간에 왜 qcnt값이 변하느냐 죠.
또 언제 변하는지...알길이 없네요..
참조하지 않는데도, 값이 변하는 경험 있으신분 안계신가요 ㅜ.ㅜ
"For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life"-John 3:16
변수 선언하는 <메인> 부분qcnt근처를 보여
변수 선언하는 <메인> 부분
qcnt
근처를 보여 주실순 없나요?
그리고 qcnt가 두군데 있는데. 어느 부분을 말씀하시는지 모르겠군요.
고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"
main 에서 qcnt 보다 먼저 선언된 변수에서 오버플로가 일어나는지
main 에서 qcnt 보다 먼저 선언된 변수에서 오버플로가 일어나는지 확인해보세요.
예를 들면,
memset( &stSub, 0x00, sizeof( st_Sub_AType2 ) );
같은 곳에서 크기 이상으로 덮어쓸 경우 오류가 날 수 있습니다.
---
http://coolengineer.com
[quote="fehead"]변수 선언하는 <메인> 부분
선언부입니다. st_Sub_AType2 는 저희 시스템에서 사용하는 메세지큐 구조체구요.
qcnt 변수가 사용된 부분은 위의 소스에도 나와 있는데, 딱 두군데 밖에 없습니다.
이 부분 하구요( 파일에서 메세지큐를 읽는 부분..함수는 위에 전 소스 있습니다. ) 이렇게 for문에서 하나 있습니다."For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life"-John 3:16
[quote="pynoos"]main 에서 qcnt 보다 먼저 선언된 변
다시한번 깊은 관심 감사드립니다. 정말 고맙습니다.
아직 고치지는 못했지만,...그래도 희망이 보이네요.
이게 또 애매한 것이...
에러가 나는 시점이 언제인지 도저히 알길이....없네요.
지금 현재 4시간째 시뮬레이션 중인데...이번에는 또 에러가 안 뜨네요.
memset...문제가 없을 듯 합니다.
왜냐면... while문이 시작하는 시점에서 qcnt의 값은 항상 바르거든요. QLIST에서 읽어들인 que의 개수와 일치합니다.
하지만, 어느 시점인가...에러가 날 때는...값이 3000단위로 올라가 버립니다. 두 세번 발생했는데, 그 값이 또 무슨 의미가 있는것인지...
ㅜ.ㅜ 어찌할꼬..
"For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life"-John 3:16
아! 그리고, 관련은 없지만,[code:1] else&#
아! 그리고, 관련은 없지만,
에서 return하기전에 fclose 안하셨더군요.
---
http://coolengineer.com
메시지큐 파일의 내용에 3000 같은 숫자가 나오는 것과 관련이 있지 않
메시지큐 파일의 내용에 3000 같은 숫자가 나오는 것과 관련이 있지 않을까요?
제 생각엔 스택이 깨진 것으로 보이네요. 이쪽 함수만 보지 마시고 msgget() 같은
것도 같이 보세요. 디버거로 따라가면 금방 잡을 수 있을 것 같은데...
pynoos님이 말씀하신 것이 문제일것 같은데.stSub 을 쓰는
pynoos님이 말씀하신 것이 문제일것 같은데.
stSub 을 쓰는데서 overflow낼 가능성이 제일 높아 보임니다.
고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"
조건부 브레이크 포인트를 이용해보세요.예를 들면[code:1]$
조건부 브레이크 포인트를 이용해보세요.
예를 들면
위의 경우 i 값이 10보다 크면 멈추도록하는 것입니다.
---
http://coolengineer.com
[quote="fehead"]pynoos님이 말씀하신 것이 문제일것 같은
컴파일 다시하고 대기중입니다.
하지만...이건 아닐 것 같습니다. 왜냐면...
memset으로 했을 경우 0x00값이 셋팅이 되는데 그렇다면
while문 시작전에 이미 qcnt변수의 값은 바뀌어야 정상아닌가요...
그런데 문제는 정상적으로 작동을 하다가...갑자기 바뀐다는 데 있습니다.
제가 이 곳에 코드를 올린 것은, 코드 상에 문제가 있나 해서 입니다.
제 눈에는 도저히 별다른 이상이 없거든요? 물론 제가 100퍼센트 만든 것이 아니기 때문에...자신은 또 없어지네요 ㅜ.ㅜ
하여간 대기중입니다....이번엔 또 6시간째 에러가 없네요...
궁금한것이 있는데요,
외부 다른 프로세스에 의해서도 변수값이 변할 수가 있을까요? 물리적으로야 그럴 수 있을 듯 하지만서도, 그 정도는 하드웨어에서 당연히 안될 것 같다는 생각도 들긴 하지만....하여간에 벼라별 생각이 다듭니다. ㅜ.ㅜ
"For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life"-John 3:16
제가 말씀 드린건 memset이 아니라.stSub변수를 건드리는
제가 말씀 드린건 memset이 아니라.
stSub변수를 건드리는 부분입니다. :)
예.
memcpy(&stSub, buf, sizeof(stSub));
strncpy(stSub.str, buf, sizeof(buf));
stSub.str[100] = 0xBB;
등등..
고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"
완전히 예상치도 못한 전혀 다른 곳에서 생기는 문제일수도 있겠지요. -_
완전히 예상치도 못한 전혀 다른 곳에서 생기는 문제일수도 있겠지요. -_-;
잘못된 포인터사용 혹은 오버플로우가 예측 가능한 범위 내에서 생기는 게 아니라는......
qcnt와는 전혀 관련없는, 더불어 stSub과도 별 관련없는 어딘가가 문제일 수도 있습니다.
pynoos님께서 올려주신 방법처럼, 변수의 값을 이용한 조건부 브레이크가 원인파악에 도움이 될 듯 합니다.
여기에서 문제가 될 가능성은, tNow 값을 변경하는 작업에서 오버플로우가 발생하거나, stSub값을 변경하는 작업에서 오버플로우 내지는 잘못된 포인터 사용..이 문제가 될 수 있겠지만, 이런 가능성에 대해 분석하고 디버깅 해 봐도 별다른 소득이 없다면, 해당 함수에서 호출되는 모든 함수들이 범인일 가능성으로 확대해야 합니다. 그냥 로컬 변수의 값을 변경하는 것 조차도 스택이 깨지면서 혹은 포인터를 잘못 쓰면서 우연히 qcnt가 위치한 스택의 값을 변경해버릴 수도 있거든요. 거기서도 못 찾으면, 모든 함수를 대상으로 의심을 해 봐야 합니다. -_-;
그저...... 인내심을 가지고 꾸준히 디버깅을 하는 방법 외에는...... ;
아니면 전체적으로 소스레벨의 분석을......( 포인터 연산에서 정상적인 포인터의 범위인지 검사하지 않고 그냥 쓰는 부분이 있다거나, 스택 오버 플로우가 날 수 있는 부분이 있다거나...... )
이런 류의 버그들은, 운 좋으면(?) 일정한 조건으로 재현이 가능하지만, 운 없으면 정말 자기 맘대로(......) 재현이 됩니다. 개인적인 경험으로는, 후자의 경우는 메모리의 동적 할당과 관계가 있을 가능성이 크다는 정도의 힌트가 된다고도 볼 수 있을까요...... 전자는 스택쪽인 가능성이 좀 더 클테고...... -_-; 여하튼 주금이죠......
꼭 잡으시길......
오버플로어가 아닐까 싶네요..
pynoos 님 의견에 한표..
리포트 작성때 어떤 변수가 이유없이 값이 변하더군요. 절대로 그 값이 나올수 없는데.. 내공부족으로 디버깅 툴은 않쓰고, printf문으로도 찍어보고, 눈으로 소스코드를 꼼꼼히 훌터 보았는데, 정답은 배열크기를 오버해서 저장한것이었습니다. 서로 아무런 연관없는 배열과 변수였는데... "어떻게 이럴수가" 라는 .. . 잡담이 되었네용 ;;
-------------------- 절취선 --
행복하세요:)
Re: 오버플로어가 아닐까 싶네요..
잘 알겠습니다.
역시...글을 올리는 곳은 KLDP가 제일 기분이 좋군요.
IBMMANIA쪽도 괜찮았는데...이 쪽만큼의 답변은...^^;;;
하나씩 뒤져봐야겠네요..언제 등장할는지는 모르지만 ㅜ.ㅡ
답변해 주신 분들께 진심으로 감사드립니다. 고맙습니다.
제가 이 버그를 때려 잡아야, 여러 답변해주신분들의 속이 시원해지시겠죠? 꼭 잡겠습니다. ^^
해결했습니다.역시 문제는 오버플로우 때문이었습니다.해당 소스의
해결했습니다.
역시 문제는 오버플로우 때문이었습니다.
해당 소스의 다른 함수에서 특정 변수( 스트링 )이름을 저장할때...
16자의 제한을 넘어서 24자를 저장했더니....그 변수가 영향을 받더군요...
로그로 확인을 했는데....왜 몰랐을까요...ㅜ.ㅜ
머리 나쁘면...몸이 고생한다는 진리는 어디가나 적용 되는군요.
관심 가져 주신 분들 가슴 깊이 감사드립니다.
"For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life"-John 3:16
축하 드립나다 :)
축하 드립나다 :)
고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"
댓글 달기