成员函数和方法并不是特别多,但是为了实现这个功能却花了我近10天的功夫,因为某些方法或函数的不恰当的调用,
会导致意想不到的问题,如程序挂起。主要参考了Oracle的官方文档:
http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96612/d_debug.htm
http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96612/d_debug2.htm
为了实现调试功能,你要打开两个Oracle连接,一个是执行你要调试语句的targetSession,
另外一个是对其进行调试的debugSession.在调试之前,你需要对你要调试的存储过程/函数/包要重新编译以产生编译信息
ALTER [PROCEDURE | FUNCTION | PACKAGE | TRIGGER | TYPE] <name> COMPILE DEBUG;
ALTER [PACKAGE | TYPE] <name> COMPILE DEBUG BODY;
请看下面的流程图关于目标会话/调试会话需要执行的动作及其相互关系:

启动调试的代码:
1
private void StartDebug()
2
{
3

13
14
initialize target session and command
30
31
initialize debug session and command
40
41
prepare
52
53
Get DebugID;
57
targetCommand.CommandText = "begin SYS.DBMS_DEBUG.Debug_on(true,false); end;";
58
targetCommand.ExecuteNonQuery ();
59
}
60
this.executeException = null;
61
//if(this.targetThread == null)
62
//{
63
targetThread = new System.Threading.Thread(new System.Threading.ThreadStart(this.Execute));
64
//}
65
66
targetThread.Start();
67
System.Threading.Thread.Sleep(500);
68
if(this.Synchronize())
69
{
70
this.Debug(BreakFlag.AnyCall);
71
this.btnStartDebug.Enabled = false;
72
this.mStepInto.Enabled = true;
73
this.mStepOver.Enabled = true;
74
this.mRun.Enabled = true;
75
}
76
else
77
{
78
this.executeException = null;
79
this.IsDebuging = false;
80
this.MSQL.Document.ReadOnly = false;
81
this.btnStartDebug.Enabled = true;
82
this.mStepInto.Enabled = false;
83
this.mStepOver.Enabled = false;
84
this.mRun.Enabled = false;
85
if(this.ObjectName != null && this.ObjectName != "")
86
{
87
this.btnConfigure.Enabled = true;
88
}
89
}
90
}
91

2

3


13

14

30

31

40

41

52

53

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

与目标会话同步的代码:






























