GPS 데이터를 다루는 개발을 진행하는 중에 세그멘테이션 오류
라는 불친절한 메시지와 함께
개발이 중단되고 큰 혼란에 빠진 상황이었다. 세그멘테이션 오류
는 아래와 같은 상황에 발생할 수 있다.
Struct
구조체에 담아 보관하고, 라이브러리로 컴파일한다.while
문을 통해 계속 요청하는데 5~10분 동안은 데이터가 잘 넘어오는데 무조건 세그멘테이션 오류
라는 불친절한 메시지와 함께 실행이 종료되었다.printf()
로 에러가 발생하는 지점을 확인하고 수정해주었다.파일 쓰기
기능이 있어서 세그멘테이션 오류가 발생했고파일 쓰기
부분을 삭제해도 에러가 발생했는데 uart_open
하고 닫지 않아 발생해서 닫는 코드를 추가했다.// c++
// 앞부분(데이터 Parsing 등등) 생략
// 아래 process 함수가 Python 코드에서 반복문으로 계속 요청되는 코드이다.
EXPORT void process(void* st)
{
checker = 3;
unsigned char r_buf[1024];// 여기부터 unsigned char 로 수정
bzero(r_buf,1024);
memset(chrBuf, 0x00, 2000);
fd = uart_open(fd,"/dev/ttyUSB6");/*/dev/ttyUSB 경로 설정 */
if(fd == -1)
{
fprintf(stderr,"uart_open error\n");
exit(EXIT_FAILURE);
}
if(uart_set(fd,BAUD,8,'N',1) == -1)
{
fprintf(stderr,"uart set failed!\n");
exit(EXIT_FAILURE);
}
// ** 이 부분이 파일을 열어서 해당 데이터를 저장하기 위한 코드인데 삭제해줘야한다. **//
FILE *fp;
fp = fopen("Record.txt","w");
// ** 끝 **//
while(1)
{
ret = recv_data(fd,r_buf,44);
if(ret == -1)
{
fprintf(stderr,"uart read failed!\n");
exit(EXIT_FAILURE);
}
for (int i=0;i<ret;i++)
{
// ** 이 부분 위에서 정의한 파일에 데이터를 기록하는 코드인데 삭제해줘야한다. **//
fprintf(fp,"%2X ",r_buf[i]);
// ** 끝 **//
ParseData(r_buf[i]);
// 1216 체크해서 out
if(checker == 1){
checker=0;
break;
}
}
if(checker == 0){break;}
}
// 1216 struct 값 입력 및 반환
printf("구조체 전달!\n");
Struct temp = {yy,mm,dd,hh,mi,ss,ms,ax,ay,az,t,wx,wy,wz,roll,pitch,yaw,mx,my,mz,press,h,lon_final,lat_final,gh,gy,gv,q0,q1,q2,q3,sn,pdop,hdop,vdop};
*((Struct*)st) = temp;
세그멘테이션 오류
가 발생했다.파일 쓰기
부분에서 생기는 문제로 계속해서 파일을 써서 발생했다.uart_open
에 대한 부분을 제대로 종료해주지 않아서 추가 에러가 발생했다. EXPORT void process(void* st)
{
try{
checker = 3;
unsigned char r_buf[44];// 여기부터 unsigned char 로 수정
bzero(r_buf,44);
memset(chrBuf, 0x00, 2000);
fd = uart_open(fd,"/dev/ttyUSB6");/*/dev/ttyUSB 경로 설정 */
if(fd == -1)
{
fprintf(stderr,"uart_open error\n");
exit(EXIT_FAILURE);
}
if(uart_set(fd,BAUD,8,'N',1) == -1)
{
fprintf(stderr,"uart set failed!\n");
exit(EXIT_FAILURE);
}
while(1)
{
ret = recv_data(fd,r_buf,sizeof(r_buf));
if(ret == -1)
{
fprintf(stderr,"uart read failed!\n");
exit(EXIT_FAILURE);
}
for (int i=0;i<ret;i++)
{
ParseData(r_buf[i]);
if(checker == 1){
checker=0;
break;
}
}
if(checker == 0){break;}
}
// ** uart 를 오픈했으면 닫아줘야한다 **//
uart_close(fd);
// ** 끝 **//
printf("구조체 전달!\n");
if (st != NULL) { // 추가된 NULL 체크
Struct temp = { yy, mm, dd, hh, mi, ss, ms, ax, ay, az, t, wx, wy, wz, roll, pitch, yaw, mx, my, mz, press, h, lon_final, lat_final, gh, gy, gv, q0, q1, q2, q3, sn, pdop, hdop, vdop };
*((Struct*)st) = temp;
}
} catch (std::exception& e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
exit(1);
}
}
while
문으로 반복을 돌릴 때 에러가 발생하는 경우가 많다. 미연에 방지하기 위해 디버깅을 잘해줘야한다.uart
같은 통신을 사용할 때 open 했으면 꼭 close 도 꼭 해주자.