| 796 | } |
| 797 | |
| 798 | func startServerDebug(cfg *devConfig, serverArgs []string, group *procGroup) error { |
| 799 | ctx := group.Ctx() |
| 800 | logger := group.logger |
| 801 | |
| 802 | debugBin := filepath.Join(cfg.projectRoot, "build", |
| 803 | fmt.Sprintf("coder_debug_%s_%s", runtime.GOOS, runtime.GOARCH)) |
| 804 | dlvBinDir := filepath.Join(cfg.projectRoot, "build", ".bin") |
| 805 | dlvBin := filepath.Join(dlvBinDir, "dlv") |
| 806 | |
| 807 | // Build debug binary and install dlv in parallel. |
| 808 | eg, egCtx := errgroup.WithContext(ctx) |
| 809 | eg.Go(func() error { |
| 810 | buildArgs := []string{ |
| 811 | "--os", runtime.GOOS, "--arch", runtime.GOARCH, |
| 812 | "--output", debugBin, "--debug", |
| 813 | } |
| 814 | if cfg.agpl { |
| 815 | buildArgs = append(buildArgs, "--agpl") |
| 816 | } |
| 817 | cmd := cfg.cmd(egCtx, |
| 818 | filepath.Join(cfg.projectRoot, "scripts", "build_go.sh"), |
| 819 | buildArgs...) |
| 820 | w := &logWriter{logger: logger.Named("build-debug")} |
| 821 | cmd.Stdout = w |
| 822 | cmd.Stderr = w |
| 823 | return cmd.Run() |
| 824 | }) |
| 825 | eg.Go(func() error { |
| 826 | goVer := strings.TrimPrefix(runtime.Version(), "go") |
| 827 | cmd := cfg.cmd(egCtx, "go", "install", |
| 828 | "github.com/go-delve/delve/cmd/dlv@latest") |
| 829 | cmd.Env = append(cmd.Env, |
| 830 | "GOBIN="+dlvBinDir, "GOTOOLCHAIN=go"+goVer) |
| 831 | w := &logWriter{logger: logger.Named("dlv-install")} |
| 832 | cmd.Stdout = w |
| 833 | cmd.Stderr = w |
| 834 | return cmd.Run() |
| 835 | }) |
| 836 | if err := eg.Wait(); err != nil { |
| 837 | return xerrors.Errorf("debug build: %w", err) |
| 838 | } |
| 839 | |
| 840 | srvCmd := cfg.cmd(ctx, debugBin, serverArgs...) |
| 841 | if err := group.Start("api", srvCmd); err != nil { |
| 842 | return err |
| 843 | } |
| 844 | |
| 845 | dlvCmd := cfg.cmd(ctx, dlvBin, "attach", |
| 846 | strconv.Itoa(srvCmd.Process.Pid), |
| 847 | "--headless", "--continue", |
| 848 | "--listen", "127.0.0.1:12345", |
| 849 | "--accept-multiclient") |
| 850 | if err := group.Start("dlv", dlvCmd); err != nil { |
| 851 | return xerrors.Errorf("attaching dlv: %w", err) |
| 852 | } |
| 853 | logger.Info(ctx, "delve debugger listening", slog.F("addr", "127.0.0.1:12345")) |
| 854 | return nil |
| 855 | } |