单步调试的代码:
1
private ErrorCode Continue(out RuntimeInfo runtimeInfo,BreakFlag breakFlag)
2
{
3
runtimeInfo = new RuntimeInfo();
4
string strSQL= "declare \n " +
5
" running_info sys.dbms_debug.runtime_info; \n" +
6
"begin \n" +
7
" :cont_result := sys.dbms_debug.continue(run_info =>running_info,\n" +
8
" breakflags =>:breakflag,\n" +
9
" info_requested =>sys.dbms_debug.info_getStackDepth + \n" +
10
" sys.dbms_debug.info_getLineInfo + sys.dbms_debug.info_getBreakpoint);" +
11
" :Terminated := running_info.Terminated;\n" +
12
" :Line := running_info.Line#; \n" +
13
" :Reason := running_info.Reason;\n" +
14
" :BreakPoint := running_info.BreakPoint;\n" +
15
" :Oer := running_info.Oer;\n" +
16
" :StackDepth := running_info.StackDepth;\n" +
17
" :DBLink := running_info.Program.DBLink;\n" +
18
" :EntrypointName := running_info.Program.EntrypointName;\n" +
19
" :Name := running_info.Program.Name;\n" +
20
" :NameSpace := running_info.Program.NameSpace;\n" +
21
" :Owner := running_info.Program.Owner;\n" +
22
" :UnitType := running_info.Program.LibunitType;\n" +
23
"end;";
24
this.debugCommand.Parameters.Clear();
25
26
OracleParameter pIn = this.debugCommand.Parameters.Add("breakflag",OracleType.Int32);
27
pIn.Value = breakFlag;
28
29
OracleParameter pOut = this.debugCommand.Parameters.Add("Terminated",OracleType.Int32);
30
pOut.Direction = ParameterDirection.Output;
31
32
pOut = this.debugCommand.Parameters.Add("Line",OracleType.Int32);
33
pOut.Direction = ParameterDirection.Output;
34
35
pOut = this.debugCommand.Parameters.Add("Reason",OracleType.Int32);
36
pOut.Direction = ParameterDirection.Output;
37
38
pOut = this.debugCommand.Parameters.Add("BreakPoint",OracleType.Int32);
39
pOut.Direction = ParameterDirection.Output;
40
41
pOut = this.debugCommand.Parameters.Add("Oer",OracleType.Int32);
42
pOut.Direction = ParameterDirection.Output;
43
44
pOut = this.debugCommand.Parameters.Add("StackDepth",OracleType.Int32);
45
pOut.Direction = ParameterDirection.Output;
46
47
pOut = this.debugCommand.Parameters.Add("DBLink",OracleType.VarChar,20);
48
pOut.Direction = ParameterDirection.Output;
49
50
pOut = this.debugCommand.Parameters.Add("EntrypointName",OracleType.VarChar,20);
51
pOut.Direction = ParameterDirection.Output;
52
53
pOut = this.debugCommand.Parameters.Add("Name",OracleType.VarChar,20);
54
pOut.Direction = ParameterDirection.Output;
55
56
pOut = this.debugCommand.Parameters.Add("NameSpace",OracleType.Int32);
57
pOut.Direction = ParameterDirection.Output;
58
59
pOut = this.debugCommand.Parameters.Add("Owner",OracleType.VarChar,20);
60
pOut.Direction = ParameterDirection.Output;
61
62
63
pOut = this.debugCommand.Parameters.Add("UnitType",OracleType.Int32);
64
pOut.Direction = ParameterDirection.Output;
65
66
pOut = this.debugCommand.Parameters.Add("cont_result",OracleType.Int32);
67
pOut.Direction = ParameterDirection.Output;
68
69
this.debugCommand.CommandText = strSQL;
70
this.debugCommand.ExecuteNonQuery();
71
72
pOut = this.debugCommand.Parameters["cont_result"];
73
int p = int.Parse(pOut.Value.ToString());
74
ErrorCode errorCode = (ErrorCode)p;
75
76
runtimeInfo.Terminated = 0;
77
if(errorCode == ErrorCode.success)
78
{
79
runtimeInfo.Terminated = GetValueFromParameters(this.debugCommand.Parameters,"Terminated",-1);
80
runtimeInfo.Line = GetValueFromParameters(this.debugCommand.Parameters,"Line",-1);
81
runtimeInfo.Reason = (ReasonFlag)GetValueFromParameters(this.debugCommand.Parameters,"Reason",0);
82
runtimeInfo.Breakpoint = GetValueFromParameters(this.debugCommand.Parameters,"Breakpoint",-1);
83
runtimeInfo.Oer = GetValueFromParameters(this.debugCommand.Parameters,"Oer",-1);
84
runtimeInfo.StackDepth = GetValueFromParameters(this.debugCommand.Parameters,"StackDepth",-1);
85
runtimeInfo.Program.Dblink = GetValueFromParameters(this.debugCommand.Parameters,"DBLink","");
86
runtimeInfo.Program.EntrypointName = GetValueFromParameters(this.debugCommand.Parameters,"EntrypointName","");
87
runtimeInfo.Program.Line = runtimeInfo.Line;
88
runtimeInfo.Program.Name = GetValueFromParameters(this.debugCommand.Parameters,"Name","");
89
runtimeInfo.Program.Namespace = (NameSpace)GetValueFromParameters(this.debugCommand.Parameters,"NameSpace",127);
90
runtimeInfo.Program.Owner = GetValueFromParameters(this.debugCommand.Parameters,"Owner","");
91
runtimeInfo.Program.UnitType =(LibunitType)GetValueFromParameters(this.debugCommand.Parameters,"UnitType",-1);
92
}
93
return errorCode;
94
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

处理单步调试结果的代码:
1
private void Debug(BreakFlag breakFlag)
2
{
3
RuntimeInfo runtimeInfo;
4
this.Continue(out runtimeInfo,breakFlag);
5
//this.MString.ActiveTextAreaControl.TextArea.
6
if(runtimeInfo.Reason == ReasonFlag.KernlExit || this.targetThread.ThreadState == System.Threading.ThreadState.Stopped)
7
{
8
this.DetachSession();
9
this.MSQL.ActiveTextAreaControl.SelectionManager.ClearSelection();
10
System.Threading.Thread.Sleep(500);
11
if(this.executeException != null)
12
{
13
ExceptionDialog.Show(this.executeException.Message,MessageboxTitle.Title.Error,this.executeException);
14
}
15
else
16
{
17
DisplayOutParameter();
18
}
19
// if(this.targetThread.ThreadState != System.Threading.ThreadState.Stopped)
20
// this.AutoDebug();
21
this.IsDebuging = false;
22
if(this.ObjectName != null && this.ObjectName != "")
23
{
24
this.btnConfigure.Enabled = true;
25
}
26
this.richTextBox1.Text = "";
27
this.MSQL.Document.ReadOnly = false;
28
this.mRun.Enabled = false;
29
this.mStepInto.Enabled = false;
30
this.mStepOver.Enabled = false;
31
this.btnStartDebug.Enabled = true;
32
if(currentDebugSQLEditor != null && currentDebugMarker != null)
33
{
34
currentDebugSQLEditor.Document.MarkerStrategy.TextMarker.Remove(currentDebugMarker);
35
currentDebugSQLEditor.Refresh();
36
}
37
}
38
else if(runtimeInfo.Program.Name == "" && runtimeInfo.Line > 0)
39
{
40
this.tabSource.SelectedTab = this.tabSource.TabPages[0];
41
Highlight(this.tabSource.TabPages[0],runtimeInfo.Line);
42
DisplayAllVarValue();
43
GetBackTrace();
44
}
45
else if(runtimeInfo.Program.Name != "" && runtimeInfo.Line > 0)
46
{
47
int x =0;
48
x ++;
49
string objectName = runtimeInfo.Program.Owner + "." + runtimeInfo.Program.Name;
50
Crownwood.Magic.Controls.TabPage sourcePage = this.GetTabPage(runtimeInfo);
51
//if(runtimeInfo.Program.Namespace == NameSpace.Pkg_Body
52
if(sourcePage == null)
53
{
54
sourcePage = this.GenerateTabPage(runtimeInfo);
55
56
}
57
if(sourcePage != null)
58
{
59
this.tabSource.SelectedTab = sourcePage;
60
Highlight(sourcePage,runtimeInfo.Line);
61
}
62
DisplayAllVarValue();
63
GetBackTrace();
64
}
65
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

所有的源代码:
/Files/SharkXu/OracleDebug.zip
Oracle 调试功能我已经融合进了我的Shark DB Expert