GDB: core_analyzer

## core analyzer

https://sourceforge.net/projects/core-analyzer/files/Core%20Analyzer/ から、バージョン　2.16 がダウンロードできます。
わたしは、core_analyzer の Print General Core Information くらいしか利用した事がありませんが、core ファイルのメモリマップの把握として使っています。

## 出力例

```
$ ./core_analyzer /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131.x86_64/bin/java ./core.*
Please input the address of variable main_arena
You can find it by command "(gdb)print &main_arena"
main_arena ? 0x3d82d8e120
Please input the address of variable mp_
You can find it by command "(gdb)print &mp_"
mp_ ? 0x3d82d90720
Warning: 56 mmap memory blocks were found while mp_ reports 16
******************************************************************
** Core Analyzer version 2.16                                   **
** Please report bugs to: Michael Yan (myan@gmail.com)          **
******************************************************************

Main Menu:
[0] Print General Core Information
[1] Find References to an Object (horizontal search)
[2] What Is This Address and Underlying Object Type (vertical search)
[3] Objects Shared Between Threads
[4] Memory Pattern Analysis
[5] Query Heap Memory Block
[6] Page Walk (check the integrity of surrounding memory blocks)
[7] Heap Walk (check the whole heap for corruption and memory usage stats)
[8] Biggest Heap Memory Blocks
[9] Biggest Heap Memory Owners(variables)
[10] Heap Memory Leak Candidates
[11] Quit
Select [0-11]: 0
NOTE
        [0] name: CORE type: PRPSINFO
                process_state=T
                filename=java [java -verbose UnloadableClassLoader /home/imai/Java/myapp.jar com.example.myapp.]
        [1] name: CORE type: PRSTATUS
                pid=4040 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d8320e82d %rsp=0x7f16681f31d0
        [2] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [3] name: LINUX type: 514
        [4] name: CORE type: PRSTATUS
                pid=4041 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d8320b68c %rsp=0x7f166042a8a0
        [5] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [6] name: LINUX type: 514
        [7] name: CORE type: PRSTATUS
                pid=4042 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d8320b68c %rsp=0x7f1660329920
        [8] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [9] name: LINUX type: 514
        [10] name: CORE type: PRSTATUS
                pid=4043 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d8320ba5e %rsp=0x7f165d308870
        [11] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [12] name: LINUX type: 514
        [13] name: CORE type: PRSTATUS
                pid=4044 signal=0 user_time=0.0sec sys_time=0.0sec
        [14] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [15] name: LINUX type: 514
        [16] name: CORE type: PRSTATUS
                pid=4045 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d8320b68c %rsp=0x7f165d1064e0
        [17] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [18] name: LINUX type: 514
        [19] name: CORE type: PRSTATUS
                pid=4046 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d8320da00 %rsp=0x7f165d005930
        [20] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [21] name: LINUX type: 514
        [22] name: CORE type: PRSTATUS
                pid=4047 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d8320b68c %rsp=0x7f165cf04a30
        [23] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [24] name: LINUX type: 514
        [25] name: CORE type: PRSTATUS
                pid=4048 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d8320b68c %rsp=0x7f165ce03ab0
        [26] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [27] name: LINUX type: 514
        [28] name: CORE type: PRSTATUS
                pid=4049 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d8320b68c %rsp=0x7f165cd027c0
        [29] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [30] name: LINUX type: 514
        [31] name: CORE type: PRSTATUS
                pid=4050 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d8320ba5e %rsp=0x7f165cc01910
        [32] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [33] name: LINUX type: 514
        [34] name: CORE type: PRSTATUS
                pid=4039 signal=0 user_time=0.0sec sys_time=0.0sec
                %rip=0x3d832082fd %rsp=0x7ffe7bb92c30
        [35] name: CORE type: FPREGSET [fpregset struct]
                floating point register set
        [36] name: LINUX type: 514
        [37] name: CORE type: AUXV
                type=33
                type=16 hardware_capability=395049983
                type=6  pagesize=4096
                type=17 frequency_of_times()=100
                type=3  &phdr[0]=0x400040
                type=4  sizeof(phdr[0])=56
                type=5  #phdr_entries=8
                type=7  ld.so_base_addr=0x0
                type=8  proc_flags=0x0
                type=9  entry_point=0x400610
                type=11 real_uid=0
                type=12 effective_uid=0
                type=13 real_gid=0
                type=14 effective_gid=0
                type=23 was_exec_setuid-like? NO
                type=25
                type=31
                type=15 plat_name=0x7ffe7bb97279

No.                vaddr       memsz      filesz     perm    name
=================================================================
[  0]           0x600000        8192        8192      RW-   [ .data ]  [ /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131.x86_64/bin/java ]
[  1]          0x14cc000      135168      135168      RW-   [ heap ]
[  2]         0xbea00000    53477376    53477376      RW-   [ heap ]
[  3]         0xc1d00000   120586240   120586240      RW-   [ unknown ]
[  4]         0xc9000000   212860928   212860928      RW-   [ .data ]  [ /lib64/libm.so.6 ]
[  5]         0xd5b00000   402128896   402128896      RW-   [ .data ]  [ /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131.x86_64/jre/bin/../lib/amd64/jli/libjli.so ]
[  6]         0xeda80000   307757056   307757056      RW-   [ .data ]  [ /lib64/libpthread.so.0 ]
[  7]       0x3d8241f000        8192        8192      R--   [ .rodat]  [ /lib64/ld-linux-x86-64.so.2 ]
[  8]       0x3d82421000        4096        4096      RW-   [ unknown ]
[  9]       0x3d82422000        4096        4096      RW-   [ .data ]  [ /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131.x86_64/bin/java ]
[ 10]       0x3d82802000        4096        4096      R--   [ .rodat]  [ /lib64/libdl.so.2 ]
[ 11]       0x3d82803000        4096        4096      RW-   [ unknown ]
[ 12]       0x3d82d8a000       16384       16384      R--   [ .rodat]  [ /lib64/libc.so.6 ]
[ 13]       0x3d82d8e000        8192        8192      RW-   [ unknown ]
[ 14]       0x3d82d90000       16384       16384      RW-   [ unknown ]
[ 15]       0x3d8300c000        4096        4096      RW-   [ .data ]  [ /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131.x86_64/jre/bin/../lib/amd64/jli/libjli.so ]
[ 16]       0x3d83417000        4096        4096      R--   [ .rodat]  [ /lib64/libpthread.so.0 ]
[ 17]       0x3d83418000        4096        4096      RW-   [ unknown ]
[ 18]       0x3d83419000       16384       16384      RW-   [ unknown ]
[ 19]       0x3d83806000        4096        4096      R--   [ .rodat]  [ /lib64/librt.so.1 ]
[ 20]       0x3d83807000        4096        4096      RW-   [ unknown ]
[ 21]       0x3d83c15000        4096        4096      RW-   [ unknown ]
[ 22]       0x3d8c815000        4096        4096      RW-   [ .data ]  [ /lib64/libgcc_s.so.1 ]
[ 23]       0x3d8e0e8000       28672       28672      R--   [ .rodat]  [ /usr/lib64/libstdc++.so.6 ]
[ 24]       0x3d8e0ef000        8192        8192      RW-   [ unknown ]
[ 25]       0x3d8e0f1000       86016       86016      RW-   [ unknown ]
[ 26]     0x7f160c000000     4468736     4468736      RW-   [ heap ]
[ 27]     0x7f160c443000    62640128    62640128      R--   [ unknown ]
[ 28]     0x7f1614000000    66998272    66998272      RW-   [ heap ]
[ 29]     0x7f1617fe5000      110592      110592      R--   [ unknown ]
[ 30]     0x7f161c000000    67051520    67051520      RW-   [ heap ]
[ 31]     0x7f161fff2000       57344       57344      R--   [ unknown ]
[ 32]     0x7f1624000000    67076096    67076096      RW-   [ heap ]
[ 33]     0x7f1627ff8000       32768       32768      R--   [ unknown ]
[ 34]     0x7f1628000000    67043328    67043328      RW-   [ heap ]
[ 35]     0x7f162bff0000       65536       65536      R--   [ unknown ]
[ 36]     0x7f162c000000      135168      135168      RW-   [ heap ]
[ 37]     0x7f162c021000    66973696    66973696      R--   [ unknown ]
[ 38]     0x7f1630000000      135168      135168      RW-   [ heap ]
[ 39]     0x7f1630021000    66973696    66973696      R--   [ unknown ]
[ 40]     0x7f1634000000    12283904    12283904      RW-   [ heap ]
[ 41]     0x7f1634bb7000    54824960    54824960      R--   [ unknown ]
[ 42]     0x7f1638000000     9154560     9154560      RW-   [ heap ]
[ 43]     0x7f16388bb000    57954304    57954304      R--   [ unknown ]
[ 44]     0x7f163c000000      135168      135168      RW-   [ heap ]
[ 45]     0x7f163c021000    66973696    66973696      R--   [ unknown ]
[ 46]     0x7f1648000000      135168      135168      RW-   [ heap ]
[ 47]     0x7f1648021000    66973696    66973696      R--   [ unknown ]
[ 48]     0x7f164c000000      135168      135168      RW-   [ heap ]
[ 49]     0x7f164c021000    66973696    66973696      R--   [ unknown ]
[ 50]     0x7f1650000000     1060864     1060864      RW-   [ heap ]
[ 51]     0x7f1650103000    66048000    66048000      R--   [ unknown ]
[ 52]     0x7f1654000000      135168      135168      RW-   [ heap ]
[ 53]     0x7f1654021000    66973696    66973696      R--   [ unknown ]
[ 54]     0x7f1658000000      872448      872448      RW-   [ heap ]
[ 55]     0x7f16580d5000    66236416    66236416      R--   [ unknown ]
[ 56]     0x7f165cb02000        4096        4096      R--   [ unknown ]
[ 57]     0x7f165cb03000     1048576     1048576      RW-   [ stack ]  [ tid=11 ]
[ 58]     0x7f165cc03000       12288       12288      R--   [ unknown ]
[ 59]     0x7f165cc06000     1040384     1040384      RW-   [ stack ]  [ tid=10 ]
[ 60]     0x7f165cd04000       12288       12288      R--   [ unknown ]
[ 61]     0x7f165cd07000     1040384     1040384      RW-   [ stack ]  [ tid=9 ]
[ 62]     0x7f165ce05000       12288       12288      R--   [ unknown ]
[ 63]     0x7f165ce08000     1040384     1040384      RW-   [ stack ]  [ tid=8 ]
[ 64]     0x7f165cf06000       12288       12288      R--   [ unknown ]
[ 65]     0x7f165cf09000     1040384     1040384      RW-   [ stack ]  [ tid=7 ]
[ 66]     0x7f165d007000       12288       12288      R--   [ unknown ]
[ 67]     0x7f165d00a000     1040384     1040384      RW-   [ stack ]  [ tid=6 ]
[ 68]     0x7f165d108000       12288       12288      R--   [ unknown ]
[ 69]     0x7f165d10b000     1040384     1040384      RW-   [ stack ]  [ tid=5 ]
[ 70]     0x7f165d209000        4096        4096      R--   [ unknown ]
[ 71]     0x7f165d20a000    11231232    11231232      RW-   [ heap ]
[ 72]     0x7f165de76000    37437440    37437440      RW-   [ heap ]
[ 73]     0x7f166022a000        4096        4096      R--   [ unknown ]
[ 74]     0x7f166022b000     1048576     1048576      RW-   [ stack ]  [ tid=3 ]
[ 75]     0x7f166032b000        4096        4096      R--   [ unknown ]
[ 76]     0x7f166032c000     1155072     1155072      RW-   [ stack ]  [ tid=2 ]
[ 77]     0x7f1660446000      233472      233472      RW-   [ unknown ]
[ 78]     0x7f166047f000      417792      417792      RW-   [ unknown ]
[ 79]     0x7f16604e5000      786432      786432      RW-   [ unknown ]
[ 80]     0x7f16605a5000      106496      106496      RW-   [ unknown ]
[ 81]     0x7f16605bf000      233472      233472      RW-   [ unknown ]
[ 82]     0x7f16605f8000      417792      417792      RW-   [ unknown ]
[ 83]     0x7f166065e000      782336      782336      RW-   [ unknown ]
[ 84]     0x7f166071d000      602112      602112      RW-   [ unknown ]
[ 85]     0x7f16607b0000        4096        4096      RW-   [ unknown ]
[ 86]     0x7f16607b1000     2555904     2555904      RWX   [ unknown ]
[ 87]     0x7f1660a21000    47775744    47775744      RW-   [ unknown ]
[ 88]     0x7f16639b8000        4096        4096      RW-   [ .data ]  [ /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131.x86_64/jre/lib/amd64/libzip.so ]
[ 89]     0x7f1663bc5000        4096        4096      R--   [ .rodat]  [ /lib64/libnss_files.so.2 ]
[ 90]     0x7f1663bc6000        4096        4096      RW-   [ unknown ]
[ 91]     0x7f1663def000        8192        8192      RW-   [ .data ]  [ /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131.x86_64/jre/lib/amd64/libjava.so ]
[ 92]     0x7f1663ffe000        8192        8192      RW-   [ .data ]  [ /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131.x86_64/jre/lib/amd64/libverify.so ]
[ 93]     0x7f1664000000    67104768    67104768      RW-   [ heap ]
[ 94]     0x7f1667fff000        4096        4096      R--   [ unknown ]
[ 95]     0x7f1668021000      126976      126976      RW-   [ unknown ]
[ 96]     0x7f1668040000      745472      745472      RW-   [ unknown ]
[ 97]     0x7f16680f6000       12288       12288      R--   [ unknown ]
[ 98]     0x7f16680f9000     1040384     1040384      RW-   [ stack ]  [ tid=1 ]
[ 99]     0x7f1668479000        4096        4096      R--   [ .rodat]  [ /lib64/libm.so.6 ]
[100]     0x7f166847a000        4096        4096      RW-   [ unknown ]
[101]     0x7f16691b9000      802816      802816      RW-   [ .data ]  [ /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131.x86_64/jre/lib/amd64/server/libjvm.so ]
[102]     0x7f166927d000      204800      204800      RW-   [ unknown ]
[103]     0x7f16692c4000        4096        4096      RW-   [ unknown ]
[104]     0x7f16692c5000        4096        4096      R--   [ unknown ]
[105]     0x7f16692c6000        4096        4096      RW-   [ unknown ]
[106]     0x7ffe7bb84000       86016       86016      RW-   [ stack ]  [ tid=12 ]
[107]     0x7ffe7bba3000        4096        4096      R-X   [ unknown ]
[108] 0xffffffffff600000        4096        4096      R-X   [ unknown ]

Main Menu:
[0] Print General Core Information
[1] Find References to an Object (horizontal search)
[2] What Is This Address and Underlying Object Type (vertical search)
[3] Objects Shared Between Threads
[4] Memory Pattern Analysis
[5] Query Heap Memory Block
[6] Page Walk (check the integrity of surrounding memory blocks)
[7] Heap Walk (check the whole heap for corruption and memory usage stats)
[8] Biggest Heap Memory Blocks
[9] Biggest Heap Memory Owners(variables)
[10] Heap Memory Leak Candidates
[11] Quit
Select [0-11]: 

```

