PostgreSQL 如何打印函数调用栈信息

增加了调用堆信息的输出. 可以用于plpgsql debug等.
测试 :
pg94@db-192-168-100-216-> psql
psql (9.4devel)
Type "help" for help.

digoal=# -- access to call stack
digoal=# create or replace function inner_func(int)
digoal-# returns int as $$
digoal$# declare _context text;
digoal$# begin
digoal$#   get diagnostics _context = pg_context;
digoal$#   raise notice '***%***', _context;
digoal$#   return 2 * $1;
digoal$# end;
digoal$# $$ language plpgsql;
CREATE FUNCTION
digoal=#
digoal=# create or replace function outer_func(int)
digoal-# returns int as $$
digoal$# begin
digoal$#   return inner_func($1);
digoal$# end;
digoal$# $$ language plpgsql;
CREATE FUNCTION
digoal=#
digoal=# create or replace function outer_outer_func(int)
digoal-# returns int as $$
digoal$# begin
digoal$#   return outer_func($1);
digoal$# end;
digoal$# $$ language plpgsql;
CREATE FUNCTION
digoal=#
digoal=# select outer_outer_func(10);
NOTICE:  ***PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS
PL/pgSQL function outer_func(integer) line 3 at RETURN
PL/pgSQL function outer_outer_func(integer) line 3 at RETURN***
CONTEXT:  PL/pgSQL function outer_func(integer) line 3 at RETURN
PL/pgSQL function outer_outer_func(integer) line 3 at RETURN
 outer_outer_func
------------------
               20
(1 row)

以下SQL :
digoal$#   get diagnostics _context = pg_context;
digoal$#   raise notice '***%***', _context;
将call stack的信息打印出来如下 :
NOTICE:  ***PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS
PL/pgSQL function outer_func(integer) line 3 at RETURN
PL/pgSQL function outer_outer_func(integer) line 3 at RETURN***
CONTEXT:  PL/pgSQL function outer_func(integer) line 3 at RETURN
PL/pgSQL function outer_outer_func(integer) line 3 at RETURN
对于一些敏感函数, 如果要跟踪被调用或者间接调用的情况, 可以把stack的信息输出到表中 例如.
digoal=#  create table if not exists rec_inner_func_called (id serial8 primary key, info text, crt_time timestamp default clock_timestamp());
digoal=#
create or replace function inner_func(int)
returns int as $$
declare _context text;
begin
  get diagnostics _context = pg_context;
  insert into rec_inner_func_called(info) values (_context);
  return 2 * $1;
end;
$$ language plpgsql;
CREATE FUNCTION

digoal=# select outer_outer_func(10);
 outer_outer_func
------------------
               20
(1 row)

digoal=# select * from rec_inner_func_called;
 id |                              info                               |          crt_time
----+-----------------------------------------------------------------+----------------------------
  1 | PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS+| 2013-07-26 09:19:32.588016
    | PL/pgSQL function outer_func(integer) line 3 at RETURN         +|
    | PL/pgSQL function outer_outer_func(integer) line 3 at RETURN    |
(1 row)
digoal=# select outer_outer_func(100);
 outer_outer_func
------------------
              200
(1 row)

digoal=# select outer_outer_func(100);
 outer_outer_func
------------------
              200
(1 row)

digoal=#
digoal=#
digoal=# select * from rec_inner_func_called;
 id |                              info                               |          crt_time
----+-----------------------------------------------------------------+----------------------------
  1 | PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS+| 2013-07-26 09:19:32.588016
    | PL/pgSQL function outer_func(integer) line 3 at RETURN         +|
    | PL/pgSQL function outer_outer_func(integer) line 3 at RETURN    |
  2 | PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS+| 2013-07-26 09:19:46.031669
    | PL/pgSQL function outer_func(integer) line 3 at RETURN         +|
    | PL/pgSQL function outer_outer_func(integer) line 3 at RETURN    |
  3 | PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS+| 2013-07-26 09:20:30.25935
    | PL/pgSQL function outer_func(integer) line 3 at RETURN         +|
    | PL/pgSQL function outer_outer_func(integer) line 3 at RETURN    |
  4 | PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS+| 2013-07-26 09:20:32.665713
    | PL/pgSQL function outer_func(integer) line 3 at RETURN         +|
    | PL/pgSQL function outer_outer_func(integer) line 3 at RETURN    |
(4 rows)

[参考]
1. http://www.postgresql.org/docs/devel/static/plpgsql-control-structures.html#PLPGSQL-DIAGNOSTICS
时间: 2024-09-12 03:37:27

PostgreSQL 如何打印函数调用栈信息的相关文章

