gdb 사용시 전역변수의 포인터값을 찍어볼려면 도대체 어떻게해야하나요?
글쓴이: gloomyr / 작성시간: 월, 2010/03/29 - 10:22오전
데이터 값이 중간에 깨져서 그원인을 지금 일주일재 찾고있는 개발자입니다.
원래 gdb가 전역변수의 포인터 값의 데이터값에는 접근을 못하나요??
예를 들어서
typedef struct test
{
int aa;
}_test;
_test * ttt;
저런식으로 선언하고 쓰고있다면
*ttt의 값이 중간에 값이 깨져버립니다.
원인을 찾을려고 gdb로 값을 깨지는 순간을 캐치할려고하는데
p ttt ----> 0xxxxxx 이런 주소가 나오고
p * ttt ----> can not access memory....
p ttt->aa ----> can not access.....
p (*ttt).aa ----> can not access.....
당최.. 중간에 값은 할당하고 다 있습니다.
프린트 에프로 찍으면 값은 잘나오고요..
gdb로 전역변수의 포인터값을 찍을려면 어떻게 해야하난요??
Forums:
...
흠 그런 에러는 포인터가 이미 깨져서 접근할 수 없는 이상한 주소를 가리키고 있을 때 나오는 에러인데요.
정말로 그런 상황에서 printf로 찍으면 제대로 나오나요?
네 0xxxxx <-- 요거는
네 0xxxxx <-- 요거는 그냥 x라고적어논거에요
정상적으로 전역공간 10xxxxx 10으로 시작하는 주소로 시작하는 공간입니다.
printf("%d",ttt->aa); 아주 잘찍힙니다.
혹시, *ttt 바로 전에
혹시, *ttt 바로 전에 선언된 전역변수에서 overflow 되서 쓰여진건 아닌지요?
삽질의 대마왕...
삽질의 대마왕...
overflow 됬다하심은
overflow 됬다하심은 설마 똑같은 변수를 선언햇다고 하심이...
그런건 아니라~~
이변수는 여기저기서 아주 많이 쓰입니다.
다른곳에서는 문제업습니다.
흠 어디에서 데이터가 깨지냐고하면
record & replay 입니다.
단순히 저장했다가 다시 리플레이하는겁니다.
혹시 파일 저장과 로드가 잘못되었나해서 수차례 확인해보앗지만
저장과 로드시에는 무제가 업습니다.
로드한 모듈에서 지나서
태스크 프로세스를 지나서
웨이트 포 틱 함수로 동기화를 거친다음에
어느순간 전연변수의 데이터가 깨집니다.
환장하겟군요..
ㅠㅜ
로드한 모듈에서
로드한 모듈에서 지나서
태스크 프로세스를 지나서
웨이트 포 틱 함수로 동기화를 거친다음에
어느순간 전연변수의 데이터가 깨집니다.
----------------------------------------------------
그 어느순간이란게 어딘가요?
랜덤하게 발생하면 패스;;
그리고 overflow라는게 할당한 메모리보다 더 많은 데이타를 저장할때 발생하는거니까
구조체에 저장할때 값도 알아보시면 좋을것같아요~
흘러가고있는 지금 이 시간에 충실하자.
gdb보다는 valgrind 같은
gdb보다는 valgrind 같은 메모리 관련 도구를 쓰는 것이 적합할듯합니다.
-----
오늘 나의 취미는 끝없는, 끝없는 인내다. 1973 法頂
-----
오늘 나의 취미는 끝없는, 끝없는 인내다. 1973 法頂
환장할 노릇 이네요..
이게 도대체 어떻게 된 노릇일가요.
원래는 문제가 파일데이터가 깨지는것이였습니다. 하지만 아무리 봐도 로직상 문제가 보이지 않아서
kldp 에서 여기저기 눈팅하다가 알게된 사실이 오버플로우..
거기에 주안점을 두고 아무리 봐도.. 알수가 없기에
혹시 함수의 호출 순서를 바꾸어 보았습니다.
예전에 A 라는 함수의 데이터가 깨졌었다고 하면
실행 흐름은 C EF B EF A 이런 식입니다.
그래서 요녀석을 A EF B EF C 이렇게 바꾸어 보았습니다...
잘됩니다....
값도 깨지지 않습니다.
하지만.. 잘되던 C의 로직이 무언가 문제가 발생햇습니다. 잘나오던화면이 번쩍번쩐한다던지..
흠.. 무엇이 문제 일까요.. 어디선가 오버플로가 발생해서 다른곳의 갑을 다 덮어버리는 것일가요..
집에좀 보내주세요.
코드 양이 많지 않다면 ..
코드 양이 많지 않다면 어느정도의 실제 코드를 올려주시는 것이
가장 빠른 해결점을 찾을 듯 합니다.
잘 아시겠지만 메모리 할당, 해제, 경계에 관한 실수가 있지 않나 생각 됩니다.
gdb watch는 써보셨나요?
gdb에서 "watch ttt"라고 설정하시고 실행을 하면 ttt의 값이 변하는 순간 브레이크가 걸립니다.
누가 실수로 값을 덮어쓰는 거면 이걸로 쉽게(?) 잡으실 수 있을 겁니다.
그리고 설명을 봐서는 분명 buffer overflow 같은 게 있는 것 같은데 valgrind로 돌려보시면 많은 경우 문제를 잡을 수 있습니다.
* 아 노파심에 쓰자면 컴파일할 때 warning은 다 켜고 하셨죠?
gdb에서 "watch ttt"라고
gdb에서 "watch ttt"라고 설정하시고 실행을 하면 ttt의 값이 변하는 순간 브레이크가 걸립니다
->전역벼수의 포인터변수기 때문에 watch ttt --> 처음 메모리 할당할대 주소가 0x00 에서 0x12xxx 으로 할당될때만 바뀌고 그담엔 잠잠
-> watch *ttt --> can not access momory.....
그러니깐 전역변수의 * 변수(구조체)의 값을 확인할려면 gdb 상에선 방법이 없나요??
유저 커맨드 디파인이나 함수를 짤수 박에 없는건가요??
로직이 어느 특정상황이 항상 일정하게 발생하는게 아니라서 참 대략 난감 하네요 ㅠㅜ
valgrind 결과는 나중에 올려드리겠습니다.
결과만봐서는 메모리 렉이 엄청난거같은데 말입니다.
댓글 달기