## core_analyzer 2.16 のインストール

この投稿を書いている時点 2018.5.25 では 2.18 がありますが、RHEL 7 などでは、ライブラリが不足しているとのエラーで動作しません。
そのため旧バージョンですが core_analyzer 2.16 を使います。

```
# mkdir /work
# cd /work

まずは 7zip を適当なところからダウンロード＆インストールします。

● RHEL 6
# wget https://www.mirrorservice.org/sites/dl.fedoraproject.org/pub/epel/6/x86_64/Packages/p/p7zip-16.02-10.el6.x86_64.rpm
# rpm -ivh p7zip-16.02-10.el6.x86_64.rpm 

● RHEL 7
# wget https://www.mirrorservice.org/sites/dl.fedoraproject.org/pub/epel/7/x86_64/Packages/p/p7zip-16.02-10.el7.x86_64.rpm
# rpm -ivh p7zip-16.02-10.el7.x86_64.rpm

core_analyzer_2.16 をダウンロード＆展開します。
# wget https://jaist.dl.sourceforge.net/project/core-analyzer/Core%20Analyzer/core_analyzer_2_16.7z
# 7za x core_analyzer_2_16.7z
...
# chmod 755 ./core_analyzer_2_16/Linux/core_analyzer
```

# core_analyzer にパッチをあてる

