6
0

More than 5 years have passed since last update.

athrill(アスリル)機能マニュアル(データアクセス制御)

Posted at

概要

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()]

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0