]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: whitelist debugCall32..debugCall65536 in debugCallCheck
authorAlessandro Arzilli <alessandro.arzilli@gmail.com>
Tue, 5 Feb 2019 07:49:49 +0000 (08:49 +0100)
committerAustin Clements <austin@google.com>
Mon, 29 Apr 2019 04:05:29 +0000 (04:05 +0000)
Whitelists functions debugCall32 through debugCall65536 in
runtime.debugCallCheck so that any instruction inside those functions
is considered a safe point.
This is useful for implementing nested function calls.

For example when evaluating:

f(g(x))

The debugger should:

1. initiate the call to 'f' until the entry point of 'f',
2. complete the call to 'g(x)'
3. copy the return value of 'g(x)' in the arguments of 'f'
4. complete the call to 'f'

Similarly for:

f().amethod()

The debugger should initiate the call to '.amethod()', then initiate
and complete the call to f(), copy the return value to the arguments
of '.amethod()' and finish its call.
However in this example, unlike the other example, it may be
impossible to determine the entry point of '.amethod()' until after
'f()' is evaluated, which means that the call to 'f()' needs to be
initiated while stopped inside a debugCall... function.

Change-Id: I575c23542709cedb1a171d63576f7e11069c7674
Reviewed-on: https://go-review.googlesource.com/c/go/+/161137
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
src/runtime/asm_amd64.s
src/runtime/debugcall.go

index e5b987858ddc1a307366bbfc1142354d9e8a2225..1cca0c794bf8fefda64bc62aaa798d1e38ff5550 100644 (file)
@@ -1612,6 +1612,8 @@ restore:
 
        RET
 
+// runtime.debugCallCheck assumes that functions defined with the
+// DEBUG_CALL_FN macro are safe points to inject calls.
 #define DEBUG_CALL_FN(NAME,MAXSIZE)            \
 TEXT NAME(SB),WRAPPER,$MAXSIZE-0;              \
        NO_LOCAL_POINTERS;                      \
index d26e3c26b95930a2f47535d58e883e17bd8bf67a..f03d2358ebb2682a1a0c5c25e274ab698dd6be82 100644 (file)
@@ -46,12 +46,32 @@ func debugCallCheck(pc uintptr) string {
                        return
                }
 
+               name := funcname(f)
+
+               switch name {
+               case "debugCall32",
+                       "debugCall64",
+                       "debugCall128",
+                       "debugCall256",
+                       "debugCall512",
+                       "debugCall1024",
+                       "debugCall2048",
+                       "debugCall4096",
+                       "debugCall8192",
+                       "debugCall16384",
+                       "debugCall32768",
+                       "debugCall65536":
+                       // These functions are whitelisted so that the debugger can initiate multiple function calls.
+                       // See: https://golang.org/cl/161137/
+                       return
+               }
+
                // Disallow calls from the runtime. We could
                // potentially make this condition tighter (e.g., not
                // when locks are held), but there are enough tightly
                // coded sequences (e.g., defer handling) that it's
                // better to play it safe.
-               if name, pfx := funcname(f), "runtime."; len(name) > len(pfx) && name[:len(pfx)] == pfx {
+               if pfx := "runtime."; len(name) > len(pfx) && name[:len(pfx)] == pfx {
                        ret = debugCallRuntime
                        return
                }