ソースコードからのコンパイルは面倒なので、手抜きですがバイナリにパッチをあて起動できるようにします。

```
# ./core_analyzer_2_16/Linux/core_analyzer /work/abc /work/core.1292
The memory manager of glibc 2.17 is not supported in this release
Fail to initialize core analyzer
# 

上記のとおりエラーで起動しないので、glibc のバージョンチェック部分にパッチをあてます。

# gdb -write -q ./core_analyzer_2_16/Linux/core_analyzer
...

(gdb) x/10i  0x40e8b9 
   0x40e8b9 <init_heap()+415>:  mov    0x20617d(%rip),%edx        # 0x614a3c <glibc_ver_minor>
   0x40e8bf <init_heap()+421>:  lea    -0x3(%rdx),%eax
   0x40e8c2 <init_heap()+424>:  cmp    $0x2,%eax
   0x40e8c5 <init_heap()+427>:  jbe    0x40e8eb <init_heap()+465>
   0x40e8c7 <init_heap()+429>:  cmp    $0xc,%edx
   0x40e8ca <init_heap()+432>:  je     0x40e8eb <init_heap()+465>
   0x40e8cc <init_heap()+434>:  mov    0x2061ae(%rip),%esi        # 0x614a80 <glibc_ver_major>
   0x40e8d2 <init_heap()+440>:  mov    $0x411c48,%edi
   0x40e8d7 <init_heap()+445>:  mov    $0x0,%eax
   0x40e8dc <init_heap()+450>:  callq  0x4012f8 <printf@plt>
(gdb) 
(gdb) set {unsigned char}0x40e8c4 = 0x11
(gdb) x/i 0x40e8c2
   0x40e8c2 <init_heap()+424>:  cmp    $0x11,%eax
(gdb) q

変更後、エラーは出ません。

# ./core_analyzer_2_16/Linux/core_analyzer /work/abc /work/core.1292
Please input the address of variable main_arena
You can find it by command "(gdb)print &main_arena"
main_arena ? 
```

