|
- // Copyright 2018 Google Inc. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
-
- // +build linux
-
- // Package local provides access to a local program.
- package local
-
- import (
- "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug"
- "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server"
- "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server/protocol"
- )
-
- var _ debug.Program = (*Program)(nil)
- var _ debug.File = (*File)(nil)
-
- // Program implements the debug.Program interface.
- // Through that interface it provides access to a program being debugged.
- type Program struct {
- s *server.Server
- }
-
- // New creates a new program from the specified file.
- // The program can then be started by the Run method.
- func New(textFile string) (*Program, error) {
- s, err := server.New(textFile)
- return &Program{s: s}, err
- }
-
- func (p *Program) Open(name string, mode string) (debug.File, error) {
- req := protocol.OpenRequest{
- Name: name,
- Mode: mode,
- }
- var resp protocol.OpenResponse
- err := p.s.Open(&req, &resp)
- if err != nil {
- return nil, err
- }
- f := &File{
- prog: p,
- fd: resp.FD,
- }
- return f, nil
- }
-
- func (p *Program) Run(args ...string) (debug.Status, error) {
- req := protocol.RunRequest{args}
- var resp protocol.RunResponse
- err := p.s.Run(&req, &resp)
- if err != nil {
- return debug.Status{}, err
- }
- return resp.Status, nil
- }
-
- func (p *Program) Stop() (debug.Status, error) {
- panic("unimplemented")
- }
-
- func (p *Program) Resume() (debug.Status, error) {
- req := protocol.ResumeRequest{}
- var resp protocol.ResumeResponse
- err := p.s.Resume(&req, &resp)
- if err != nil {
- return debug.Status{}, err
- }
- return resp.Status, nil
- }
-
- func (p *Program) Kill() (debug.Status, error) {
- panic("unimplemented")
- }
-
- func (p *Program) Breakpoint(address uint64) ([]uint64, error) {
- req := protocol.BreakpointRequest{
- Address: address,
- }
- var resp protocol.BreakpointResponse
- err := p.s.Breakpoint(&req, &resp)
- return resp.PCs, err
- }
-
- func (p *Program) BreakpointAtFunction(name string) ([]uint64, error) {
- req := protocol.BreakpointAtFunctionRequest{
- Function: name,
- }
- var resp protocol.BreakpointResponse
- err := p.s.BreakpointAtFunction(&req, &resp)
- return resp.PCs, err
- }
-
- func (p *Program) BreakpointAtLine(file string, line uint64) ([]uint64, error) {
- req := protocol.BreakpointAtLineRequest{
- File: file,
- Line: line,
- }
- var resp protocol.BreakpointResponse
- err := p.s.BreakpointAtLine(&req, &resp)
- return resp.PCs, err
- }
-
- func (p *Program) DeleteBreakpoints(pcs []uint64) error {
- req := protocol.DeleteBreakpointsRequest{PCs: pcs}
- var resp protocol.DeleteBreakpointsResponse
- return p.s.DeleteBreakpoints(&req, &resp)
- }
-
- func (p *Program) Eval(expr string) ([]string, error) {
- req := protocol.EvalRequest{
- Expr: expr,
- }
- var resp protocol.EvalResponse
- err := p.s.Eval(&req, &resp)
- return resp.Result, err
- }
-
- func (p *Program) Evaluate(e string) (debug.Value, error) {
- req := protocol.EvaluateRequest{
- Expression: e,
- }
- var resp protocol.EvaluateResponse
- err := p.s.Evaluate(&req, &resp)
- return resp.Result, err
- }
-
- func (p *Program) Frames(count int) ([]debug.Frame, error) {
- req := protocol.FramesRequest{
- Count: count,
- }
- var resp protocol.FramesResponse
- err := p.s.Frames(&req, &resp)
- return resp.Frames, err
- }
-
- func (p *Program) Goroutines() ([]*debug.Goroutine, error) {
- req := protocol.GoroutinesRequest{}
- var resp protocol.GoroutinesResponse
- err := p.s.Goroutines(&req, &resp)
- return resp.Goroutines, err
- }
-
- func (p *Program) VarByName(name string) (debug.Var, error) {
- req := protocol.VarByNameRequest{Name: name}
- var resp protocol.VarByNameResponse
- err := p.s.VarByName(&req, &resp)
- return resp.Var, err
- }
-
- func (p *Program) Value(v debug.Var) (debug.Value, error) {
- req := protocol.ValueRequest{Var: v}
- var resp protocol.ValueResponse
- err := p.s.Value(&req, &resp)
- return resp.Value, err
- }
-
- func (p *Program) MapElement(m debug.Map, index uint64) (debug.Var, debug.Var, error) {
- req := protocol.MapElementRequest{Map: m, Index: index}
- var resp protocol.MapElementResponse
- err := p.s.MapElement(&req, &resp)
- return resp.Key, resp.Value, err
- }
-
- // File implements the debug.File interface, providing access
- // to file-like resources associated with the target program.
- type File struct {
- prog *Program // The Program associated with the file.
- fd int // File descriptor.
- }
-
- func (f *File) ReadAt(p []byte, offset int64) (int, error) {
- req := protocol.ReadAtRequest{
- FD: f.fd,
- Len: len(p),
- Offset: offset,
- }
- var resp protocol.ReadAtResponse
- err := f.prog.s.ReadAt(&req, &resp)
- return copy(p, resp.Data), err
- }
-
- func (f *File) WriteAt(p []byte, offset int64) (int, error) {
- panic("unimplemented")
- }
-
- func (f *File) Close() error {
- req := protocol.CloseRequest{
- FD: f.fd,
- }
- var resp protocol.CloseResponse
- err := f.prog.s.Close(&req, &resp)
- return err
- }
|