:: 게시판
:: 이전 게시판
|
- PGR21 관련된 질문 및 건의는 [건의 게시판]을 이용바랍니다.
- (2013년 3월 이전) 오래된 질문글은 [이전 질문 게시판]에 있습니다. 통합 규정을 준수해 주십시오. (2015.12.25.)
통합규정 1.3 이용안내 인용"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
16/09/23 18:00
포트란을 본격적으로 해본적은 없어서 정확한 답은 못 드리겠고요;;;
SIGSEGV는 대부분 침범하면 안되는 메모리 영역에 접근하려 할 때 나는 에러입니다. 아마도 저 주석처리한 WRITE문의 문법이 틀린게 아닌가 싶습니다.
16/09/23 18:14
죄송합니다. 글을 잘못적었습니다. 주석처리한 부분을 주석처리하면 프로그램이 안돌고, 출력하게하면 프로그램이 실행돼요. 본문 수정했습니다.
16/09/23 18:31
write문이 그렇게 자원을 많이 차지하는지 모르겠는데 굳이 최적화하려고 하지 않고 되는 대로 돌리는 게 문제해결에 빠르지 않을까요.
원인은 서브루틴 안을 봐야 알겠지만, 어쩌면 아웃풋 스트림 버퍼를 비워 줘야 되서 그런 코드가 있는 것인지도 모르겠네요.
16/09/23 18:44
설명드리긴 긴데 돌고있는 프로그램을 살짝살짝 바꾸다 에러가 발생해서요.. 그것도 몇 줄 만지지 않아 이해가 안가고 그런 상황인데요.
그래서 저 에러 메세지에 대해 검색해보다보니 많은 사람들이 겪는 에러인데 딱히 이거다 하고 답을 주는 포스팅은 못봐서 혹시 경험자가 계시면 어떤 에러인지라도 알고싶어서 질문올려봤어요. 말씀해주신것도 한가지 해결책이 될 것 같네요. 감사합니다.
16/09/23 18:46
저도 포트란을 해보지는 않아서 정확한 답이 될지는 모르겠습니다.
위에서 말씀주신 것처럼 Segmentation fault 는 잘못된 메모리 접근에 대한 에러입니다. 잘못된 접근은 여러가지가 있지만, loop를 도는 경우에는 접근할 수 있는 index를 넘어가면서 생기는 경우도 있습니다. 보통 loop으로 array index를 참고하면서 종료 조건을 잘못주어 (max index + 1)을 접근하면 이러한 형태의 문제가 생깁니다. 저라면 WRITE는 주석한 상태에서 1. loop을 벗기고 상수로 고정시킨 상태에서도 같은 문제가 생기는지 2. loop을 2번만 돌도록 강제해도 같은 문제가 생기는지 확인할 것 같습니다. 1.에서 문제가 생기면 내부 로직의 문제이고, 2. 에서 문제가 생기면 index가 문제를 만드는 것으로 볼 수 있으니까요. 그 다음 WRITE를 넣어서 다시 확인하겠습니다. 해결이 될지는 모르겠네요.. 만약 두 상황 모두에서 WRITE를 사용해야지만 문제가 생기지 않는다면, WRITE 내부가 어떻게 구현되어있고, 무슨 영향을 미치는지 찾아보셔야합니다.
16/09/23 19:19
loop문제는 아닌 것 같습니다. 변형시키기 전 그러니까 프로그램이 정상실행될때로 원상복귀시키기가 어렵지 않은데 그때 루프관련쪽은 손대지 않았거든요. write는 그냥 에러를 찾아보려고 넣기시작한거지 프로그램에 영향을 미치진 않아요. 신기한건 write를 넣으니까 안되던 프로그램이 되는것인데.. 어떤 메모리 문제인지 좀 더 알아봐야겠습니다. 감사합니다!!
16/09/23 19:01
그리고 이럴 때는 디버거를 사용하는 것이 좋습니다. 컴파일러는 무엇을 쓰시나요? 컴파일할 때 flag 옵션을 주고, 디버거를 사용하면 어느 서브루틴에서 에러가 나는 지 알 수 있으니 그걸 바탕으로 디버깅하거나 질문하시면 훨씬 쉽게 문제를 해결할 수 있습니다.
16/09/23 19:17
맽랩은 자체 디버거를 사용하는데 포트란은 할 줄 몰라서 code::block라는 걸로 하고 컴파일 및 코딩하고 있어요. 말씀하신대로 flag 옵션으로 디버깅하면 편할텐데란 생각을 하고 있는데... 저 거의 fortran은 책보며 코드 변환하는 정도가 다인데 혹시 추천해주실만한 컴파일러가 있나요?
16/09/23 19:54
인텔에서 학생용 컴파일러를 무료(1년 마다 갱신해야 됩니다만.....)로 배포하고 있습니다.
구글링 해보면 찾을 수 있으실 겁니다.
16/09/23 20:03
포트란은 여러가지 계열이 있는데 제가 하고있는 gfortran으로 짠 프로그램은 인텔계열 포트란 컴파일러에서 호환이 되질 않아요ㅠ
신경써주셔서 감사합니다.
16/09/24 01:19
gfortran은 gdb가 짝이지요. 전 ifort를 많이 쓰긴 했지만 그건 gdb랑은 잘 안 맞더라고요. 인텔은 전용 디버거가 있으니 그게 gdb보다 더 낫긴 하지만 좀 비싸죠. gdb는 기본적으로 gcc를 위한 툴이라, C 관련으로 좀 배워야 할 부분이 있기는 하지만 다른 gui 프로그램과 조합하면 쓸만할 겁니다.
16/09/24 15:42
문제를 벌써 해결하셨는지 모르겠지만, 도움이 될까해서 적어봅니다.
Segmentation fault error가 떴을때 제가 가장 먼저 해보는 것은 컴파일 옵션에 최적화 옵션 -O2 등을 빼고 -fbounds-check 를 넣는 것입니다. (-Wall옵션을 같이 넣어서 워닝 부분도 없애주면 좋습니다!) 많이 하는 실수가 배열크기보다 큰 인덱스를 써서 잘못된 위치의 메모리값을 참조하는 것이기 때문에 보통은 이 옵션으로 문제를 해결합니다. 이것으로 해결되지 않으면, print*, 'after function name()' 을 모든 섭루틴 전후에 적어서 어느부분에서 에러가 나는지를 먼저 확인합니다. 그리고 문제가 발생하는 섭루틴에서 다시 각 변수값이 어떻게 변하는지 printf로 확인합니다. 간단한 테스트 예제를 만들고 본인이 기대하는 값이 계속 유지되는지 또는 잘 바뀌는지 확인합니다. 이 방법이 디버깅의 기본이며 모든 것이라는 생각이 듭니다.. GDB를 활용하면 더욱 좋겠지요. 이 외에 포트란에서는 interface를 잘못 적으면 Segmentation fault error가 발생하는 경우가 있었습니다. c같았으면 컴파일에서 에러날게 포트란에서는 컴파일 에러가 안나는 것입니다. ㅠ 한번은, 섭루틴 변수관련해서 inout을 in으로만 interface쪽에 적어놓았더니 실행시에 문제가 발생했던 것입니다. 그래서 섭루틴을 수정하였다면, interface는 습관적으로 최신 섭루틴의 변수들을 복사해서 갱신해 주는게 좋습니다. 그럼 즐거운 디버깅시간 되세요~ ^^;
16/09/26 13:13
네~ 해결했어요!! 근데 말씀해주신것처럼 서브루틴쪽에 write로 하다가 더 꼬인것같아요. 흠.. 그러니까 어디가 잘못된건지 하나하나 찾아보려고 각 서브루틴쪽에 write를 넣었는데 위에 여러분이 말씀해주신것처럼 서브루틴쪽에 제가 잘못한게 있었어요. 차라리 write를 안하고 코딩쪽을 살펴봤으면 될걸 아 왜 이런 문제가 생기는지 이해안가네 하며 며칠을 보냈네요ㅠㅠ
근데 정말 궁금한건 그렇게 잘못된 부분이 있었는데 왜 write를 루프마다 실행시키면 프로그램이 돌아갔는지 신기하네요:D 디버깅은 했는데 정말 궁금한게 오히려 생겼어요. 말씀해주신 것들 잘 스크랩해뒀다가 다음에 디버깅할때 참고하겠습니다. 감사합니다!!
|