th0x4c 備忘録

[OS] 仮想メモリ空間のメモリマップを調べる

目的

仮想メモリ空間のアドレス等のメモリマップを調べる。

なお、ちゃんと調べたわけではないので誤りがあるかもしれない。

環境

  • OS: Oracle Enterprise Linux 5.8
  • Kernel: 2.6.32-300.10.1.el5uek x86_64

仮想メモリ空間のメモリマップ

Unix/Linux における仮想メモリ空間のメモリマップは一般には以下のようになっている。

+------------------------------+  0x0000000000000000
:                              :
+------------------------------+
|                              |
|  text                        |  機械命令
|                              |
+------------------------------+
|                              |
|  data                        |  初期化された static 変数
|                              |
+------------------------------+
|                              |
|  BSS                         |  初期化されていない static 変数
|                              |
+------------------------------+
|                              |
|  heap                        |  malloc() で動的に確保される領域(上位アドレスに伸びる)
|                              |
+------------------------------+
|             ||||             |
|             VVVV             |
:                              :
:                              :
|                              |
+------------------------------+
|                              |
|  shared memory               |  共有メモリ領域
|                              |
+------------------------------+
|                              |
:                              :
:                              :
|             ^^^^             |
|             ||||             |
+------------------------------+
|                              |
|  stack                       |  関数呼び出しやローカル変数等で使用されるスタック領域(下位アドレスに伸びる)
|                              |
+------------------------------+
|                              |
|  arguments / environments    |  引数と環境変数
|                              |
+------------------------------+
:                              :
:                              :
+------------------------------+  0xffffffffffffffff = 2^64 (64bit の場合)

実例

以下のプログラムでメモリマップを確認する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/shm.h>

#define STRSIZE 64

void hello(char *name);
void hello_local_world();

char not_initialized_global_world[STRSIZE];
char initialized_global_world[STRSIZE] = "initialized global world";


int main(int argc, char *argv[])
{
  static char not_initialized_static_world[STRSIZE];
  static char initialized_static_world[STRSIZE] = "initialized static world";
  char *malloc_world;
  int shmid;
  char *shared_memory_world;
  char *big_malloc_world;
  char *medium_malloc_world_1;
  char *medium_malloc_world_2;

  strcpy(not_initialized_global_world, "not initialized global world");

  strcpy(not_initialized_static_world, "not initialized static world");

  malloc_world = (char *) malloc(sizeof(char) * STRSIZE);
  strcpy(malloc_world, "malloc world");

  shmid = shmget(IPC_PRIVATE, sizeof(char) * STRSIZE, 0666 | IPC_CREAT);
  shared_memory_world = (char *) shmat(shmid, 0, 0);
  strcpy(shared_memory_world, "shared memory world");

  big_malloc_world = (char *) malloc(256 * 1024);
  strcpy(big_malloc_world, "big malloc world");

  medium_malloc_world_1 = (char *) malloc(131 * 1024 + 905);
  strcpy(medium_malloc_world_1, "medium malloc world 1");

  medium_malloc_world_2 = (char *) malloc(131 * 1024 + 904);
  strcpy(medium_malloc_world_2, "medium malloc world 2");

  hello(argv[1]);
  hello(not_initialized_global_world);
  hello(initialized_global_world);
  hello(not_initialized_static_world);
  hello(initialized_static_world);
  hello(malloc_world);
  hello(shared_memory_world);
  hello(big_malloc_world);
  hello(medium_malloc_world_1);
  hello(medium_malloc_world_2);
  hello_local_world();

  getchar();

  free(malloc_world);
  shmdt(shared_memory_world);
  shmctl(shmid, IPC_RMID, 0);
  free(big_malloc_world);
  free(medium_malloc_world_1);
  free(medium_malloc_world_2);

  return 0;
}

void hello(char *name)
{
  printf("hello, %s: 0x%016lx\n", name, name);
}

void hello_local_world()
{
  char local_world[STRSIZE];

  strcpy(local_world, "local world");
  hello(local_world);
}

実行結果は以下。

$ gcc -o hello hello.c
$ ./hello ARGworld
hello, ARGworld: 0x00007ffff7269cb5
hello, not initialized global world: 0x0000000000600ec0
hello, initialized global world: 0x0000000000600de0
hello, not initialized static world: 0x0000000000600e80
hello, initialized static world: 0x0000000000600e20
hello, malloc world: 0x0000000001f61010
hello, shared memory world: 0x00007f2eeea0e000
hello, big malloc world: 0x00007f2eee9b0010
hello, medium malloc world 1: 0x00007f2eee98f010
hello, medium malloc world 2: 0x0000000001f61060
hello, local world: 0x00007ffff7269680