在C/C++程序里打印调用栈信息

我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如果能让程序自己输出调用栈,那是最好不过了.本文介绍和调用椎栈相关的几个函数.   NAME       backtrace, backtrace_symbols, backtrace_symbols_fd - support for application self-debugging SYNOPSIS       #include

GDB查看栈信息

当程序被停住了,你需要做的第一件事就是查看程序是在哪里停住的.当你的程序调用了一个函数,函数的地址,函数参数,函数内的局部变量都会被压入"栈"(Stack)中.你可以用GDB命令来查看当前的栈中的信息. 下面是一些查看函数调用栈信息的GDB命令: backtracebt 打印当前的函数调用栈的所有信息.如:&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp;(gdb) bt#0  func (n=2

源代码-怎么样再linux下查看dump_stack()函数打印出来的信息?

问题描述 怎么样再linux下查看dump_stack()函数打印出来的信息? 本人Linux小白,刚学没多久,最近我想要研究下linux中打开文件操作的流程,于是我就在内核的filp open()函数的源代码中插入了dump_stack_()函数. 我重新编译内核之后,直接在终端调用cd 命令行,然后想在系统日志里面看看有没有 函数调用打印出来,但是翻来翻去好像什么都没有的样子. 但是我自己写一个简单的模块,里面有dump_stack_函数,在编译模块,再运行这个模块, 这样的话又可以在日志里

Linux Debugging(一): 使用反汇编理解C++程序函数调用栈

        拿到CoreDump后,如果看到的地址都是????,那么基本上可以确定,程序的栈被破坏掉了.GDB也是使用函数的调用栈去还原"事故现场"的.因此理解函数调用栈,是使用GDB进行现场调试或者事后调试的基础,如果不理解调用栈,基本上也从GDB得不到什么有用的信息.当然了,也有可能你非常"幸运", 一个bt就把哪儿越界给标出来了.但是,大多数的时候你不够幸运,通过log,通过简单的code walkthrough,得不到哪儿出的问题:或者说只是推测,不能确

函数调用栈的获取原理分析【转】

转自:http://hutaow.com/blog/2013/10/15/dump-stack/ 上一篇文章<在Linux程序中输出函数调用栈>,讲述了在Linux中如何利用backtrace获取调用栈,本篇文章主要介绍一下获取函数调用栈的原理,并给出相应的实现方式. 要了解调用栈,首先需要了解函数的调用过程,下面用一段代码作为例子: #include <stdio.h> int add(int a, int b) { int result = 0; result = a + b;

用spring AOP做日志管理 执行controller的时候 打印当前用户信息

问题描述 用spring AOP做日志管理 执行controller的时候 打印当前用户信息 主要知道是哪些用户了执行了哪些controller,是否执行成功了.现在有个问题就是,获取不到当前用户信息. 解决方案 用户登录时用session绑定 其他请求时在通过session获取 这样就行吧

android程序,在运行时莫名的死掉,只打印一堆GC信息,其他调试信息看不到

问题描述 android程序,在运行时莫名的死掉,只打印一堆GC信息,其他调试信息看不到 这个程序主要开辟子线程,从服务器获取图片的url,然后利用url从网络下载图片的.运行时,不知何种原因,莫名的死掉,只能打印出一堆GC信息 解决方案 检查你用的这台手机,后台Log开关是否打开了. 百度一下 解决方案二: 从你的描述看,应该是低配置机器的java虚拟机heapsize设置得比较小造成的. 你可以参考下面这个链接,修改一下你的Manifest文件试试. 如果低端机的本身限制了Heapsize,

tomcat-服务器日志打印了这些信息

问题描述 服务器日志打印了这些信息 {"cmd","/c","@echo","open","120.27.54.108>>Ex.dat&@echo","asd>>Ex.dat&@echo","asd>>Ex.dat&@echo","bin>>Ex.dat&@echo",

惠普今天宣布已经收购云打印和管理信息系统软件厂商Hiflex

北京时间12月6日消息,据国外媒体报道,惠普今天宣布该公司已经收购云打印和管理信息系统软件厂商Hiflex.惠普和Hiflex均未披露收购协议的财务条款. Hiflex成立于1991年,总部位于德国.被惠普收购后,Hiflex将继续开发现有产品和服务. 惠普成像和打印集团执行副总裁沃迈斯·乔什(Vyomesh Joshi)表示,"惠普希望打破企业客户在如何以及在哪里打印文档的传统障碍,使他们能方便地随时随地打印定制或个性化文档.Hiflex的技术为我们实现这一目标提供了一个强大的平台,将成为我们