#概要
athrill(アスリル)のデータアクセス制御について解説します.
#データアクセス制御
##メモリ情報表示(p)
メモリ表示コマンドの書式は以下のとおりです.
* print(p):
1) print <variable_name>
show memory information of the <variable_name>
2) print <addr(hex)> <size>
show memory information from <addr> to (<addr> + <size>)
3) print <addr(hex)> <type(s|t)> <typename>
show memory information from <addr> by <typename>)
メモリ表示機能は頻繁に使いますので,機能を豊富にしています.
###1) print <variable_name>
変数名を指定して,当該変数のメモリ状態を表示できます.変数はデータ型を持っていますので,データ型に応じた表示に対応しています.以下に代表的なデータ型の表示例を示します(asp3のデータ).
####プリミティブ型
p task_loop
task_loop = (typedef ulong_t )100000 (long unsigned int:4) @ 0x5fff088(0x0)
####ポインタ型(typedef)
p _kernel_p_runtsk
_kernel_p_runtsk = (TCB *: 4 ) 0x5fff780 @ 0x5fff848(0x0)
####構造体型
p tSCIF_CB_tab
tSCIF_CB_tab = ( tSCIF_CB ) = {
= (typedef tSCIF_CB )struct tag_tSCIF_CB {
_inib = (tSCIF_INIB *: 4 ) 0x713c @ 0x5fff6e4(0x0)
initialized = (typedef bool_t )1 (int:4) @ 0x5fff6e8(0x4)
}
}
####配列型
p bitmap_search_table
bitmap_search_table = ( unsigned char ) = {
[0] = 0 (unsigned char:1) @ 0x7651(0x0)
[1] = 1 (unsigned char:1) @ 0x7652(0x1)
[2] = 0 (unsigned char:1) @ 0x7653(0x2)
[3] = 2 (unsigned char:1) @ 0x7654(0x3)
[4] = 0 (unsigned char:1) @ 0x7655(0x4)
[5] = 1 (unsigned char:1) @ 0x7656(0x5)
[6] = 0 (unsigned char:1) @ 0x7657(0x6)
[7] = 3 (unsigned char:1) @ 0x7658(0x7)
[8] = 0 (unsigned char:1) @ 0x7659(0x8)
[9] = 1 (unsigned char:1) @ 0x765a(0x9)
[10] = 0 (unsigned char:1) @ 0x765b(0xa)
[11] = 2 (unsigned char:1) @ 0x765c(0xb)
[12] = 0 (unsigned char:1) @ 0x765d(0xc)
[13] = 1 (unsigned char:1) @ 0x765e(0xd)
[14] = 0 (unsigned char:1) @ 0x765f(0xe)
}
###構造体・配列型
p _kernel_tcb_table
_kernel_tcb_table = ( TCB ) = {
[0] = (typedef TCB )struct task_control_block {
task_queue = (typedef QUEUE )struct queue {
p_next = (struct queue *: 4 ) 0x5fff868 @ 0x5fff760(0x0)
p_prev = (struct queue *: 4 ) 0x5fff868 @ 0x5fff764(0x4)
}
p_tinib = (TINIB *: 4 ) 0x742c @ 0x5fff768(0x8)
tstat = (typedef uint8_t )(typedef __uint8_t )8 (unsigned char:1) @ 0x5fff76c(0xc)
bpriority = (typedef uint8_t )(typedef __uint8_t )2 (unsigned char:1) @ 0x5fff76d(0xd)
priority = (typedef uint8_t )(typedef __uint8_t )2 (unsigned char:1) @ 0x5fff76e(0xe)
actque = 134349320 (unsigned int:4) @ 0x5fff76c(0xc)
wupque = 134349320 (unsigned int:4) @ 0x5fff76c(0xc)
raster = 134349320 (unsigned int:4) @ 0x5fff76c(0xc)
enater = 134349320 (unsigned int:4) @ 0x5fff76c(0xc)
p_winfo = (WINFO *: 4 ) 0x5ffef94 @ 0x5fff770(0x10)
p_lastmtx = (MTXCB *: 4 ) 0x0 @ 0x5fff774(0x14)
tskctxb = (typedef TSKCTXB )struct task_context_block {
sp = (Unknown type: 4 ) 0x5ffef58 @ 0x5fff778(0x18)
pc = (typedef FP )(typedef TOPPERS_fp_t )(Unknown type: 4 ) 0x317e @ 0x5fff77c(0x1c)
}
}
[1] = (typedef TCB )struct task_control_block {
task_queue = (typedef QUEUE )struct queue {
p_next = (struct queue *: 4 ) 0x5fff7a0 @ 0x5fff780(0x20)
p_prev = (struct queue *: 4 ) 0x5fff8a0 @ 0x5fff784(0x24)
}
p_tinib = (TINIB *: 4 ) 0x7444 @ 0x5fff788(0x28)
tstat = (typedef uint8_t )(typedef __uint8_t )1 (unsigned char:1) @ 0x5fff78c(0x2c)
bpriority = (typedef uint8_t )(typedef __uint8_t )9 (unsigned char:1) @ 0x5fff78d(0x2d)
priority = (typedef uint8_t )(typedef __uint8_t )9 (unsigned char:1) @ 0x5fff78e(0x2e)
actque = 134809857 (unsigned int:4) @ 0x5fff78c(0x2c)
wupque = 134809857 (unsigned int:4) @ 0x5fff78c(0x2c)
raster = 134809857 (unsigned int:4) @ 0x5fff78c(0x2c)
enater = 134809857 (unsigned int:4) @ 0x5fff78c(0x2c)
p_winfo = (WINFO *: 4 ) 0x0 @ 0x5fff790(0x30)
p_lastmtx = (MTXCB *: 4 ) 0x0 @ 0x5fff794(0x34)
tskctxb = (typedef TSKCTXB )struct task_context_block {
sp = (Unknown type: 4 ) 0x5ffdf10 @ 0x5fff798(0x38)
pc = (typedef FP )(typedef TOPPERS_fp_t )(Unknown type: 4 ) 0x3370 @ 0x5fff79c(0x3c)
}
}
:
}
###2) print <addr(hex)> <size>
アドレス番地指定でメモリ情報を参照します.sizeによって表示形式が変わります.
####1バイト
unsigned char型で表示します.
p 0x5fff80c 1
size=1 byte
0 0x5fff80c 0x0 ()
####2バイト
unsigned short型で表示します.
p 0x5fff80c 2
size=2 byte
0x5fff80c 0x0
####4バイト
unsigned int型で表示します.
size=4 byte
0x5fff80c 0x8000000
####1, 2, 4バイト以外
1, 2, 4バイト以外のサイズ指定があった場合は,1バイトずつ表示します.
p 0x5fff80c 8
size=8 byte
0 0x5fff80c 0x0 ()
1 0x5fff80d 0x0 ()
2 0x5fff80e 0x0 ()
3 0x5fff80f 0x8 )
4 0x5fff810 0x0 ()
5 0x5fff811 0x0 ()
6 0x5fff812 0x0 ()
7 0x5fff813 0x0 ()
###3) print <addr(hex)> <type(s|t)> <typename>
構造体内にポインタ型のメンバがあった場合,その先のメモリ情報を参照したくなりますよね.
そのための表示機能が本機能です.
####構造体型のポインタ
p 0x74a4 s task_initialization_block
struct task_initialization_block {
tskatr = (typedef ATR )(typedef uint_t )0 (unsigned int:4) @ 0x74a4(0x0)
exinf = (typedef intptr_t )(typedef __intptr_t )0 (int:4) @ 0x74a8(0x4)
task = (typedef TASK )(Unknown type: 4 ) 0xd00 @ 0x74ac(0x8)
ipriority = (typedef uint_t )0 (unsigned int:4) @ 0x74b0(0xc)
stksz = (typedef size_t )4096 (unsigned int:4) @ 0x74b4(0x10)
stk = (Unknown type: 4 ) 0x5ff9000 @ 0x74b8(0x14)
}
####typedef型のポインタ
p 0x74a4 t TINIB
(typedef TINIB )struct task_initialization_block {
tskatr = (typedef ATR )(typedef uint_t )0 (unsigned int:4) @ 0x74a4(0x0)
exinf = (typedef intptr_t )(typedef __intptr_t )0 (int:4) @ 0x74a8(0x4)
task = (typedef TASK )(Unknown type: 4 ) 0xd00 @ 0x74ac(0x8)
ipriority = (typedef uint_t )0 (unsigned int:4) @ 0x74b0(0xc)
stksz = (typedef size_t )4096 (unsigned int:4) @ 0x74b4(0x10)
stk = (Unknown type: 4 ) 0x5ff9000 @ 0x74b8(0x14)
}
##メモリ設定(s)
メモリ設定コマンドの書式は以下のとおりです.
* set(s):
1) set <addr(hex)> <value>
set <value> on memory <addr> by byte
メモリ設定は,現時点では,1バイトしか書き込みできません.
設定例は以下のとおりです.
[設定前]
[DBG>p 0x5fff80c 1
size=1 byte
0 0x5fff80c 0x0
[設定]
[DBG>s 0x5fff80c 255
[設定後]
[DBG>p 0x5fff80c 1
size=1 byte
0 0x5fff80c 0xff
##データウォッチ(w)
メモリ破壊バグ解析に欠かせないのが,データウォッチ機能です.CPUが監視対象メモリへのアクセスを検出した場合,CPUの実行を停止しブレークします(メモリアクセス完了後に停止します).
(OS移植では頻繁に使用しました‥)
* watch(w):
1) watch {r|w|rw} {<addr(hex)> size(dec)|<variable_name>}
set a watch point. Watch points are shown using 'info watch' command.
2) watch d
delete all watch points
3) watch d <watch_no>
delete the watch point of <watch_no>
asp3の_kernel_p_runtskのウォッチ実行例を見てみましょう.
[WRITEアクセス]
[DBG>w w _kernel_p_runtsk
set watch point 0x5fff848 4
[DBG>info watch
[0] w 0x5fff848 4 _kernel_p_runtsk(+0x0)
[DBG>c
[CPU>
core0 HIT watch data : write access : [0] 0x5fff848 0x0 4
[NEXT> pc=0x82a start.S 93
[READアクセス]
[DBG>w rw _kernel_p_runtsk
set watch point 0x5fff848 4
[DBG>info watch
[0] r 0x5fff848 4 _kernel_p_runtsk(+0x0)
[DBG>c
[CPU>
ore0 HIT watch data : read access : [0] 0x5fff848 0x5fff760 4
[NEXT> pc=0x320c prc_support.S 288
[RWアクセス]
[DBG>w rw _kernel_p_runtsk
set watch point 0x5fff848 4
[DBG>info watch
[0] rw 0x5fff848 4 _kernel_p_runtsk(+0x0)
[DBG>c
[CPU>
ore0 HIT watch data : read access : [0] 0x5fff848 0x5fff760 4
[NEXT> pc=0x54e8 semaphore.c 201
##メモリREAD/WRITE実行タスク/関数表示(access)
メモリアクセス実行コンテキストがわかると,排他漏れの問題を早期に検出できる可能性が高いと思い,本機能を追加しました.
書式は以下のとおりです.
* access(-):
1) access <variable_name>
show variable access functions
表示形式は以下の通り.
+<clock> [<access type>] [<core>] [access stack] [access func]
項目 | 説明 |
---|---|
clock | アクセス発生クロック |
access type | 書き込み=WRITE, 読み込み=READ |
core | アクセス発生コア |
access stack | アクセス発生スタック変数(※) |
access func | アクセス発生関数(アセンブラ関数の場合はunknownと表記される) |
(※)TOPPERS OSの場合,アクセス発生スタック変数から実行コンテキスト(タスク or カーネル)が判別可能
asp3の_kernel_p_schedtskのaccessコマンド実行例を見てみましょう.
[DBG>access _kernel_p_schedtsk
* _kernel_p_schedtsk
+ <43640> [WRITE] [core0] [ _kernel_stack_EXC_TASK] [ unknown()]
+ <44087> [WRITE] [core0] [ _kernel_istack] [ _kernel_initialize_task()]
+ <45138> [ READ] [core0] [ intcfg_table] [ unknown()]
+ <45630> [WRITE] [core0] [ _kernel_stack_TSKID_tTask_LogTask_Task] [ ena_dsp()]
+ <254671> [WRITE] [core0] [ _kernel_stack_MAIN_TASK] [ ena_dsp()]
+ <255984> [ READ] [core0] [ _kernel_stack_MAIN_TASK] [ _kernel_make_runnable()]
+ <255995> [ READ] [core0] [ _kernel_stack_MAIN_TASK] [ act_tsk()]
+ <256289> [ READ] [core0] [ _kernel_stack_MAIN_TASK] [ _kernel_make_non_runnable()]
+ <256315> [WRITE] [core0] [ _kernel_stack_MAIN_TASK] [ _kernel_make_non_runnable()]
+ <256415> [ READ] [core0] [ _kernel_stack_MAIN_TASK] [ unknown()]
+ <1536670> [ READ] [core0] [ _kernel_istack] [ _kernel_make_runnable()]
+ <1536676> [WRITE] [core0] [ _kernel_istack] [ _kernel_make_runnable()]
+ <1537007> [ READ] [core0] [ _kernel_stack_TASK1] [ unknown()]
+ <1552963> [ READ] [core0] [ _kernel_stack_TSKID_tTask_LogTask_Task] [ _kernel_make_non_runnable()]
+ <1552989> [WRITE] [core0] [ _kernel_stack_TSKID_tTask_LogTask_Task] [ _kernel_make_non_runnable()]
+ <1553187> [ READ] [core0] [ _kernel_stack_TSKID_tTask_LogTask_Task] [ unknown()]