-
ROS gdb, valgrind 디버깅ROS 2023. 3. 1. 15:57반응형
ROS 패키지를 gdb와 valgrind로 디버깅하는 방법에 대해 기록한다.
빌드 타입 옵션을 debug로 설정한 상태에서 빌드해야 보다 정확한 위치를 파악할 수 있다.
e.g. catkin_make -DCMAKE_BUILD_TYPE=debug
rosrun, roslaunch 커맨드 실행 시 옵션으로 붙여주거나, 아예 launch 파일을 수정한 후 실행하는 방법이 있다.
1. roslaunch 커맨드 실행
커맨드에 prefix 옵션을 붙여준다.
e.g.
roslaunch --prefix 'gdb -ex run --args' my_package my_launch.launch roslaunch --prefix 'valgrind' my_package my_launch.launch
2. rosrun 커맨드 실행
마찬가지로 커맨드에 prefix 옵션을 붙여준다.
e.g.
rosrun --prefix 'gdb -ex run --args' my_package my_node rosrun --prefix 'valgrind' my_package my_node
3. launch 파일 수정
launch 파일 내 노드 부분에 launch-prefix를 추가해준다.
e.g.
<node pkg="my_package" exec="my_node" output="screen" launch-prefix="gdb -ex run --args"> ... </node>
gdb 커맨드
run
프로그램 시작
bt full / backtrace full
함수 호출 스택 출력
up / down
호출 스택 위/아래로 이동
frame
호출 스택 특정 프레임(#..)으로 이동
e.g. frame 14
print {variable}
변수 값 출력
e.g. print myVariable
break {function_name}
특정 함수에 중단점 설정
e.g. break myFunction
break {file_name}:{line_number}
특정 파일 특정 줄에 중단점 설정
e.g. break my_code.cpp:728
continue
다음 중단점까지 계속 실행
next
한 줄씩 코드 실행 (함수 호출 한 번에 수행)
step
함수 내부로 들어가서 한 줄씩 코드 실행
Thread 170 "my_test" received signal SIGABRT, Aborted. [Switching to Thread 0x7ffe6ffaf (LWP 7268)] __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 51 ../sysdeps/unix/sysv/linux/raise.c: 그런 파일이나 디렉터리가 없습니다. (gdb) bt full #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 ... #1 0x00007ffff3a127f1 in __GI_abort () at abort.c:79 ... #2 0x00007ffff3a5b837 in __libc_message (action=action@entry=do_abort, ...
세그 폴트가 발생했을 때 위와 같이 호출 스택(#..)을 확인할 수 있다.
valgrind 옵션
verbose
자세히 출력
e.g. -v
tool
memcheck(기본 툴, 메모리 오류/누수 검사), callgrind(함수 호출 정보 분석), helgrind(스레드 동기화 문제 분석)
e.g. --tool=callgrind, --tool=helgrind
leak-check
메모리 누수 검사. yes(메모리 누수 여부 확인), full(소스 파일명, 라인 위치 상세하게 출력)
e.g. --leak-check=full
show-reachable
프로그램 종료될 때 해제되지 않은 메모리 영역 있을 경우 보고
e.g. --show-reachable=yes
track-origins
초기화되지 않은 메모리 접근 시 추적
e.g. --track-origins=yes
track-children
서브 프로세스까지 추적. 멀티 프로세스에서 사용할 것.
e.g. --track-children=yes
log-file
출력 결과 파일로 저장. 절대 경로 안 넣으면 pwd에 저장됨.
e.g. --log-file=/home/candyz/valgrind-log.txt
valgrind 옵션 적용 예시
launch-prefix="valgrind -v --leak-check=full --trace-children=yes --track-origins=yes --log-file=/home/candyz/valgrind_log.txt"
메모리 누수 정보
definitely lost
더 이상 참조할 수 없는 메모리 블록 => 누수된 부분 찾아서 해제해야
indirectly lost포인터로 접근 가능한 메모리인데 루트 포인터가 definitely lost 상태일 경우 => definitely lost를 해결해야
possibly lost메모리 할당 추적은 안 되는데 참조는 가능 => 포인터 주소값 확인
still reachable접근은 가능한데 프로그램 종료될 때까지 해제가 안 됨 => 아무것도 안 해도 되긴 하는데 웬만하면 free/delete 해주기.
발생 가능한 에러
invalid read
할당 안 된 영역 / 이미 해제된 메모리에 접근하는 경우 e.g. out of index
invalid write
할당 안 된 영역 / 이미 해제된 영역에 데이터 쓰려고 할 때
invalid free
할당 안 된 포인터 해제 / 이중 해제
conditional jump or move depends on uninitialized value
조건문에 초기화 안 한 변수 사용
access not within mapped region
잘못된 메모리 접근
e.g. null 포인터 접근
process terminating with default action of signal 11 (SIGSEGV)
세그폴트
* valgrind 실행 시 다음과 같은 메시지가 나오면 메모리(8MB) 초과로 valgrind에 로드할 수 없는 것이라고 함.
brk segment overflow in thread ...
콜백 함수도 호출 안 되는 경우가 있으므로 걍 gdb로 보자.
기타 옵션
https://valgrind.org/docs/manual/manual-core.html
반응형'ROS' 카테고리의 다른 글
ROS1, ROS2 동시 사용 (0) 2024.11.12 osm_cartography - RViz에 오픈스트리트맵(OSM) 데이터 시각화하기 (0) 2022.12.25 터틀봇3 Navigation (0) 2020.12.30 터틀봇3 SLAM (0) 2020.12.27 터틀봇3 연결하기 (Ubuntu 18.04, ROS Melodic) (3) 2020.12.18