メモリマップは pmapcat /proc/<PID>/mapscat /proc/<PID>/smaps で確認できる。

$ pmap -x 19671
19671:   ./hello ARGworld
Address           Kbytes     RSS   Dirty Mode   Mapping
0000000000400000       4       4       0 r-x--  hello
0000000000600000       4       4       4 rw---  hello
0000000001f61000     132       8       8 rw---    [ anon ]
00000037be000000     112      96       0 r-x--  ld-2.5.so
00000037be21c000       4       4       4 r----  ld-2.5.so
00000037be21d000       4       4       4 rw---  ld-2.5.so
00000037be400000    1340     248       0 r-x--  libc-2.5.so
00000037be54f000    2044       0       0 -----  libc-2.5.so
00000037be74e000      16      12       8 r----  libc-2.5.so
00000037be752000       4       4       4 rw---  libc-2.5.so
00000037be753000      20      16      16 rw---    [ anon ]
00007f2eee98d000     408      20      20 rw---    [ anon ]
00007f2eeea0e000       4       4       4 rw-s-    [ shmid=0x578006 ]
00007f2eeea0f000       8       8       8 rw---    [ anon ]
00007ffff7255000      84       8       8 rw---    [ stack ]
00007ffff730e000       4       4       0 r-x--    [ anon ]
ffffffffff600000       4       0       0 r-x--    [ anon ]
----------------  ------  ------  ------
total kB            4196     444      88

$ cat /proc/19671/maps 
00400000-00401000 r-xp 00000000 fd:00 5101878                            /tmp/hello
00600000-00601000 rw-p 00000000 fd:00 5101878                            /tmp/hello
01f61000-01f82000 rw-p 00000000 00:00 0                                  [heap]
37be000000-37be01c000 r-xp 00000000 fd:00 1871272                        /lib64/ld-2.5.so
37be21c000-37be21d000 r--p 0001c000 fd:00 1871272                        /lib64/ld-2.5.so
37be21d000-37be21e000 rw-p 0001d000 fd:00 1871272                        /lib64/ld-2.5.so
37be400000-37be54f000 r-xp 00000000 fd:00 1871273                        /lib64/libc-2.5.so
37be54f000-37be74e000 ---p 0014f000 fd:00 1871273                        /lib64/libc-2.5.so
37be74e000-37be752000 r--p 0014e000 fd:00 1871273                        /lib64/libc-2.5.so
37be752000-37be753000 rw-p 00152000 fd:00 1871273                        /lib64/libc-2.5.so
37be753000-37be758000 rw-p 00000000 00:00 0 
7f2eee98d000-7f2eee9f3000 rw-p 00000000 00:00 0 
7f2eeea0e000-7f2eeea0f000 rw-s 00000000 00:04 5734406                    /SYSV00000000 (deleted)
7f2eeea0f000-7f2eeea11000 rw-p 00000000 00:00 0 
7ffff7255000-7ffff726a000 rw-p 00000000 00:00 0                          [stack]
7ffff730e000-7ffff730f000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

size コマンドで text や BSS のサイズを確認できる。

$ size hello
   text    data     bss     dec     hex filename
   2414     704     160    3278     cce hello

$ size --format=SysV -x hello
hello  :
section           size       addr
.interp           0x1c   0x400200
.note.ABI-tag     0x20   0x40021c
.gnu.hash         0x1c   0x400240
.dynsym          0x108   0x400260
.dynstr           0x6d   0x400368
.gnu.version      0x16   0x4003d6
.gnu.version_r    0x20   0x4003f0
.rela.dyn         0x18   0x400410
.rela.plt         0xd8   0x400428
.init             0x18   0x400500
.plt              0xa0   0x400518
.text            0x488   0x4005c0
.fini              0xe   0x400a48
.rodata           0x25   0x400a58
.eh_frame_hdr     0x34   0x400a80
.eh_frame         0xd4   0x400ab8
.ctors            0x10   0x600b90
.dtors            0x10   0x600ba0
.jcr               0x8   0x600bb0
.dynamic         0x190   0x600bb8
.got               0x8   0x600d48
.got.plt          0x60   0x600d50
.data             0xa0   0x600dc0
.bss              0xa0   0x600e60
.comment         0x114        0x0
Total            0xde2

これらから次のようなメモリマップとなっていると考えられる。

