1// Copyright 2019 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// debugproxy connects to the target binary, and serves an RPC interface using
16// the types in server/protocol to access and control it.
17
18// +build linux
19
20package main
21
22import (
23	"flag"
24	"fmt"
25	"log"
26	"net/rpc"
27	"os"
28
29	"cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server"
30)
31
32var (
33	textFlag = flag.String("text", "", "file name of binary being debugged")
34)
35
36func main() {
37	log.SetFlags(0)
38	log.SetPrefix("debugproxy: ")
39	flag.Parse()
40	if *textFlag == "" {
41		flag.Usage()
42		os.Exit(2)
43	}
44	s, err := server.New(*textFlag)
45	if err != nil {
46		fmt.Printf("server.New: %v\n", err)
47		os.Exit(2)
48	}
49	err = rpc.Register(s)
50	if err != nil {
51		fmt.Printf("rpc.Register: %v\n", err)
52		os.Exit(2)
53	}
54	fmt.Println("OK")
55	log.Print("starting server")
56	rpc.ServeConn(&rwc{
57		os.Stdin,
58		os.Stdout,
59	})
60	log.Print("server finished")
61}
62
63// rwc creates a single io.ReadWriteCloser from a read side and a write side.
64// It allows us to do RPC using standard in and standard out.
65type rwc struct {
66	r *os.File
67	w *os.File
68}
69
70func (rwc *rwc) Read(p []byte) (int, error) {
71	return rwc.r.Read(p)
72}
73
74func (rwc *rwc) Write(p []byte) (int, error) {
75	return rwc.w.Write(p)
76}
77
78func (rwc *rwc) Close() error {
79	rerr := rwc.r.Close()
80	werr := rwc.w.Close()
81	if rerr != nil {
82		return rerr
83	}
84	return werr
85}
86