This repository has been archived by the owner on Feb 8, 2018. It is now read-only.
/
FAQ.txt
156 lines (107 loc) · 7.2 KB
/
FAQ.txt
1
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
* How do I enter a JIT trampoline ?
Normally, the debugger hides JIT trampolines from the user, even when stepping one single
instruction. To force the debugger to debug a JIT trampoline, you need to use the
`native stepi' command in the command line interface.
* How do I enter an interncall ?
There are two ways of entering an interncall: if the module the interncall is contained in
has debugging info and the `step' property is set (use `module <number> !ignore step' in the
command line interface), the debugger will automatically enter the interncall when stepping
by source lines.
Example debugging session:
[martin@einstein debugger]$ run-mono ./lib/Interpreter.exe ./test/N.exe
Process @1 stopped at #0: 0x08365f63 in X.Main()+0x7 at N.cs:7.
#0: 0x08365f63 in X.Main()+0x7 at N.cs:7
0x08365f63 push $0x41
7 bool is_number = Char.IsNumber ('A');
Mono debugger
$ show modules
3 /home/martin/MONO-LINUX/libexec/mono-debugger-jit-wrapper loaded ignore
5 N loaded symbols step
7 /home/martin/MONO-LINUX/lib/libmono.so.0 loaded ignore
9 mscorlib loaded symbols step
$ module 7 !ignore step
$ s
Process @1 stopped at #0: 0x400aa12c in ves_icall_System_Char_IsNumber+0x1c at unicode.c:110.
0x400aa12c movzwl 0xfffffff2(%ebp),%eax
110 GUnicodeType t = g_unichar_type (c);
You can also "force" the debugger to enter the intercalls by stepping by machine instructions;
in this case, the debugger will automatically jump over the JIT trampoline and stop at the
first instruction of the interncall.
Example debugging session:
[martin@einstein debugger]$ run-mono ./lib/Interpreter.exe ./test/N.exe
Process @1 stopped at #0: 0x08366013 in X.Main()+0x7 at N.cs:7.
#0: 0x08366013 in X.Main()+0x7 at N.cs:7
0x08366013 push $0x41
7 bool is_number = Char.IsNumber ('A');
Mono debugger
$ i
Process @1 stopped at #0: 0x08366018 in X.Main()+0xc at N.cs:7.
0x08366018 call System.Char.IsNumber(System.Char)
7 bool is_number = Char.IsNumber ('A');
$
Process @1 stopped at #0: 0x400aa110.
0x400aa110 push %ebp
* Why aren't we using gdb as the backend ?
Unfortunately, using gdb as the backend would have been a lot more work than writing our
own backend from scratch. Basically, there were more things in gdb which we could not use
than things we could use - and there were also serious performance issues.
It might make sense to write a gdb backend to port the debugger to all architectures -
however, the debugger's platform/architecture specific code is less than 1500 lines of
code, so it may also be easier to port this directly.
* The debugger has problems finding `MONO_DEBUGGER__debugger_info'
You need to have a Debugger.exe.config file containing the full path name of your `mono'
executable. Normally, this file is automatically generated.
The `MONO_DEBUGGER__debugger_info' symbol must be in the `mono' executable itself, not in
a shared library, it is read by the debugger before loading any shared libraries.
* What are the requirements to get the debugger up and running on GNU/Linux ?
To get all the cool features of the GUI, you need gtk# and GNOME 2.
However, the backend and the command-line interface only depends on glib (the C library,
not glib-sharp.dll) and binutils >= 2.12 (some distros may have an older version of it).
* Can I debug Mono class libraries with it, such as corlib or System.Data ?
Sure you can do this. All you need to do is to compile them with debugging support (mcs -g).
* Can it be used to debug code which uses unmanaged code via DllImport or interncalls ?
The debugger can debug managed and unmanaged applications - and while debugging managed
applications, you can also enter interncalls and stuff like that (actually, the debugger
has an option to turn this feature on and off).
* Can I use the debugger to debug GTK# or QT# applications on Mono?
There is no reason why you shouldn't be able to do this.
* Can the debugger be ported to other platforms, such as, Linux/PPC, FreeBSD/i386, or dare
I say Windows 2000 ? If so, what would it take to port the debugger to other platforms?
We need to distinguish between hardware architectures and operating systems here.
To port the debugger to another operating system, have a look at backends/server/server.h -
this is an unmanaged API which you need to implement for that other operating system. The
current Linux implementation is in i386-linux-ptrace.c.
To port the debugger to another hardware architecture, you also need to implement the
managed IArchitecture interface; the current i386 implementation is in
arch/ArchitectureI386.cs. I'm currently using architecture-specific stuff in
i386-linux-ptrace.c because there's just one architecture; it may be a good idea to split
this file - all the ptrace() stuff should be the same for Linux/PPC, for instance.
It shouldn't be that difficult to port the debugger to another hardware architecture or
another Unix system - but I have no idea whether it'll be possible to port it to any
flavor of Windows. In any case, such a port would be a huge task and much more difficult
than porting it to another Unix system.
The problem is that to debug unmanaged applications, the debugger is using the bfd and
libopcodes libraries - which have already been ported to a lot of different Unix systems.
* What features does debugger have? How does this differ from other debuggers out there?
Well, it has a lot of features :-)
However, the coolest feature I added last week are per-thread breakpoints - if you're
debugging a multi-threaded application, you can tell the debugger that a particular
breakpoint should only break in a particular thread - and this works without hardware
breakpoints.
This'll be very important when debugging system libraries such as System.Data in a
multi-threaded application because the method you're currently debugging may be called
from another thread in the meantime.
* I thought that single stepping of source code lines was typically implemented by setting
a breakpoint on the next instruction. Why aren't we doing this ?
The problem is that you don't know where the "next instruction" is without reading and
analysing the machine code. Each instruction could be a call or a (conditional) jump - so
even if your source line is a "basic block" in C# (something which contains no jumps and
calls), this doesn't need to be the case in the generated machine code.
The other problem is that setting a breakpoint on the next instruction is about three
times more expensive that stepping a single machine instruction (read insn, write
breakpoint, continue, wait, write old insn instead of step, wait) plus the risk that
another thread may hit the breakpoint in the meantime plus the problem that breakpoints
don't work everywhere (so you won't be able to step through x86_magic_trampoline(), for
instance).
* I'm getting an undefined symbol `_sch_istable'.
Please read the section "binutils and libbfd issues" in README.FreeBSD.