+------------------------------+  0x0000000000000000
:                              :
+------------------------------+  0x0000000000400000
|text                          |  機械命令
|                              |
+------------------------------+  0x0000000000401000
:                              :
+------------------------------+  0x0000000000600000
|                              |  0x0000000000600dc0
|data                          |  初期化された static 変数
|  initialized global var      |  0x0000000000600de0
|  initialized static var      |  0x0000000000600e20
|                              |
+------------------------------+  0x0000000000600e60
|BSS                           |  初期化されていない static 変数
|  not initialized static var  |  0x0000000000600e80
|  not initialized global var  |  0x0000000000600ec0
|                              |
+------------------------------+  0x0000000000601000
:                              :
+------------------------------+  0x0000000001f61000
|heap                          |  malloc() で動的に確保される領域(上位アドレスに伸びる)
|  malloc var                  |  0x0000000001f61010
|  malloc var                  |  0x0000000001f61060
|                              |
+------------------------------+  0x0000000001f82000
|             ||||             |
|             VVVV             |
:                              :
:                              :
|                              |
+------------------------------+  0x00000037be000000
|                              |
|  共有ライブラリ              |
|  (ld-2.5.so, libc-2.5.so)    |
+------------------------------+  0x00000037be753000
| ???                          |
+------------------------------+  0x00000037be758000
|                              |
:                              :
:                              :
|             ^^^^ ??          |
|             |||| ??          |
+------------------------------+  0x00007f2eee98d000
|heap??                        |
|  malloc var                  |  0x00007f2eee98f010
|  big malloc var              |  0x00007f2eee9b0010
|                              |
+------------------------------+  0x00007f2eee9f3000
:                              :
+------------------------------+  0x00007f2eeea0e000
|shared memory                 |  共有メモリ領域
|  shared memory var           |  0x00007f2eeea0e000
|                              |
+------------------------------+  0x00007f2eeea0f000
|???                           |
+------------------------------+  0x00007f2eeea11000
|                              |
:                              :
:                              :
|             ^^^^             |
|             ||||             |
+------------------------------+  0x00007ffff7255000
|stack                         |  関数呼び出しやローカル変数等で使用されるスタック領域(下位アドレスに伸びる)
|  local var                   |  0x00007ffff7269680
|  arguments[1]                |  0x00007ffff7269cb5
|                              |
+------------------------------+  0x00007ffff726a000
:                              :
+------------------------------+  0x00007ffff730e000
|???                           |
+------------------------------+  0x00007ffff730f000
|                              |
:                              :
:                              :
|                              |
+------------------------------+  0xffffffffff600000
|arguments / environments??    |
|                              |
+------------------------------+  0xffffffffff601000
:                              :
:                              :
+------------------------------+  0xffffffffffffffff = 2^64 (64bit の場合)

heap としては 0x0000000001f61000 〜 0x0000000001f82000 の 132Kbytes が割り当てられているようだが、 約132Kbytes より大きく malloc() で動的にメモリを割り当てるとアドレスが飛んで 0x00007f2eee98d000 付近に メモリが割り当てられ、しかも下位にメモリが伸びているようだ。

参考

[GDB] 別環境で採取した Core ファイルを解析する方法

目的

別環境で採取した core ファイルを解析する。

環境

  • OS: Oracle Enterprise Linux 5.8
  • GDB: GNU gdb 7.0.1-42.el5

解析に必要なファイル

別環境で発生した core ファイルを解析するためには以下のファイルが必要。

  • core ファイル
  • 実行ファイル
  • 共有ライブラリ

例えば、以下のように abort() でわざと core を吐かせて試してみる。

$ cat hello.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  printf("hello, world\n");
  abort();
  return 0;
}

$ gcc -o hello hello.c
$ ./hello
hello, world
Aborted (core dumped)
$ ls -ltr | tail -1
-rw------- 1 oracle oinstall 184320 Oct 10 20:59 core.7441

core.7441 という core ファイルが吐かれた。

実行ファイルは core ファイルに対して file コマンドを実行すれば確認できる。

$ file core.7441
core.7441: ELF 64-bit LSB core file AMD x86-64, version 1 (SYSV), SVR4-style, from 'hello'

hello という実行ファイルによってこの core が吐かれたことが分かる。

共有ライブラリは GDB で core を読み込んで info share で確認できる。

