--//按照https://nenadnoveljic.com/blog/tracing-library-cache-locks/介绍:
In order to close this gap I, first, examined the following two Oracle C functions on the release 19.6.0.0.200114:
kgllkal and kglGetSO.
kgllkal allocates a library cache lock. It receives the following arguments:
rdx: handle address
rcx: lock mode
Further, it calls kglGetSO to allocate the library cache state object. kglGetSO returns the lock address.
--//按照介绍调用kglGetSO返回lock address.我推测 library cache pind的pin地点也是类似的情况。
$ ./lookup.awk kglGetSO
kglGetSO : kernel generic library cache management get state object
3.编写脚本如下:
$ cat lkpn.gdb2
set pagination off
set logging file /tmp/lkpn.log
set logging overwrite on
set logging on
set $lk = 0
set $pn = 0
set $lock = 0
#break kglpnal if $rcx==3
break kglpnal if ($rcx=3 && $rdx=0x00000000635F4DA0)
commands
silent
printf "kglpnal count %02d -- handle address: %016x, mode: %d ", ++$pn ,$rdx ,$rcx
echo kglnaobj address:
x/s $rdx+0x1c8
c
end
(gdb) c
Continuing.
Program received signal SIGUSR2, User defined signal 2.
0x00007f35cee68fca in semtimedop () at ../sysdeps/unix/syscall-template.S:81
/usr/src/debug/glibc-2.17-c758a686/sysdeps/unix/syscall-template.S:81:3374:beg:0x7f35cee68fca
--//有了前面的信息,改写脚本如下:
$ cat lkpn.gdb2
set pagination off
set logging file /tmp/lkpn.log
set logging overwrite on
set logging on
set $lk = 0
set $pn = 0
set $lock = 0
#break kgllkal if $rcx==3
#break kgllkal if ( $rcx==3 && $rdx==0x00000000670C9E58 )
#break kgllkal if $rdx==0x00000000670C9E58
break kgllkal
condition 1
commands
silent
printf "kgllkal count %02d -- handle address: %016x, mode: %d ", ++$lk ,$rdx ,$rcx
echo kglnaobj address:
x/s $rdx+0x1c8
c
end
#break kglpnal if $rcx==3
#break kglpnal if $rdx==0x00000000635F4DA0
break kglpnal
commands
silent
printf "kglpnal count %02d -- handle address: %016x, mode: %d ", ++$pn ,$rdx ,$rcx
echo kglnaobj address:
x/s $rdx+0x1c8
c
end
#break kglGetSO
#commands
# silent
# finish
#end
break *0x0000000015367fbe
commands
silent
printf "kglGetS0 return lock address : %016x\n", $rdx
c
end
break *0x1536c16a
commands
silent
printf "kglGetS0 return pin address : %016x\n", $rdx
c
end
--//注:调用kgllkal在调用kglGetS0的返回停止在0x15367fbe地点时,对应寄存器rdx的就是lock地点(推测)。
4.继续测试,验证lock address是否精确。
--//session 3,再打开新的会话:
SCOTT@book01p(272,12390)> @spid
SID SERIAL# PROCESS SERVER SPID PID P_SERIAL# C50
---------- ---------- ------------------------ --------- ------------------------------ ------- ---------- --------------------------------------------------
272 12390 6427 DEDICATED 6429 70 20 alter system kill session '272,12390' immediate;
--//window 1:
$ rlgdb -f -p 6429 -x lkpn.gdb2
...
/usr/src/debug/glibc-2.17-c758a686/sysdeps/unix/syscall-template.S:81:3374:beg:0x7f931703e480
Breakpoint 1 at 0x15367e90
Breakpoint 2 at 0x1536c020
Breakpoint 3 at 0x15367fbe
Breakpoint 4 at 0x1536c16a
(gdb) c
--//重复前面的测试,只不外这次是3个会话。
--//session 1:
SCOTT@book01p(412,5770)> exec lcp
--//session 2:
SCOTT@book01p(148,4168)> set timing on
SCOTT@book01p(148,4168)> alter procedure lcp compile;
--//挂起!!
--//session 4:
SCOTT@book01p(272,12390)> set timing on
SCOTT@book01p(272,12390)> alter procedure lcp compile;
--//挂起!!