-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdebugtrace.R
135 lines (105 loc) · 2.91 KB
/
debugtrace.R
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
## debug and trace
# browser is great, but...
# fixed <- function(len) {
# x <- numeric()
# for(i in 1:len) {
# x[i] <- i + runif(1)
# browser()
# }
# return(x)
# }
# Now we have that break in execution in production code
# Unlike print() or a JavaScript engine's console.log()
# browser() will stop execution and raise the console!
fixed <- function(len) {
x <- numeric()
for(i in 1:len) {
x[i] <- i + runif(1)
}
return(x)
}
debug(fixed)
fixed(10)
undebug(fixed)
# If we only want to look once:
debugonce(fixed)
# we can also check to see if we've set the debug flag
isdebugged(fixed)
## That's cool, but...
undebug(fixed)
# sometimes the functions we write are gigantic.
# this is nominally our reason for manually debugging in most cases
trace(fixed, tracer = browser, at = 2)
# now we've entered the function at the 2nd step
# "step" here is a bit opaque.
# In order to exactly determine where we want to enter
# we can do:
as.list(body(fixed))
# [[1]]
# `{`
#
# [[2]]
# x <- numeric()
#
# [[3]]
# for (i in 1:len) {
# x[i] <- i + runif(1)
# }
#
# [[4]]
# return(x)
# don't bother guessing what your insertion point should be.
# You'll likely get it wrong.
# body() can also be useful to get a sense of how trace inserts
# breakpoints
someStuff <- function() {
x <- 1:10
x <- sqrt(x)
x[] <- x
return(x)
}
trace(what = "someStuff", at = 2, tracer = browser)
body(someStuff)
# {
# {
# .doTrace(browser(), "step 2")
# x <- 1:10
# }
# x <- sqrt(x)
# x[] <- x
# return(x)
# }
untrace(someStuff)
# trace() serves different functions depending on the passed arguments
# if we only pass in the function we want to trace...
trace(`<-`)
fixed(10)
# trace: x <- numeric()
# trace: x[i] <- i + runif(1)
# trace: x <- `[<-`(`*tmp*`, i, value = 1.27961299289018)
# trace: x[i] <- i + runif(1)
# trace: x <- `[<-`(`*tmp*`, i, value = 2.745730265975)
# trace: x[i] <- i + runif(1)
# trace: x <- `[<-`(`*tmp*`, i, value = 3.8495321678929)
# trace: x[i] <- i + runif(1)
# trace: x <- `[<-`(`*tmp*`, i, value = 4.45552718802355)
# trace: x[i] <- i + runif(1)
# trace: x <- `[<-`(`*tmp*`, i, value = 5.18439966184087)
# trace: x[i] <- i + runif(1)
# trace: x <- `[<-`(`*tmp*`, i, value = 6.99301336007193)
# trace: x[i] <- i + runif(1)
# trace: x <- `[<-`(`*tmp*`, i, value = 7.22802428947762)
# trace: x[i] <- i + runif(1)
# trace: x <- `[<-`(`*tmp*`, i, value = 8.32285486720502)
# trace: x[i] <- i + runif(1)
# trace: x <- `[<-`(`*tmp*`, i, value = 9.0931670491118)
# trace: x[i] <- i + runif(1)
# trace: x <- `[<-`(`*tmp*`, i, value = 10.6346214360092)
# [1] 1.279613 2.745730 3.849532 4.455527 5.184400 6.993013
# [7] 7.228024 8.322855 9.093167 10.634621
untrace(`<-`)
# What happened?
# We traced the assignment function
# because it is a binary operator, we have to quote it in backticks
# assignment happens very ofter, so it isn't super-informative
# but we can do this to any function