$ gdb ./hello ./core.7441 
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-42.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/hello...(no debugging symbols found)...done.
[New Thread 7441]
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Core was generated by `./hello'.
Program terminated with signal 6, Aborted.
#0  0x00000037be430265 in raise () from /lib64/libc.so.6
(gdb) info share
From                To                  Syms Read   Shared Object Library
0x00000037be41d780  0x00000037be50ad68  Yes (*)     /lib64/libc.so.6
0x00000037be000a70  0x00000037be01682e  Yes (*)     /lib64/ld-linux-x86-64.so.2
(*): Shared library is missing debugging information.

共有ライブラリとしては以下が読み込まれていることが分かる。

  • /lib64/libc.so.6
  • /lib64/ld-linux-x86-64.so.2

なお、実行中に動的リンクを行うようなプログラムでなければ、共有ライブラリは ldd コマンドでも確認できる。

$ ldd ./hello
        linux-vdso.so.1 =>  (0x00007fffcd1ff000)
        libc.so.6 => /lib64/libc.so.6 (0x00000037be400000)
        /lib64/ld-linux-x86-64.so.2 (0x00000037be000000)

以上より、この例では他の環境でこの core ファイルを解析するためには次のファイルを採取する必要がある。

  • core ファイル => core.7441
  • 実行ファイル => hello
  • 共有ライブラリ => /lib64/libc.so.6, /lib64/ld-linux-x86-64.so.2

別環境での core の解析

別環境に先ほど採取したファイルを展開する。 今回は以下のように配置した。

/tmp/core.7441
/tmp/bin/hello
/tmp/lib/libc.so.6
/tmp/lib/ld-linux-x86-64.so.2

GDB でこの core を解析するためには、採取した共有ライブラリを読み込むために以下のように solib-absolute-prefix, solib-search-path を設定する。

$ cd /tmp
$ gdb
(gdb) set solib-absolute-prefix /tmp/lib
(gdb) set solib-search-path /tmp/lib
(gdb) file ./bin/hello
(gdb) core-file ./core.7441 

実際の実行例は以下。

$ gdb
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-42.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) set solib-absolute-prefix /tmp/lib
(gdb) set solib-search-path /tmp/lib
(gdb) file ./bin/hello
Reading symbols from /tmp/bin/hello...(no debugging symbols found)...done.
(gdb) core-file ./core.7441 
[New Thread 7441]
Reading symbols from /tmp/lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /tmp/lib/libc.so.6
Reading symbols from /tmp/lib/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /tmp/lib/ld-linux-x86-64.so.2
Core was generated by `./hello'.
Program terminated with signal 6, Aborted.
#0  0x00000037be430265 in raise () from /tmp/lib/libc.so.6
(gdb) bt
#0  0x00000037be430265 in raise () from /tmp/lib/libc.so.6
#1  0x00000037be431d10 in abort () from /tmp/lib/libc.so.6
#2  0x00000000004004f6 in main ()

ソースファイル

デバックオプション(-g オプション)付きでコンパイルされている場合は、ソースファイルがあればソースコードを使用した調査ができる。 コンパイルした環境と別の環境で core 解析する場合、ソースコードを入手して、GDB の directory にてソースファイルを展開したディレクトリを指定する。

実行例は以下。(実行ファイルはデバックオプション付きでコンパイルしたものを使用)

(gdb) bt
#0  0x00000030ea830265 in raise () from /tmp/lib/libc.so.6
#1  0x00000030ea831d10 in abort () from /tmp/lib/libc.so.6
#2  0x00000000004004f6 in main (argc=1, argv=0x7fff9d995df8) at hello.c:7
(gdb) frame 2
#2  0x00000000004004f6 in main (argc=1, argv=0x7fff9d995df8) at hello.c:7
7   hello.c: No such file or directory.
    in hello.c
(gdb) list
2     in hello.c

ソースファイルが見つからないと上記のようにソースコードが必要な調査ができない。 directory にてソースファイルを展開したディレクトリを指定すると、ソースコードを元にした調査ができる。 (ディレクトリが複数ある場合は:で区切って複数指定するか、directory をディレクトリの分だけ実行すれば追加される)

(gdb) directory /tmp/src
Source directories searched: /tmp/src:$cdir:$cwd
(gdb) frame 2
#2  0x00000000004004f6 in main (argc=1, argv=0x7fff9d995df8) at hello.c:7
7         abort();
(gdb) list
2       #include <stdlib.h>
3       
4       int main(int argc, char *argv[])
5       {
6         printf("hello, world\n");
7         abort();
8         return 0;
9       }

[Oracle] SQL 計画管理

目的

SQL 計画管理により、実行計画を固定化する。

環境

  • OS: Oracle Enterprise Linux 5.8
  • DB: Oracle Database 11g Release 2 (11.2.0.3)

マニュアル