**変更している内容**

```diff:./gdbplus/gdb-7.7/gdb/heap_ptmalloc.c
   1417         // Support a subset of all glibc versions
-  1418         if (glibc_ver_minor != 3
-  1419                 && glibc_ver_minor != 4
-  1420                 && glibc_ver_minor != 5
-  1421                 //&& glibc_ver_minor != 11
   1422                 && glibc_ver_minor != 12)
   1423         {
   1424                 CA_PRINT("The memory manager of glibc %d.%d is not supported in this release\n",
   1425                                 glibc_ver_major, glibc_ver_minor);
   1426                 return CA_FALSE;
   1427         }

たぶん上記が以下のように変更されたのと等価のはず？？？

+               if (glibc_ver_minor > 17 && 
                        && glibc_ver_minor != 12)
            
```

## core_analyzer の実行

gdb で main_arena と mp_ を調べた後に実行します。

```
(gdb) p &main_arena
$1 = (<data variable, no debug info> *) 0x7f606ca34760 <main_arena>
(gdb) p &mp_
$2 = (<data variable, no debug info> *) 0x7f606ca341a0 <mp_>
(gdb)

確認しておいたアドレスを、 core_analyzer に入力

# ./core_analyzer_2_16/Linux/core_analyzer  /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64/bin/java /home/imai/Java/core.*
Please input the address of variable main_arena
You can find it by command "(gdb)print &main_arena"
main_arena ? 0x7f606ca34760
Please input the address of variable mp_
You can find it by command "(gdb)print &mp_"
mp_ ? 0x7f606ca341a0

最初に記載した出力が行われます。
```

健忘録としてと、また、何かのヒントになれば幸いです。