Skip to content

Commit d61d17b

Browse files
authored
Merge pull request #7 from skx/2-breakpoint
Added breakpoint support.
2 parents 644b0ee + bcd0b33 commit d61d17b

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

README.md

+45
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Table of Contents
88
* [Usage](#usage)
99
* [My Approach](#my-approach)
1010
* [Timeline](#timeline)
11+
* [Debugging the generated program](#debugging-the-generated-program)
1112
* [Test Programs](#test-programs)
1213
* [Future Plans?](#future-plans)
1314
* [Bug Reports?](#bug-reports)
@@ -96,6 +97,50 @@ In the end it took me about four hours to get something I was happy with, and la
9697
* After that I slowly made improvements
9798
* Adding a lexer in [#4](https://github.com/skx/bfcc/pull/4)
9899
* Allowing the generation of either C or assembly in [#6](https://github.com/skx/bfcc/pull/6)
100+
* Allow generating a breakpoint instruction when using the assembly-backend in [#7](https://github.com/skx/bfcc/pull/7).
101+
102+
103+
### Debugging the generated program
104+
105+
If you run the compiler with the `-debug` flag a breakpoint will be generated
106+
immediately at the start of the program. You can use that breakpoint to easily
107+
debug the generated binary via `gdb`.
108+
109+
$ bfcc -debug ./examples/hello-world.bf
110+
111+
Now you can launch that binary under `gdb`, and run it:
112+
113+
$ gdb ./a.out
114+
(gdb) run
115+
..
116+
Program received signal SIGTRAP, Trace/breakpoint trap.
117+
0x00000000004000bb in _start ()
118+
119+
Disassemble the code via `disassemble`, and step over instructions one at a time via `stepi`. If your program is long you might see a lot of output from the `disassemble` step.
120+
121+
(gdb) disassemble
122+
Dump of assembler code for function _start:
123+
0x00000000004000b0 <+0>: movabs $0x600290,%r8
124+
0x00000000004000ba <+10>: int3
125+
=> 0x00000000004000bb <+11>: addb $0x8,(%r8)
126+
0x00000000004000bf <+15>: cmpb $0x0,(%r8)
127+
0x00000000004000c3 <+19>: je 0x40013f <close_loop_1>
128+
End of assembler dump.
129+
130+
You can set a breakpoint at a line in the future, and continue running till
131+
you hit it, with something like this:
132+
133+
(gdb) break *0x00000000004000c3
134+
(gdb) cont
135+
136+
Once there inspect the registers with commands like these two:
137+
138+
(gdb) print $r8
139+
(gdb) print *$r8
140+
(gdb) info registers
141+
142+
Further documentation can be found in the `gdb` manual, which is worth reading
143+
if you've an interest in compilers, debuggers, and decompilers.
99144

100145

101146

generators/generator_asm.go

+8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ _start:
3535
`
3636
buff.WriteString(programStart)
3737

38+
//
39+
// Should we generate a debug-breakpoint?
40+
//
41+
debug := os.Getenv("DEBUG")
42+
if debug == "1" {
43+
buff.WriteString(" int3\n")
44+
}
45+
3846
//
3947
// Keep track of "[" here.
4048
//

main.go

+12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func main() {
2020
//
2121
backend := flag.String("backend", "asm", "The backend to use for compilation.")
2222
cleanup := flag.Bool("cleanup", true, "Remove the generated files after creation.")
23+
debug := flag.Bool("debug", false, "Insert a debugging-breakpoint in the generated file, if possible.")
2324
run := flag.Bool("run", false, "Run the program after compiling.")
2425
flag.Parse()
2526

@@ -71,6 +72,17 @@ func main() {
7172
os.Setenv("CLEANUP", "0")
7273
}
7374

75+
//
76+
// Will we setup a debug-breakpoint?
77+
//
78+
// This only makes sense for the ASM-backend.
79+
//
80+
if *debug {
81+
os.Setenv("DEBUG", "1")
82+
} else {
83+
os.Setenv("DEBUG", "0")
84+
}
85+
7486
//
7587
// Generate the compiled version
7688
//

0 commit comments

Comments
 (0)