SQL 計画管理

SQL 計画管理により、実行計画を固定化することができる。具体的には次のステップで行う。

  1. SQL 計画の自動取得(OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES=TRUE)
  2. 実行計画を管理する SQL を 2 回以上実行
  3. 取得した SQL 計画の使用(OPTIMIZER_USE_SQL_PLAN_BASELINES=TRUE)

実際に実行してみる。

  • SQL 計画の自動取得(OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES=TRUE)

OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES 初期化パラメータ(デフォルト FALSE)を TRUE に設定することで SQL 計画の自動取得が有効になる。

SQL> ALTER SESSION SET OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES=TRUE;

Session altered.
  • SQL を 2 回以上実行

SQL を 2 回以上実行して、SQL 計画ベースラインに保存する。

SQL> SELECT * FROM scott.emp WHERE empno = 7900;

     EMPNO ENAME                          JOB                                MGR HIREDATE        SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- -------- ---------- ---------- ----------
      7900 JAMES                          CLERK                             7698 81-12-03        960                    30

SQL> SELECT * FROM scott.emp WHERE empno = 7900;

     EMPNO ENAME                          JOB                                MGR HIREDATE        SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- -------- ---------- ---------- ----------
      7900 JAMES                          CLERK                             7698 81-12-03        960                    30
  • SQL 計画の自動取得を無効化(OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES=FALSE)

SQL 計画の自動取得を無効化する。

SQL> ALTER SESSION SET OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES=FALSE;

Session altered.
  • SQL が SQL 計画ベースラインに保存されたことを確認

DBA_SQL_PLAN_BASELINES を確認する。

SQL> col sql_text for a60
     col sql_handle for a30
     col plan_name for a30
     set lines 200
SQL> SELECT SQL_TEXT, SQL_HANDLE, PLAN_NAME, ENABLED, ACCEPTED, FIXED
     FROM   DBA_SQL_PLAN_BASELINES;

SQL_TEXT                                                     SQL_HANDLE                     PLAN_NAME                      ENABLED   ACCEPTED  FIXED
------------------------------------------------------------ ------------------------------ ------------------------------ --------- --------- ---------
SELECT * FROM scott.emp WHERE empno = 7900                   SQL_84ec680ef31d6de4           SQL_PLAN_89v381vtjuvg4695cc014 YES       YES       NO

実行計画を確認する。

SQL> SELECT * FROM TABLE(
       DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE(
         sql_handle=>'SQL_84ec680ef31d6de4',
         format=>'basic'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
SQL handle: SQL_84ec680ef31d6de4
SQL text: SELECT * FROM scott.emp WHERE empno = 7900
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
Plan name: SQL_PLAN_89v381vtjuvg4695cc014         Plan id: 1767686164
Enabled: YES     Fixed: NO      Accepted: YES     Origin: AUTO-CAPTURE
--------------------------------------------------------------------------------


PLAN_TABLE_OUTPUT
----------------------------------------------
Plan hash value: 2949544139

----------------------------------------------
| Id  | Operation                   | Name   |
----------------------------------------------
|   0 | SELECT STATEMENT            |        |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |
|   2 |   INDEX UNIQUE SCAN         | PK_EMP |
----------------------------------------------

20 rows selected.
  • 取得した SQL 計画の使用(OPTIMIZER_USE_SQL_PLAN_BASELINES=TRUE)

OPTIMIZER_USE_SQL_PLAN_BASELINES 初期化パラメータ(デフォルト TRUE)を TRUE に設定することで取得した SQL 計画を使用する。

SQL> ALTER SESSION SET OPTIMIZER_USE_SQL_PLAN_BASELINES=TRUE;

Session altered.

あとは普通に SQL を実行するだけで取得した SQL 計画が使用される。

SQL> set autotrace on
SQL> SELECT * FROM scott.emp WHERE empno = 7900;

     EMPNO ENAME                          JOB                                MGR HIREDATE        SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- -------- ---------- ---------- ----------
      7900 JAMES                          CLERK                             7698 81-12-03        960                    30


Execution Plan
----------------------------------------------------------
Plan hash value: 2949544139

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |    39 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    39 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |     1 |       |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("EMPNO"=7900)

Note 
-----
   - SQL plan baseline "SQL_PLAN_89v381vtjuvg4695cc014" used for this statement


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        889  bytes sent via SQL*Net to client
        512  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

Note の SQL plan baseline "SQL_PLAN_89v381vtjuvg4695cc014" used for this statement という出力から取得した SQL 計画が使用されていることが分かる。