DBMS_DEBUG 不支持跨会话断点调试,因其设计为单会话绑定,仅适用于8i–9i,10g起被DBMS_DEBUG_JDWP取代,12c后彻底不可用;跨会话调试须依赖JDWP协议、DEBUG权限、监听配置及带调试信息的编译对象。

DBMS_DEBUG 不支持跨会话断点调试——它只在当前会话内有效,且 Oracle 官方早已弃用该包。 从 10g 起,Oracle 就转向基于 DBMS_DEBUG_JDWP 的 JDWP 协议调试模型;DBMS_DEBUG 在 12c 后彻底不可用,调用会直接报 ORA-00904: "DBMS_DEBUG" invalid identifier 或 PLS-00201: identifier 'DBMS_DEBUG' must be declared。
为什么 DBMS_DEBUG 不能用于跨会话调试
DBMS_DEBUG 是 Oracle 8i–9i 时代的旧调试接口,设计上就是单会话绑定的:它依赖 DBMS_DEBUG.ATTACH_SESSION 主动 attach 到**同一实例内另一个已存在的会话 ID(SID)**,但该操作要求:目标会话必须已显式执行过 DBMS_DEBUG.DEBUG_ON,且未提交或退出。现实中几乎无法协调两个会话的时间窗口、权限与状态。
- 目标会话一旦执行完 PL/SQL 块就自动终止,
ATTACH_SESSION失败 - 即使 attach 成功,断点只能设在当前会话编译的对象上,无法“注入”到别人正在运行的会话代码中
- 无远程监听机制,不支持客户端工具(如 SQL Developer)连接控制
- Oracle 19c 文档已明确标注
DBMS_DEBUG为 deprecated,且默认不安装(需手动运行catdbdebug.sql,但不推荐)
真正可行的跨会话调试替代方案
所谓“跨会话”,实际需求通常是:你在 SQL Developer 里发起一个调用,想停在数据库里另一个用户/会话正在执行的存储过程里。这靠的是 DBMS_DEBUG_JDWP + 客户端监听,而非 DBMS_DEBUG。
- 确保数据库启用远程调试:
ALTER SYSTEM SET remote_debugging = TRUE SCOPE=BOTH(19c+ 还需确认debug_jdwp参数未被禁用) - 调试发起者(你的连接)必须拥有
DEBUG CONNECT SESSION和DEBUG ANY PROCEDURE权限 - 在 SQL Developer 中右键连接 → Start Debugging,看到状态栏显示 “Debugger listening on port XXXX” 才算就绪
- 触发目标过程的调用(比如通过另一会话执行
EXEC other_user.pkg.proc(...)),只要该过程已用DEBUG模式编译(ALTER PROCEDURE ... COMPILE DEBUG),就会自动连接到你的监听器并停在断点处 - 注意:断点必须设在**被调用方对象的源码行**(如
other_user的包体),且该对象编译时启用了调试信息(查SELECT plsql_debug FROM dba_plsql_object_settings)
常见错误:断点没触发,却以为是 DBMS_DEBUG 问题
多数人卡在这一步,其实和 DBMS_DEBUG 完全无关:
- 断点设在包头(
PACKAGE)而非包体(PACKAGE BODY)——只有包体可执行,断点无效 - 目标过程用
CREATE OR REPLACE PROCEDURE重建但未加DEBUG,或会话级未执行ALTER SESSION SET PLSQL_DEBUG = TRUE再编译 - SQL Developer 连接角色选了
READ ONLY或未勾选DEBUG角色,导致调试协议被拒绝 - 防火墙或网络策略阻断了 JDWP 端口(默认 4000),表现为“Debugger listening…” 但永远等不到连接
- 调用链中某层是 SQL 语句(如
INSERT)、内置函数(如SYSDATE)或加密对象(如DBMS_LOB),F7Step Into会直接跳过,不是 bug,是设计如此
真正要实现“跨会话停进别人的过程”,关键不在调用哪个包,而在调试通道是否打通、目标对象是否带调试符号、以及调用路径是否真实经过那行代码——DBMS_DEBUG 这条路,早在二十年前就封死了。


















