nioqrc oracle,oracle trouble shooting 时看 call stack

call stack 和system call 的区别!

在ORACLE 中我们常用call stack 来匹配是否命中某些bug,这时查看call stack 中的函数调用路径来进一步印证。

在某些情况下,例如进程执行慢,我又会通过strace ,truss 来追踪某个进程,查看其系统调用 情况。

那么call stack 和system call 的区别是什么?

首先说system call:

操作系统通过系统调用为运行于其上的进程提供服务。

当用户态进程发起一个系统调用,

CPU 将切换到

内核态 并开始执行一个

内核函数 。 内核函数负责响应应用程序的要求,例如操作文件、进行网络通讯或者申请内存资源等。

那么,在应用程序内,调用一个系统调用的流程是怎样的呢?

我们以一个假设的系统调用

xyz 为例,介绍一次系统调用的所有环节。

7aa65a33af3a409f662c767e74d16c17.png

如上图,系统调用执行的流程如下:

应用程序 代码调用系统调用(

xyz ),该函数是一个包装系统调用的 库函数 ;包装装函数的名称与其调用的系统调用的名称相同。例如,glibc包含一个函数truncate(),该函数调用底层的“ truncate”系统调用。

库函数 (

xyz )负责准备向内核传递的参数,并触发 软中断 以切换到内核;

CPU 被

软中断 打断后,执行

中断处理函数 ,即

系统调用处理函数 ( system_call);

系统调用处理函数 调用 系统调用服务例程 (

sys_xyz ),真正开始处理该系统调用;

call stack:

调用堆栈是从程序开始到当前程序执行时所调用的函数的名称列表。

system call 和call stack主要区别在于,call stack跟踪包括应用程序(Oracle进程)的被调用方法或函数,而system call跟踪仅包括对操作系统内核的(函数)请求。

以下追踪一个select语句就可以看出差异:

这里采用strace来跟踪系统调用和stack来跟踪调用堆栈。

SQL> select sid from v$mystat where rownum=1;

SID

----------

37

SQL> select paddr from v$session where sid=37;

PADDR

----------------

00000000902080E8

SQL> select spid from v$process where addr='00000000902080E8';

SPID

------------------------

30091

alter system flush buffer_cache;

SQL>  alter system flush buffer_cache;

System altered.

alter session set "_serial_direct_read" = TRUE;

select * from cwdtest;

此时抓取pstack,call stack情况:

6fa743ebabf2e5e40c5f8b2bc98332c2.png

抓取strace(system call情况)

2220f9525b9c097afbf49ab8d95b3971.png

从以上可以看出system call 是看不到调用它们的应用程序代码或函数。

使用oradebug 会改变代码的常规路径,因此打印出来的call stack后面是无需关注:

再次拿以上的pstack情况来看:

6fa743ebabf2e5e40c5f8b2bc98332c2.png

同样的进程,我们使用oradebug 来打印堆栈:

SQL> oradebug SHORT_STACK

ksedsts()+465

SQL>  oradebug SHORT_STACK

ksedsts()+465

整理pstack打印堆栈是:

main-(calls)-> ssthrdmain-(calls)-> opimai_real->(calls)-> sou2o-(calls)-> opidrv-(calls)->opiodr->(calls)->opiino()-> opitsk->(calls)-> opikndf2->(calls)-> nioqrc->(calls)-> nsbrecv->(calls)-> nsbasic_brc->(calls)-> ntpfprd->(calls)-> sntpread ->(calls)->read

整理oradebug打印的堆栈是:

main-(calls)-> ssthrdmain-(calls)-> opimai_real->(calls)-> sou2o-(calls)-> opidrv-(calls)->opiodr->(calls)->opiino()-> opitsk->(calls)-> opikndf2->(calls)-> nioqrc->(calls)-> nsbrecv->(calls)-> nsbasic_brc->(calls)-> ntpfprd->(calls)-> sntpread  -(calls)->read -(calls)-> __sighandler -(calls)-> sspuser -(calls)->ksdxcb -(calls)-> ksdxfstk-(calls)->ksedsts

从上面整理的堆栈调用就可以看出,oradebug 多出了__sighandler -(calls)-> sspuser -(calls)->ksdxcb -(calls)-> ksdxfstk-(calls)->ksedsts的几个函数的调用,这其实是通过oradebug转储堆栈引起的,在oracle 的 diag trace中也是如此,在排查故障时可以忽略这一部分,

oradebug运行“ short_stack”跟踪,则将更改Oracle的常规代码路径。

OS工具的行为有所不同,因为它们通常会暂停进程并转储堆栈。

参考文献

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值