whatcanGOwrong

This commit is contained in:
2024-09-19 21:38:24 -04:00
commit d0ae4d841d
17908 changed files with 4096831 additions and 0 deletions
@@ -0,0 +1,284 @@
# How to write a Delve client, an informal guide
## Spawning the backend
The `dlv` binary built by our `Makefile` contains both the backend and a
simple command line client. If you are writing your own client you will
probably want to run only the backend, you can do this by specifying the
`--headless` option, for example:
```
$ dlv --headless debug
```
The rest of the command line remains unchanged. You can use `debug`, `exec`,
`test`, etc... along with `--headless` and they will work. If this project
is part of a larger IDE integration then you probably have your own build
system and do not wish to offload this task to Delve, in that case it's
perfectly fine to always use the `dlv exec` command but do remember that:
1. Delve may not have all the information necessary to properly debug optimized binaries, so it is recommended to disable them via: `-gcflags='all=-N -l`.
2. your users *do want* to debug their tests so you should also provide some way to build the test executable (equivalent to `go test -c --gcflags='all=-N -l'`) and pass it to Delve.
It would also be nice for your users if you provided a way to attach to a running process, like `dlv attach` does.
Command line arguments that should be handed to the inferior process should be specified on dlv's command line after a "--" argument:
```
dlv exec --headless ./somebinary -- these arguments are for the inferior process
```
Specifying a static port number, like in the [README](//github.com/go-delve/delve/tree/master/Documentation/README.md) example, can be done using `--listen=127.0.0.1:portnumber`.
This will, however, cause problems if you actually spawn multiple instances of the debugger.
It's probably better to let Delve pick a random unused port number on its own. To do this do not specify any `--listen` option and read one line of output from dlv's stdout. If the first line emitted by dlv starts with "API server listening at: " then dlv started correctly and the rest of the line specifies the address that Delve is listening at.
The `--log-dest` option can be used to redirect the "API server listening at:" message to a file or to a file descriptor. If the flag is not specified, the message will be output to stdout while other log messages are output to stderr.
## Controlling the backend
Once you have a running headless instance you can connect to it and start sending commands. Delve's protocol is built on top of the [JSON-RPC 1.0 specification](https://www.jsonrpc.org/specification_v1).
The methods of a `service/rpc2.RPCServer` are exposed through this connection, to find out which requests you can send see the documentation of RPCServer on [Go Reference](https://pkg.go.dev/github.com/go-delve/delve/service/rpc2#RPCServer).
### Example
Let's say you are trying to create a breakpoint. By looking at [Go Reference](https://pkg.go.dev/github.com/go-delve/delve/service/rpc2#RPCServer) you'll find that there is a `CreateBreakpoint` method in `RPCServer`.
This method, like all other methods of RPCServer that you can call through the API, has two arguments: `args` and `out`: `args` contains all the input arguments of `CreateBreakpoint`, while `out` is what `CreateBreakpoint` will return to you.
The call that you could want to make, in pseudo-code, would be:
```
RPCServer.CreateBreakpoint(CreateBreakpointIn{ File: "/User/you/some/file.go", Line: 16 })
```
To actually send this request on the JSON-RPC connection you just have to convert the CreateBreakpointIn object to json and then wrap everything into a JSON-RPC envelope:
```
{"method":"RPCServer.CreateBreakpoint","params":[{"Breakpoint":{"file":"/User/you/some/file.go","line":16}}],"id":27}
```
Delve will respond by sending a response packet that will look like this:
```
{"id":27, "result": {"Breakpoint": {"id":3, "name":"", "addr":4538829, "file":"/User/you/some/file.go", "line":16, "functionName":"main.main", "Cond":"", "continue":false, "goroutine":false, "stacktrace":0, "LoadArgs":null, "LoadLocals":null, "hitCount":{}, "totalHitCount":0}}, "error":null}
```
## Selecting the API version
Delve currently supports two version of its API, APIv1 and APIv2. By default
a headless instance of `dlv` will serve APIv1 for backward-compatibility
with older clients, however new clients should use APIv2 as new features
will only be made available through version 2. The preferred method of
switching to APIv2 is to send the `RPCServer.SetApiVersion` command right
after connecting to the backend.
Alternatively the `--api-version=2` command line option can be used when
spawning the backend.
## Diagnostics
Just like any other program, both Delve and your client have bugs. To help
with determining where the problem is you should log the exchange of
messages between Delve and your client somehow.
If you don't want to do this yourself you can also pass the options `--log
--log-output=rpc` to Delve. In fact the `--log-output` has many useful
values and you should expose it to users, if possible, so that we can
diagnose problems that are hard to reproduce.
## Using RPCServer.Command
`Command` is probably the most important API entry point. It lets your
client stop (`Name == "halt"`) and resume (`Name == "continue"`) execution
of the inferior process.
The return value of `Command` is a `DebuggerState` object. If you lose the
DebuggerState object returned by your last call to `Command` you can ask for
a new copy with `RPCServer.State`.
### Dealing with simultaneous breakpoints
Since Go is a programming language with a big emphasis on concurrency and
parallelism it's possible that multiple goroutines will stop at a breakpoint
simultaneously. This may at first seem incredibly unlikely but you must
understand that between the time a breakpoint is triggered and the point
where the debugger finishes stopping all threads of the inferior process
thousands of CPU instructions have to be executed, which make simultaneous
breakpoint triggering not that unlikely.
You should signal to your user *all* the breakpoints that occur after
executing a command, not just the first one. To do this iterate through the
`Threads` array in `DebuggerState` and note all the threads that have a non
nil `Breakpoint` member.
### Special continue commands
In addition to "halt" and vanilla "continue" `Command` offers a few extra
flavours of continue that automatically set interesting temporary
breakpoints: "next" will continue until the next line of the program,
"stepout" will continue until the function returns, "step" is just like
"next" but it will step into function calls (but skip all calls to
unexported runtime functions).
All of "next", "step" and "stepout" operate on the selected goroutine. The
selected goroutine is described by the `SelectedGoroutine` field of
`DebuggerState`. Every time `Command` returns the selected goroutine will be
reset to the goroutine that triggered the breakpoint.
If multiple breakpoints are triggered simultaneously the selected goroutine
will be chosen randomly between the goroutines that are stopped at a
breakpoint. If a breakpoint is hit by a thread that is executing on the
system stack *there will be no selected goroutine*. If the "halt" command is
called *there may not be a selected goroutine*.
The selected goroutine can be changed using the "switchGoroutine" command.
If "switchGoroutine" is used to switch to a goroutine that's currently
parked SelectedGoroutine and CurrentThread will be mismatched. Always prefer
SelectedGoroutine over CurrentThread, you should ignore CurrentThread
entirely unless SelectedGoroutine is nil.
### Special continue commands and asynchronous breakpoints
Because of the way go internals work it is not possible for a debugger to
resume a single goroutine. Therefore it's possible that after executing a
next/step/stepout a goroutine other than the goroutine the next/step/stepout
was executed on will hit a breakpoint.
If this happens Delve will return a DebuggerState with NextInProgress set to
true. When this happens your client has two options:
* You can signal that a different breakpoint was hit and then automatically attempt to complete the next/step/stepout by calling `RPCServer.Command` with `Name == "continue"`
* You can abort the next/step/stepout operation using `RPCServer.CancelNext`.
It is important to note that while NextInProgress is true it is not possible
to call next/step/stepout again without using CancelNext first. There can
not be multiple next/step/stepout operations in progress at any time.
### RPCServer.Command and stale executable files
It's possible (albeit unfortunate) that your user will decide to change the
source of the program being executed in the debugger, while the debugger is
running. Because of this it would be advisable that your client check that
the executable is not stale every time `Command` returns and notify the user
that the executable being run is stale and line numbers may nor align
properly anymore.
You can do this bookkeeping yourself, but Delve can also help you with the
`LastModified` call that returns the LastModified time of the executable
file when Delve started it.
## Using RPCServer.CreateBreakpoint
The only two fields you probably want to fill of the Breakpoint argument of
CreateBreakpoint are File and Line. The file name should be the absolute
path to the file as the compiler saw it.
For example if the compiler saw this path:
```
/Users/you/go/src/something/something.go
```
But `/Users/you/go/src/something` is a symbolic link to
`/Users/you/projects/golang/something` the path *must* be specified as
`/Users/you/go/src/something/something.go` and
`/Users/you/projects/golang/something/something.go` will not be recognized
as valid.
If you want to let your users specify a breakpoint on a function selected
from a list of all functions you should specify the name of the function in
the FunctionName field of Breakpoint.
If you want to support the [same language as dlv's break and trace commands](//github.com/go-delve/delve/tree/master/Documentation/cli/locspec.md)
you should call RPCServer.FindLocation and
then use the returned slice of Location objects to create Breakpoints to
pass to CreateBreakpoint: just fill each Breakpoint.Addr with the
contents of the corresponding Location.PC.
## Looking into variables
There are several API entry points to evaluate variables in Delve:
* RPCServer.ListPackageVars returns all global variables in all packages
* PRCServer.ListLocalVars returns all local variables of a stack frame
* RPCServer.ListFunctionArgs returns all function arguments of a stack frame
* RPCServer.Eval evaluates an expression on a given stack frame
All those API calls take a LoadConfig argument. The LoadConfig specifies how
much of the variable's value should actually be loaded. Because of
LoadConfig a variable could be loaded incompletely, you should always notify
the user of this:
* For strings, arrays, slices *and structs* the load is incomplete if: `Variable.Len > len(Variable.Children)`. This can happen to structs even if LoadConfig.MaxStructFields is -1 when MaxVariableRecurse is reached.
* For maps the load is incomplete if: `Variable.Len > len(Variable.Children) / 2`
* For interfaces the load is incomplete if the only children has the onlyAddr attribute set to true.
### Loading more of a Variable
You can also give the user an option to continue loading an incompletely
loaded variable. To load a struct that wasn't loaded automatically evaluate
the expression returned by:
```
fmt.Sprintf("*(*%q)(%#x)", v.Type, v.Addr)
```
where v is the variable that was truncated.
To load more elements from an array, slice or string:
```
fmt.Sprintf("(*(*%q)(%#x))[%d:]", v.Type, v.Addr, len(v.Children))
```
To load more elements from a map:
```
fmt.Sprintf("(*(*%q)(%#x))[%d:]", v.Type, v.Addr, len(v.Children)/2)
```
All the evaluation API calls except ListPackageVars also take a EvalScope
argument, this specifies which stack frame you are interested in. If you
are interested in the topmost stack frame of the current goroutine (or
thread) use: `EvalScope{ GoroutineID: -1, Frame: 0 }`.
More information on the expression language interpreted by RPCServer.Eval
can be found [here](//github.com/go-delve/delve/tree/master/Documentation/cli/expr.md).
### Variable shadowing
Let's assume you are debugging a piece of code that looks like this:
```
for i := 0; i < N; i++ {
for i := 0; i < M; i++ {
f(i) // <-- debugger is stopped here
}
}
```
The response to a ListLocalVars request will list two variables named `i`,
because at that point in the code two variables named `i` exist and are in
scope. Only one (the innermost one), however, is visible to the user. The
other one is *shadowed*.
Delve will tell you which variable is shadowed through the `Flags` field of
the `Variable` object. If `Flags` has the `VariableShadowed` bit set then
the variable in question is shadowed.
Users of your client should be able to distinguish between shadowed and
non-shadowed variables.
## Gracefully ending the debug session
To ensure that Delve cleans up after itself by deleting the `debug` or `debug.test` binary it creates
and killing any processes spawned by the program being debugged, the `Detach` command needs to be called.
In case you are disconnecting a running program, ensure to halt the program before trying to detach.
## Testing the Client
A set of [example programs is
available](https://github.com/aarzilli/delve_client_testing) to test corner
cases in handling breakpoints and displaying data structures. Follow the
instructions in the README.txt file.
@@ -0,0 +1,32 @@
# Server/Client API Documentation
Delve exposes two API interfaces, JSON-RPC and DAP, so that frontends other than the built-in [terminal client](../cli/README.md), such as [IDEs and editors](../EditorIntegration.md), can interact with Delve programmatically. The [JSON-RPC API](json-rpc/README.md) is used by the [terminal client](../cli/README.md), and will always stay up to date in lockstep regardless of new features. The [DAP API](dap/README.md) is a popular generic API already in use by many [tools](https://microsoft.github.io/debug-adapter-protocol/implementors/tools/).
## Usage
In order to run Delve in "API mode", simply invoke with one of the standard commands, providing the `--headless` flag, like so:
```
$ dlv debug --headless --api-version=2 --log --log-output=debugger,dap,rpc --listen=127.0.0.1:8181
```
This will start the debugger in a non-interactive mode, listening on the specified address, and will enable logging. The logging flags as well as the server address are optional, of course.
Optionally, you may also specify the `--accept-multiclient` flag if you would like to connect multiple JSON-RPC or DAP clients to the API.
You can connect to the headless debugger from Delve itself using the `connect` subcommand:
```
$ dlv connect 127.0.0.1:8181
```
This can be useful for remote debugging.
## API Interfaces
Delve has been architected in such a way as to allow multiple client/server implementations. All of the "business logic" as it were is abstracted away from the actual client/server implementations, allowing for easy implementation of new API interfaces.
### Current API Interfaces
- [JSON-RPC](json-rpc/README.md)
- [DAP](dap/README.md)
@@ -0,0 +1,147 @@
# DAP Interface
Delve exposes a [DAP](https://microsoft.github.io/debug-adapter-protocol/overview) API interface.
This interface is served over a streaming TCP socket using `dlv` server in one of the two headless modes:
1. [`dlv dap`](../../usage/dlv_dap.md) - starts a single-use DAP-only server that waits for a client to specify launch/attach configuration for starting the debug session.
2. `dlv --headless <command> <debuggee>` - starts a general server, enters a debug session for the specified debuggee and waits for a [JSON-RPC](../json-rpc/README.md) or a [DAP](https://microsoft.github.io/debug-adapter-protocol/overview) remote-attach client to begin interactive debugging. Can be used in multi-client mode with the following options:
* `--accept-multiclient` - use to support connections from multiple clients
* `--continue` - use to resume debuggee execution as soon as server session starts
See [Launch and Attach Configurations](#launch-and-attach-configurations) for more usage details of these two options.
The primary user of this mode is [VS Code Go](https://github.com/golang/vscode-go). Please see its
detailed [debugging documentation](https://github.com/golang/vscode-go/blob/master/docs/debugging.md) for additional information.
## Debug Adapter Protocol
[DAP](https://microsoft.github.io/debug-adapter-protocol/specification) is a general debugging protocol supported by many [tools](https://microsoft.github.io/debug-adapter-protocol/implementors/tools/) and [programming languages](https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/). We tailored it to Go specifics, such as mapping [threads request](https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Threads) to communicate goroutines and [exceptionInfo request](https://microsoft.github.io/debug-adapter-protocol/specification#Requests_ExceptionInfo) to support panics and fatal errors.
See [dap.Server.handleRequest](https://github.com/go-delve/delve/search?q=handleRequest) and capabilities set in [dap.Server.onInitializeRequest](https://github.com/go-delve/delve/search?q=onInitializeRequest) for an up-to-date list of supported requests and options.
## Launch and Attach Configurations
In addition to the general [DAP spec](https://microsoft.github.io/debug-adapter-protocol/specification), the server supports the following implementation-specific configuration options for starting the debug session:
<table border=1>
<tr><th>request<th>mode<th>required<th colspan=9>optional<th></tr>
<tr><td rowspan=5>launch<br><a href="https://pkg.go.dev/github.com/go-delve/delve/service/dap#LaunchConfig">godoc</a>
<td>debug<td>program <td>dlvCwd<td>env<td>backend<td>args<td>cwd<td>buildFlags<td>output<td>noDebug
<td rowspan=7>
substitutePath<br>
stopOnEntry<br>
stackTraceDepth<br>
showGlobalVariables<br>
showRegisters<br>
showPprofLabels<br>
hideSystemGoroutines<br>
goroutineFilters
</tr>
<tr>
<td>test<td>program <td>dlvCwd<td>env<td>backend<td>args<td>cwd<td>buildFlags<td>output<td>noDebug</tr>
<tr>
<td>exec<td>program <td>dlvCwd<td>env<td>backend<td>args<td>cwd<td> <td> <td>noDebug</tr>
<tr>
<td>core<td>program<br>corefilePath<td>dlvCwd<td>env<td> <td> <td> <td> <td> <td> </tr>
<tr>
<td>replay<td>traceDirPath <td>dlvCwd<td>env<td> <td> <td> <td> <td> <td> </tr>
<tr><td rowspan=2>attach<br><a href="https://pkg.go.dev/github.com/go-delve/delve/service/dap#AttachConfig">godoc</a>
<td>local<td>processId <td> <td> <td>backend<td> <td> <td> <td> <td> </tr>
<tr>
<td>remote<td> <td> <td> <td> <td> <td> <td> <td> <td> </tr>
</table>
Not all of the configurations are supported by each of the two available DAP servers:
<table border=1>
<tr>
<th>request<th>"mode":<th>`dlv dap`<th>`dlv --headless` <th> Description <th> Typical Client Usage
</tr>
<tr>
<td>launch<td>"debug"<br>"test"<br>"exec"<br>"replay"<br>"core"<td>supported<td>NOT supported <td> Tells the `dlv dap` server to launch the specified target and start debugging it.
<td rowspan=2>The client would launch the `dlv dap` server for the user or allow them to specify `host:port` of an external (a.k.a. remote) server.
<tr>
<td>attach<td>"local"<td>supported<td>NOT supported<td>Tells the `dlv dap` server to attach to an existing process local to the server.
</tr>
<tr>
<td>attach<td>"remote"<td>NOT supported<td>supported<td>Tells the `dlv --headless` server that it is expected to already be debugging a target specified as part of its command-line invocation.
<td>The client would expect `host:port` specification of an external (a.k.a. remote) server that the user already started with target <a href="https://github.com/go-delve/delve/blob/master/Documentation/usage/README.md">command and args</a>.
</tr>
</table>
## Disconnect and Shutdown
### Single-Client Mode
When used with `dlv dap` or `dlv --headless --accept-multiclient=false` (default), the DAP server will shut itself down at the end of the debug session, when the client sends a [disconnect request](https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Disconnect). If the debuggee was launched, it will be taken down as well. If the debuggee was attached to, `terminateDebuggee` option will be respected.
When the program terminates, we send a [terminated event](https://microsoft.github.io/debug-adapter-protocol/specification#Events_Terminated), which is expected to trigger a [disconnect request](https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Disconnect) from the client for a session and a server shutdown. The [restart request](https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Restart) is not yet supported.
The server also shuts down in case of a client connection error or SIGTERM signal, taking down a launched process, but letting an attached process continue.
Pressing Ctrl-C on the terminal where a headless server is running sends SIGINT to the debuggee, foregrounded in headless mode to support debugging interactive programs.
### Multi-Client Mode
When used with `dlv --headless --accept-multiclient=true`, the DAP server will honor the multi-client mode when a client [disconnects](https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Disconnect) or client connection fails. The server will remain running and ready for a new client connection, and the debuggee will remain in whatever state it was at the time of disconnect - running or halted. Once [`suspendDebuggee`](https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Disconnect) option is supported by frontends like VS Code ([vscode/issues/134412](https://github.com/microsoft/vscode/issues/134412)), we will update the server to offer this as a way to specify debuggee state on disconnect.
The client may request full shutdown of the server and the debuggee with [`terminateDebuggee`](https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Disconnect) option.
The server shuts down in response to a SIGTERM signal, taking down a launched process, but letting an attached process continue.
Pressing Ctrl-C on the terminal where a headless server is running sends SIGINT to the debuggee, foregrounded in headless mode to support debugging interactive programs.
## Debugger Output
The debugger always logs one of the following on start-up to stdout:
* `dlv dap`:
* `DAP server listening at: <host>:<port>`
* `dlv --headless`:
* `API server listening at: <host>:<port>`
This can be used to confirm that server start-up succeeded.
The server uses [output events](https://microsoft.github.io/debug-adapter-protocol/specification#Events_Output) to communicate errors and select status messages to the client. For example:
```
Step interrupted by a breakpoint. Use 'Continue' to resume the original step command.
invalid command: Unable to step while the previous step is interrupted by a breakpoint.
Use 'Continue' to resume the original step command.
Detaching and terminating target process
```
More detailed logging can be enabled with `--log --log-output=dap` as part of the [`dlv` command](../../usage/dlv.md).
It will record the server-side DAP message traffic. For example,
```
2022-01-04T00:27:57-08:00 debug layer=dap [<- from client]{"seq":1,"type":"request","command":"initialize","arguments":{"clientID":"vscode","clientName":"Visual Studio Code","adapterID":"go","locale":"en-us","linesStartAt1":true,"columnsStartAt1":true,"pathFormat":"path","supportsVariableType":true,"supportsVariablePaging":true,"supportsRunInTerminalRequest":true,"supportsMemoryReferences":true,"supportsProgressReporting":true,"supportsInvalidatedEvent":true}}
2022-01-04T00:27:57-08:00 debug layer=dap [-> to client]{"seq":0,"type":"response","request_seq":1,"success":true,"command":"initialize","body":{"supportsConfigurationDoneRequest":true,"supportsFunctionBreakpoints":true,"supportsConditionalBreakpoints":true,"supportsEvaluateForHovers":true,"supportsSetVariable":true,"supportsExceptionInfoRequest":true,"supportTerminateDebuggee":true,"supportsDelayedStackTraceLoading":true,"supportsLogPoints":true,"supportsDisassembleRequest":true,"supportsClipboardContext":true,"supportsSteppingGranularity":true,"supportsInstructionBreakpoints":true}}
2022-01-04T00:27:57-08:00 debug layer=dap [<- from client]{"seq":2,"type":"request","command":"launch","arguments":{"name":"Launch file","type":"go","request":"launch","mode":"debug","program":"./temp.go","hideSystemGoroutines":true,"__buildDir":"/Users/polina/go/src","__sessionId":"2ad0f0c1-a1fd-4fff-9fff-b8bc9a933fe5"}}
2022-01-04T00:27:57-08:00 debug layer=dap parsed launch config: {
"mode": "debug",
"program": "./temp.go",
"backend": "default",
"stackTraceDepth": 50,
"hideSystemGoroutines": true
}
...
```
This logging is written to stderr and is not forwarded via
[output events](https://microsoft.github.io/debug-adapter-protocol/specification#Events_Output).
## Debuggee Output
Debuggee's stdout and stderr are written to stdout and stderr respectfully and are not forwarded via
[output events](https://microsoft.github.io/debug-adapter-protocol/specification#Events_Output).
## Versions
The initial DAP support was released in [v1.6.1](https://github.com/go-delve/delve/releases/tag/v1.6.1) with many additional improvements in subsequent versions. The [remote attach](https://github.com/go-delve/delve/issues/2328) support was added in [v1.7.3](https://github.com/go-delve/delve/releases/tag/v1.7.3).
The DAP API changes are backward-compatible as all new features are opt-in only. To update to a new [DAP version](https://microsoft.github.io/debug-adapter-protocol/changelog) and import a new DAP feature into delve,
one must first update the [go-dap](https://github.com/google/go-dap) dependency.
<!--- TODO:
- most requests are handled synchronously and block
- hence many commands not supported when running, but setting breakpoints is
--->
@@ -0,0 +1,43 @@
# JSON-RPC interface
Delve exposes a [JSON-RPC](https://www.jsonrpc.org/specification_v1) API interface.
Note that this JSON-RPC interface is served over a streaming socket, *not* over HTTP.
# API versions
Delve currently supports two versions of its API. By default a headless instance of `dlv` will serve APIv1 for backward compatibility with old clients, however new clients should use APIv2 as new features will only be made available through version 2. To select APIv2 use `--api-version=2` command line argument.
Clients can also select APIv2 by sending a [SetApiVersion](https://pkg.go.dev/github.com/go-delve/delve/service/rpccommon#RPCServer.SetApiVersion) request specifying `APIVersion = 2` after connecting to the headless instance.
# API version 2 documentation
All the methods of the type `service/rpc2.RPCServer` can be called using JSON-RPC, the documentation for these calls is [available on godoc](https://pkg.go.dev/github.com/go-delve/delve/service/rpc2#RPCServer).
Note that all exposed methods take one single input parameter (usually called `args`) of a struct type and also return a result of a struct type. Also note that the method name should be prefixed with `RPCServer.` in JSON-RPC.
# Example
Your client wants to set a breakpoint on the function `main.main`.
The first step will be calling the method `FindLocation` with `Scope = api.EvalScope{ GoroutineID: -1, Frame: 0}` and `Loc = "main.main"`. The JSON-RPC request packet should look like this:
```
{"method":"RPCServer.FindLocation","params":[{"Scope":{"GoroutineID":-1,"Frame":0},"Loc":"main.main"}],"id":2}
```
the response packet will look like this:
```
{"id":2,"result":{"Locations":[{"pc":4199019,"file":"/home/a/temp/callme/callme.go","line":31,"function":{"name":"main.main","value":4198992,"type":84,"goType":0}}]},"error":null}
```
Now your client should call the method `CreateBreakpoint` and specify `4199019` (the `pc` field in the response object) as the target address:
```
{"method":"RPCServer.CreateBreakpoint","params":[{"Breakpoint":{"addr":4199019}}],"id":3}
```
if this request is successful your client will receive the following response:
```
{"id":3,"result":{"Breakpoint":{"id":1,"name":"","addr":4199019,"file":"/home/a/temp/callme/callme.go","line":31,"functionName":"main.main","Cond":"","continue":false,"goroutine":false,"stacktrace":0,"LoadArgs":null,"LoadLocals":null,"hitCount":{},"totalHitCount":0}},"error":null}
```