Java SVC Dump analyzer

To be completed!

Overview

This is an SVC Dump analyzer written in Java. It provides an alternative to using IPCS. In answer to the obvious question "why?", this analyzer provides the following benefits:

Here is some sample output:

found Usta TCB a7e288 tid 1ac30e20 caa 109f5120
Dsa         Entry       Offset      Function
---         -----       ------      --------
10a06d90    11aa58d8    fff8909a    SYSTDUMP
10a06940    11a90c48    00000414    ThreadUtils_CoreDump
10a06830    11a734b0    000004b2    userSignalHandler
10a06780    11a73a18    000000b8    intrDispatch
10a066c8    061596b8    000000c4    @@GETFN
10a06068    0628af48    0000075e    __zerros
10a034d0    00000008    0638260e    null
10a02a70    11a566d0    fefac3f8    CompareAndSwap_Impl
10a029c0    119223f0    000000a2    pin_object
10a02918    11740c40    00000114    jni_GetPrimitiveArrayElements
10a02710    1af1a388    000000b2    MVS_CcicsInit
10a02660    1af143b8    000000b0    Java_com_ibm_ctg_server_ServerECIRequest_CcicsInit
10a025a8    06419078    0000005c    CEEPGTFN
10a02118    119a20d0    00000138    MMIPSJNI
10a02038    1199fd48    000003ce    mmisInvokeJniMethodHelper  (com/ibm/ctg/server/ServerECIRequest.CcicsInit)
10a01f68    1198e3f8    00000100    mmipInvokeJniMethod  (com/ibm/ctg/server/ServerECIRequest.CcicsInit)
10a01e78    1198ed80    0000099e    mmipInvokeJavaMethod  (com/ibm/ctg/server/ServerECIRequest.initTrace)
10a01d88    1198ed80    0000099e    mmipInvokeJavaMethod  (com/ibm/ctg/server/ServerECIRequest.initialize)
10a01c80    1198ed80    0000099e    mmipInvokeJavaMethod  (com/ibm/ctg/client/LocalJavaGateway.flow)
10a01b90    1198ed80    0000099e    mmipInvokeJavaMethod  (com/ibm/ctg/client/JavaGateway.flow)


Usage

java -classpath svcdump.jar com.ibm.jvm.svcdump.Dump [-options] <filename>

where options can be one of:

-heap
print a table showing which classes have the most objects allocated
-cache
print alloc cache
-dis <addr> <n>
disassemble <n> instructions starting at <addr> (hex)
-caa <addr>
specify the caa to use when disassembling
-r<n>
include saved register <n> in stack trace
-verbose
print extra info for debugging purposes
-help
print extended help info and exit

these options are described in more detail below. If you want to run FindRoots, type

java -classpath svcdump.jar com.ibm.jvm.findroots.FindRoots -help

for more details.

-heap

Print a table showing which classes have the most objects allocated.

-cache

Print the Java alloc cache. This can give an idea of the most recently allocated objects since they will still be in the cache.

Sample output:

alloc cache info:
cache_busy = 0x0
cache_size = 0x7bbc
cache_block = 0x14208ef0
cache_orig_size = 0x10004
14210aac: len = 20 methods = efd7ee0 flags = 0 class = java/lang/String
14210acc: len = 70 methods = 32 flags = 2a
14210b3c: len = 68 methods = 2c flags = 2a
14210ba4: len = 20 methods = efd7ee0 flags = 0 class = java/lang/String
14210bc4: len = 20 methods = 110c4d00 flags = 0 class = java/lang/ref/Finalizer
14210be4: len = 20 methods = 110c7560 flags = 0 class = java/lang/ClassLoader$NativeLibrary
14210c04: len = 20 methods = efd7ee0 flags = 0 class = java/lang/String
14210c24: len = 50 methods = 1f flags = 2a
14210c74: len = 20 methods = efd7ee0 flags = 0 class = java/lang/String

-dis <addr> <n>

Disassemble <n> instructions starting at the hex address <addr>. The disassembler is not complete but it knows about the most common instructions. When it comes across an instruction it doesn't understand it will throw an exception and exit. This is usually because it has gone past the end of the function. I'll probably clean this up eventually but it seems good enough for now.

Sample output:

Disassembly starting at 0x11a90c48
0x11a90c48: (0x00000000): B      x'22'($r15)
0x11a90c6a: (0x00000022): STM    $r14,$r11,x'c'($r13)
0x11a90c6e: (0x00000026): L      $r14, x'4c'($r13)
0x11a90c72: (0x0000002a): LA     $r0, x'450'($r14)
0x11a90c76: (0x0000002e): CL     $r0, x'314'($r12)
0x11a90c7a: (0x00000032): LA     $r3, x'3a'($r15)
0x11a90c7e: (0x00000036): BGT    x'14'($r15)
0x11a90c82: (0x0000003a): L      $r15, x'280'($r12)
0x11a90c86: (0x0000003e): STM    $r15,$r0,x'48'($r14)
0x11a90c8a: (0x00000042): MVI    x'0'($r14), x'10'
0x11a90c8e: (0x00000046): ST     $r13, x'4'($r14)
0x11a90c92: (0x0000004a): LR     $r13, $r14
0x11a90c94: (0x0000004c): L      $r4, x'1f4'($r12)
0x11a90c98: (0x00000050): L      $r5, x'7ae'($r3)
0x11a90c9c: (0x00000054): LA     $r2, x'c4'($r13)
0x11a90ca0: (0x00000058): LA     $r1, x'98'($r13)
0x11a90ca4: (0x0000005c): ST     $r2, x'98'($r13)
0x11a90ca8: (0x00000060): L      $r14, x'170'($r5,$r4)
0x11a90cac: (0x00000064): LM     $r15,$r0,x'8'($r14)
0x11a90cb0: (0x00000068): ST     $r0, x'1f4'($r12)
0x11a90cb4: (0x0000006c): BALR   $r14, $r15
0x11a90cb6: (0x0000006e): L      $r7, x'7b2'($r3)
0x11a90cba: (0x00000072): L      $r6, x'174'($r5,$r4)
0x11a90cbe: (0x00000076): LA     $r0, x'f4'($r13)
0x11a90cc2: (0x0000007a): ST     $r0, x'ac'($r13)
0x11a90cc6: (0x0000007e): LA     $r1, x'407'($r7)
0x11a90cca: (0x00000082): LA     $r14, x'fc'($r13)
0x11a90cce: (0x00000086): LA     $r10, x'234'($r13)
0x11a90cd2: (0x0000008a): ST     $r1, x'9c'($r13)
0x11a90cd6: (0x0000008e): LA     $r11, x'41c'($r7)
0x11a90cda: (0x00000092): LM     $r15,$r0,x'8'($r6)
0x11a90cde: (0x00000096): ST     $r10, x'98'($r13)
0x11a90ce2: (0x0000009a): ST     $r11, x'438'($r13)
0x11a90ce6: (0x0000009e): ST     $r11, x'a0'($r13)
0x11a90cea: (0x000000a2): ST     $r2, x'a4'($r13)
0x11a90cee: (0x000000a6): LA     $r1, x'98'($r13)
0x11a90cf2: (0x000000aa): ST     $r14, x'a8'($r13)
0x11a90cf6: (0x000000ae): ST     $r0, x'1f4'($r12)
0x11a90cfa: (0x000000b2): BALR   $r14, $r15

-caa <addr>

Specify the hex caa address to use when disassembling. This is for future use when I figure out how to get the address of functions.

-r<n>

Include saved register <n> in stack trace.

Sample output:

found Usta TCB a7e288 tid 1ac30e20 caa 109f5120
Dsa         Entry       Offset      r12         Function
---         -----       ------      ---         --------
10a06d90    11aa58d8    fff8909a    109f5120    SYSTDUMP
10a06940    11a90c48    00000414    109f5120    ThreadUtils_CoreDump
10a06830    11a734b0    000004b2    0ef473a0    userSignalHandler
10a06780    11a73a18    000000b8    40404040    intrDispatch
10a066c8    061596b8    000000c4    40404040    @@GETFN
10a06068    0628af48    0000075e    109f5120    __zerros
10a034d0    00000008    0638260e    109f5120    null
10a02a70    11a566d0    fefac3f8    00000000    CompareAndSwap_Impl
10a029c0    119223f0    000000a2    109f5120    pin_object
10a02918    11740c40    00000114    109f5120    jni_GetPrimitiveArrayElements
10a02710    1af1a388    000000b2    109f5120    MVS_CcicsInit
10a02660    1af143b8    000000b0    109f5120    Java_com_ibm_ctg_server_ServerECIRequest_CcicsInit
10a025a8    06419078    0000005c    109f5120    CEEPGTFN
10a02118    119a20d0    00000138    109f5120    MMIPSJNI
10a02038    1199fd48    000003ce    109f5120    mmisInvokeJniMethodHelper  (com/ibm/ctg/server/ServerECIRequest.CcicsInit)
10a01f68    1198e3f8    00000100    109f5120    mmipInvokeJniMethod  (com/ibm/ctg/server/ServerECIRequest.CcicsInit)


Internals

You don't want to know! I couldn't find any documentation on SVC dumps so I reverse-engineered it. There are lots of ugly heuristics in use that I developed through trial and error. Dave Clarke has also been a goldmine of information.

Feedback

Please send comments and suggestions to me at dgriff@hursley.ibm.com.

Thanks!