RTC_API(3x)

名前
_rtc_check_free, _rtc_check_malloc, _rtc_check_realloc, _rtc_check_malloc_result, _rtc_check_realloc_result, _rtc_hide_region, _rtc_off, _rtc_on, _rtc_record_free, _rtc_record_malloc, _rtc_record_realloc, _rtc_report_error, rtc_api - プライベートメモリーアロケータが使用することのできる実行時検査 (RTC) API。

形式

#include <rtc_api.h>

RTC_Result _rtc_check_free(void *ptr);

RTC_Result _rtc_check_malloc(size_t size);

RTC_Result _rtc_check_realloc(void *ptr, size_t size);

RTC_Result _rtc_check_malloc_result(void *ptr, size_t size);

RTC_Result _rtc_check_realloc_result(void *old_ptr, void *new_ptr, size_t new_size);

RTC_Result _rtc_hide_region(void *ptr, size_t size);

RTC_Result _rtc_off(void );

RTC_Result _rtc_on(void );

RTC_Result _rtc_record_free(void *ptr);

RTC_Result _rtc_record_malloc(void *ptr, size_t size);

RTC_Result _rtc_record_realloc(void *old_ptr, void *new_ptr, size_t new_size);

void _rtc_report_error(RTC_Result err);

MT レベル

MT-Safe

機能説明
実行時検査 (RTC) では、RTC がプログラム内のすべての割り当てと割り当て解放を 追跡できるように、共有ライブラリ libc.so の標準ヒープ管理ルーチンを使用する 必要があります。 多くのアプリケーションでは、何もないところから独自の メモリー管理ルーチンを作成しています。ユーザーが独自のルーチンを使用する場合、それを プライベートアロケータといいますが、RTC はそれらを自動的には追跡できません。 ただし、RTC は標準ヒープアロケータと同じようにプライベートアロケータを 扱えるための API を提供します。 実行時検査 API 関数は、RTC に対して標準ではないメモリーアロケータの使用を 可能にするインタフェースを提供します。このインタフェースは、 プライベートメモリーアロケータであるかのように malloc、free、realloc をサポートします。これによって、メモリー領域の 割り当てや解放を行うときに API の関数を使用して RTC のメモリーマップを 更新できます。API によって、アロケータを使用するプログラムが 行うメモリーアクセスを RTC が検査できます。 「プライベートアロケータ」がプログラムヒープを使用しないときには、 RTC エラーレポートが若干異なります。 標準ヒープブロックを参照するメモリーアクセスエラーが発生すると、一般に、 RTC エラーレポート にはヒープブロック割り当ての位置が含まれます。これが、この場合には 報告されません。 RTC API にあるすべてのエントリポイントは、RTC で RTC ライブラリを実行するときに適切な関数の呼び出しに変わるマクロです。 これらを使用するために、条件ごとにコードをコンパイルする必要はありません。

_rtc_check_free() - free のような関数に渡された引数が正しいことを確認するために呼び出されます。

_rtc_check_malloc() - malloc のような関数に渡された引数が正しいことを確認するために呼び出されます。

_rtc_check_realloc() - realloc のような関数に渡された引数が正しいことを確認するために呼び出されます。

_rtc_check_malloc_result() - 'size' バイトの割り当ての結果生成されたポインタ 'ptr' が malloc のような関数の 正しい結果であることを確認するために呼び出されます。

_rtc_check_realloc_result() - 'old_ptr' を 'size' バイトに再割り当てした結果生成されたポインタ 'new_ptr' が
 realloc のような関数の正しい結果であることを確認するために呼び出されます。

_rtc_hide_region() - 'ptr' から始まる 'size' バイトを RTC メモリーマップ ではアクセスできないものとしてマークします。オンデマンドで割り当てられる
 sbrk() や mmap() で取得したメモリーに対するアクセスを無効にするために使用されます。

_rtc_off() および _rtc_on() - RTC がアクセスできないとみなしているメモリー領域にあるデータ構造を操作している間に、 プライベートアロケータがメモリーアクセス検査をシャットオフできるようにします。 アロケータはこのようなメモリー領域にアクセスする前に
 _rtc_off() を呼び出すことで検査をオフにでき、また、終了したときに
 _rtc_on() を呼び出すことで検査をオンにすることができます。

_rtc_record_free()、_rtc_record_malloc()、_rtc_record_realloc() - プライベートアロケータがメモリーのブロックの割り当てや解放を行うときに 発生するメモリー領域アクセスの変更を反映するように、 RTC のメモリーマップを変更します。

_rtc_report_error() - エラーを報告します。

戻り値

操作が正常終了した場合には、_rtc_check_free、 _rtc_check_malloc、_rtc_check_realloc、_rtc_check_malloc_result、 _rtc_check_realloc_result、_rtc_hide_region、_rtc_record_free、 _rtc_record_malloc、_rtc_record_realloc はすべて RTC_SUCCESS を戻します。 異常終了した場合には、_rtc_report_error に渡せるエラー結果を戻します。

使用例
以下の例では、RTC のメモリーマップをカレントに保つように プライベートメモリーアロケータを有効にする方法を示す RTC API 関数を 呼び出しています。

    1. 後の割り当てのためにメモリーを取得。
       {
               size_t large_block = size_needed;
               void *old_break_ptr = sbrk((int)large_block);
               RTC_Result result;
               result = _rtc_hide_region(old_break_ptr, large_block);
               if (result != RTC_success)
                       return NULL;
               return old_break_ptr;
       }

    2. ブロックの割り当て (malloc のような関数)。
       {
               size_t block_size = request_size;
               void *ptr = NULL;
               RTC_Result result = RTC_SUCCESS;
               result = _rtc_check_malloc(block_size);
               if (result == RTC_SUCCESS) {
                      _rtc_off();
                      ptr = private_alloc(block_size);
                      _rtc_on();
                      result = _rtc_record_malloc(ptr, block_size);
    		  if (result == RTC_SUCCESS) {
    		   	/* ユーザーに戻す予定のメモリーブロックの周りに
    			 * 防護ブロックがある場合は、_rtc_hide_region()
    			 * を使用してその防護ブロックをアクセスできない
    			 * ものとしてマークする
    			 */
    		  }
               }
               if (result != RTC_SUCCESS)
                       _rtc_report_error(result);
               return ptr;
        }

    3. ブロックの解放 (free のような関数)。
       {
               RTC_Result result = RTC_SUCCESS;
               result = _rtc_check_free(ptr);
               if (result == RTC_SUCCESS) {
                       _rtc_off();
                       private_free(ptr);
                       _rtc_on();
                       (void)_rtc_record_free(ptr);
               } else {
                       _rtc_report_error(result);
               }
       }

    4. ブロックの再割り当て (realloc のような関数)。
       {
               void *new_ptr = NULL;
               size_t size = request_size;
               void *old_ptr;
               RTC_Result result = RTC_SUCCESS;
               result = _rtc_check_realloc(old_ptr, size);
               if (result == RTC_SUCCESS) {
                       _rtc_off();
                       new_ptr = private_realloc(old_block_record, size);
                       _rtc_on();
                       result = _rtc_check_realloc_result(old_ptr, new_ptr, size);
                       if (result == RTC_SUCCESS)
                           result = _rtc_record_realloc(old_ptr, new_ptr, size);
               }
               if (result != RTC_SUCCESS)
                       _rtc_report_error(result);
               return new_ptr;
       }

関連項目
dbx(1)、 mmap(2)、 sbrk(2)