kernel의 I/O stack은 VFS->Filesystem->Block->driver 의 계층으로 이루어지고, 각 단계에서 식별할 수 있는 filesystem 관련 kernel 자료구조들이 있다. inode, dentry, bio, request 등의 자료구조들은 I/O stack을 거치면서 해당 stack에 맞게 처리되는데 디버깅이 필요하거나 특별한 파일을 식별하여 tracing이 필요할떄 상호간에 변환이 필요한 경우가 있다. 예를 들어, file에 대한 요청은 filesystem을 거치면서 bio로 변환되어 block device driver로 전달되는데, 이때 어떤 파일에 대한 request인지 확인하기 위해서는 driver level에 전달된 bio를 file name, inode 등으로 변환해야할 필요가 있다는 것이다. bio에서 inode를 추출하기 위해서 아래와 같은 과정을 거치면 된다. #sample code struct inode *inode_from_bio(struct bio *bio) { if (bio && bio_has_data(bio) && bio->bi_io_vec && bio->bi_io_vec->bv_page) { if (PageAnon(bio->bi_io_vec->bv_page)) { struct inode *inode; inode = dio_bio_get_inode(bio); return inode; } else { if (page_mapping(bio->bi_io_vec->bv_page)) { return page_mapping(bio->bi_io_vec->bv_page)->host; } } } return NULL; } 그리고 inode에서 filename을 얻어내기 위해서 아래와 같은 코드를 사용하면 되는데, inode에는 inode와 연결된 dentry들이 list로 연결되어 있어 가능하다. char *fname_from_inode(struct inode* inode) { struct dentry *dentry = NULL; char *filename = NULL; if (!inode) return NULL; if (hlist_empty(&inode->i_dentry)) return NULL; dentry = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); filename = dentry->d_iname; return filename; } |
|
'dev/tip'에 해당되는 글 8건
- 2019/06/18 scott [Filesystem] bio, inode, filename 변환
- 2018/05/13 scott [Crash] 유용한 명령어#2
- 2016/06/14 scott [Crash] 유용한 명령어
- 2015/01/15 scott HTML내에서 php 코드 사용하기
댓글+트랙백 RSS :: http://www.semanogic.com/blog/tc/scott/rss/response/96
댓글+트랙백 ATOM :: http://www.semanogic.com/blog/tc/scott/atom/response/96
Crash tool을 이용해서 VM Core dump를 올리고 나면 볼수 있는 것이
kernel space의 process stack 뿐인데, user space의 call stack을 볼 수 있으면 굉장히 유용하다.
Crash extension 중 gcore가 있는데, 이는 pid 기반으로 process의 core dump를 추출해주며, core dump를 gdb로 로딩하면 process의 stack 정보를 볼수 있다. [crash utility의 extensions] 위 page에서 gcore 검색하면 최신 source로 link가 걸려있음. 다운로드한 파일을 crash tool의 extension 폴더에 풀고 extension을 재 빌드해주면 gcore.so가 생성됨. crash>extend /path/to/gcore/extension/gcore.so crash>gcore -f 255 -v 0 1 -> 위에서 제일 마지막 숫자가 core dump하려는 process의 PID이고, 명령어 실행하고 나면, core.1.init 과 같이 core dump가 생성되며, 이후 gdb를 사용하여 symbol과 함께 로딩 해주면 끝. gdb ./init ./core.1.init (gdb)bt library symbol 경로 설정은 set solib-search-path |
댓글+트랙백 RSS :: http://www.semanogic.com/blog/tc/scott/rss/response/95
댓글+트랙백 ATOM :: http://www.semanogic.com/blog/tc/scott/atom/response/95
// 변수 출력 crash> p bt_dev_p bt_dev_p = $1 = (struct brcm_bt_dev *) 0xffffffc095fdf840 // structure 내부 data 출력 crash> struct brcm_bt_dev 0xffffffc095fdf840 struct brcm_bt_dev { c_dev = { kobj = { name = 0x0, entry = { next = 0xffffffc095fdf848, prev = 0xffffffc095fdf848 }, parent = 0x0, kset = 0x0, [ snip ] next = 69 } } } }, task_list = { next = 0xffffffc095fdf970, prev = 0xffffffc095fdf970 } } } // module symbol loading crash> mod -S . mod: cannot find or load object file for xxxx module MODULE NAME SIZE OBJECT FILE ffffffbffc0650f0 brcm_bt_drv 13853 ./brcm_bt_drv.ko // workqueue 출력 crash> runq CPU 0 RUNQUEUE: ffffffc0c58e7d80 CURRENT: PID: 350 TASK: ffffffc0c0b20000 COMMAND: "dhd_dpc" RT PRIO_ARRAY: ffffffc0c58e7eb8 [ 1] PID: 350 TASK: ffffffc0c0b20000 COMMAND: "dhd_dpc" CFS RB_ROOT: ffffffc0c58e7e18 [120] PID: 5437 TASK: ffffffc02cc621c0 COMMAND: "kworker/0:0" [100] PID: 17289 TASK: ffffffc0536a0b40 COMMAND: "kworker/0:0H" [120] PID: 3 TASK: ffffffc0c42b0b40 COMMAND: "ksoftirqd/0" CPU 1 RUNQUEUE: ffffffc0c58f8d80 CURRENT: PID: 10061 TASK: ffffffc052f18000 COMMAND: "mdss_fb0" RT PRIO_ARRAY: ffffffc0c58f8eb8 [ 83] PID: 10061 TASK: ffffffc052f18000 COMMAND: "mdss_fb0" CFS RB_ROOT: ffffffc0c58f8e18 [120] PID: 1238 TASK: ffffffc095c22d00 COMMAND: "kernel_logger" CPU 2 RUNQUEUE: ffffffc0c5909d80 CURRENT: PID: 19 TASK: ffffffc0c3e5f080 COMMAND: "ksoftirqd/2" RT PRIO_ARRAY: ffffffc0c5909eb8 [no tasks queued] CFS RB_ROOT: ffffffc0c5909e18 [111] PID: 459 TASK: ffffffc0b28bc380 COMMAND: "DispSync" [120] PID: 8 TASK: ffffffc0c42b4ec0 COMMAND: "rcu_preempt" CPU 3 RUNQUEUE: ffffffc0c591ad80 CURRENT: PID: 2403 TASK: ffffffc0435c0b40 COMMAND: "kworker/3:3" RT PRIO_ARRAY: ffffffc0c591aeb8 [no tasks queued] CFS RB_ROOT: ffffffc0c591ae18 [no tasks queued] CPU 4 RUNQUEUE: ffffffc0c592bd80 CURRENT: PID: 0 TASK: ffffffc0c3ca6540 COMMAND: "swapper/4" RT PRIO_ARRAY: ffffffc0c592beb8 [no tasks queued] CFS RB_ROOT: ffffffc0c592be18 [no tasks queued] CPU 5 RUNQUEUE: ffffffc0c593cd80 CURRENT: PID: 0 TASK: ffffffc0c3ca1680 COMMAND: "swapper/5" RT PRIO_ARRAY: ffffffc0c593ceb8 [no tasks queued] CFS RB_ROOT: ffffffc0c593ce18 [no tasks queued] // list 출력 crash> list delayed_fput_list ffffffc001b81888 ffffffc04b1ab600 ffffffc058036000 ffffffc04ae1ac00 ffffffc04ae1a400 ffffffc09ef22700 ffffffc09ef22200 ffffffc0b37caa00 ffffffc058036800 // open files crash> files 55 // files "pid" PID: 55 TASK: ffffffc0c3001680 CPU: 1 COMMAND: "mpm" ROOT: / CWD: / FD FILE DENTRY INODE TYPE PATH 0 ffffffc017708400 ffffffc0303fb798 ffffffc0c26746c0 UNKN inotify 1 ffffffc017694d00 ffffffc024e2abd0 ffffffc0c26746c0 UNKN inotify crash> foreach files // all pid // symbol to virtual address crash> sym bt_send_data_ldisc ffffffbffc063638 (t) bt_send_data_ldisc [brcm_bt_drv] /source/android/kernel/drivers/bluetooth/broadcom/bt_protocol_driver/brcm_bt_drv.c: 470 // tree 구조 파싱 crash> tree -t radix -r address_space.page_tree 0xFFFFFFC0F1809330 ...skipping... // memory read crash> rd -s 0xFFFFFFC002D06650 128 ffffffc002d06650: print_fmt_writeback_single_inode_template+128
ffffffc007219800 |