address 를 가지고 실제 코드를 찾아가는 방법은 objdump 를 쓰시면 됩니다.
문제가 발생한 elf 파일과 소스가 있다면,
> objdump -S --start-address=0x######## --stop-address=0x########
이런 식으로 address range를 주어서 해당 address 범위의 소스를 찾아낼수 있답니다.
임베디드 환경에서 코딩중인데, 실행 시 죽었을 때 죽은 위치(address)는 얻었습니다만, 실제 제가 짠 코드 어디서 segmentation fault를 유발 시켰는지 알수가 없었습니다.
그래서 해당 address를 가지고 실제 제가 짠 코드의 위치를 알고자 했던 것인데요..
위 objdump를 사용해 이 위치를 알 수 있는 것인지요..혹 불가능 하다면 어떤 다른 방법이 있을까요..?
댓글이 없네요..
아시는분 답변 부탁드립니다.
signal handler에서
signal handler에서 ucontext_t parameter를 받지 않나요?
좀더 상세하게 설명해 주실 수 있을까요?
내용을 정확하게 이해하지 못했습니다. 죄송합니다만, 좀더 상세하게 설명 부탁드립니다..
objdump 를 쓰시면 됩니다.
address 를 가지고 실제 코드를 찾아가는 방법은 objdump 를 쓰시면 됩니다.
문제가 발생한 elf 파일과 소스가 있다면,
> objdump -S --start-address=0x######## --stop-address=0x########
이런 식으로 address range를 주어서 해당 address 범위의 소스를 찾아낼수 있답니다.
질문하신 분은...
질문하신 분은... 아마도 커널레벨에서 추적하고 싶으신 모양입니다.
목적은 이렇습니다.
임베디드 환경에서 코딩중인데, 실행 시 죽었을 때 죽은 위치(address)는 얻었습니다만, 실제 제가 짠 코드 어디서 segmentation fault를 유발 시켰는지 알수가 없었습니다.
그래서 해당 address를 가지고 실제 제가 짠 코드의 위치를 알고자 했던 것인데요..
위 objdump를 사용해 이 위치를 알 수 있는 것인지요..혹 불가능 하다면 어떤 다른 방법이 있을까요..?
흠... cross gcc 로
흠...
cross gcc 로 컴팔할때 -g -O0옵션을 주고 컴팔해서
타겟에서 실행하기 전에 ulimit -c unlimited 실행해서 core dump를 만들게 해주구요...
프로그램 실행해서 core dump가 생기면... gdb로 gdb my.exec.program core 실행해서 보면... 친절히 소스레벨 몇번째줄에서 죽었는지 나올껍니다...
예전에 듣기론 cross gdb로는 target의 core 파일을 분석할 수 없다고 들었는데...(어디 보니 최신버전 gdb에선 해결했다는 소문도...) cross gdb로 작업하시지 마시고 native gdb를 만들어서 사용하세요...
native gdb를 만들려면... 삽질이 좀 필요한데 먼저 cross gcc로 native gcc를 만든 후에 native gcc로 native gdb를 만들었던거 같은데...
혹시 개발환경을 어디서 제공받아쓰신다면 제공해주는 쪽에서 native gdb, native gcc등은 제공해줄껍니다...
한가지 더 질문 드립니다.
일단 위 방법 중 objdump를 사용한 방법으로 어느 위치에서 fault가 발생 하였는지는 확인 하였습니다.
그런데,
main()
{
char *p;
sprintf(p,"%s","HAHAHA");
}
와 같이 coding한 후 돌렸을 때
/lib/ld-linux.so.2속의 위치를 알려주네요..
즉 sprintf의 내부 어딘가에서 죽을 때 그 위치를 알려준다는 것이죠.
하지만, 제가 알고 싶은것은 'main 함수 내의 error발생 위치 입니다'
이 위치를 알기 위한 방법이 있을까요?
짧은 제 생각엔, call stack을 뒤져야 가능 할 것 같은데, 전혀 방법을 모르겠습니다.
혹은 죽을 때 memory dump가 일어나고 죽는다고 하였는데, 이 dump를 분석하면 가능하지 않을까요?
이 dump를 사용해 분석하는 방법이 있다면 알려주셨으면 합니다. dump의 저장위치나, 보는법 같은, 어떤 내용이라도 괜찮습니다.
답변 부탁드립니다.
음..쉬운 질문은
음..쉬운 질문은 아니지만, 공부가 필요한 부분입니다.
뉴스그룹에도 보면 간간히 sybase 엔진 개발자들도 이런 질문들을 하곤 합니다. -_-;;
StackFrame에 대해 공부를 하시구요, 그러면 이전 StackFrame으로 찾아가는 방법에 대해서
이해하실 수 있습니다.
무엇을 원하시는지 저는 정확히 알고 있으니, 이렇게 공부를 먼저 하시는 게 좋을 것 같네요.
참고로, mpatrol 과 같은 소스에서 stack backtrace에 대한 것을 찾으실 수 있습니다.
대략적으로
Segmentation Fault가 발생하면, 해당 시그널 핸들러가 불려집니다.
이 핸들러는 직접 설정하셔야지요.
그러면, 그 핸들러에서 ucontext 정보를 얻어서 그 중의 멤버 하나가 정확하게
에러가 발생한 어드레스를 가리킵니다.
그리고, 현재의 스택 포인터와 이전의 스택 포인터를 가진 스택 프레임 포인터 값을 구해서
차례로 이전 스택까지 내려가시면 됩니다.
건승하시길.
고도의 추상화, 극도의 구체화, 에디슨을 그리워하다.
고도의 추상화, 극도의 구체화, 에디슨을 그리워하다.
답변 감사합니다.
해당 내용을 공부할 수 있는 site나 정보 있으시면 공유 부탁드립니다.
쉽지 않은 작업일 줄 알고 있습니다만, 한번 공부해 보고 싶네요.
답변 감사드립니다.
-_-ㅋ
의심가는 지역에 printf("%d ",cnt++); 를 집어 넣으셔요 -_-
'급한' 프로젝트 라면요.
물론 디버거 쓰는게 최고지만
제 임베디드 보드는 메모리가 마니 부족해서 objdump 나 gdb 를 미처 넣지 못했어서
썻던 가슴시린 방법입니다..
댓글 달기