Skip to content

Commit

Permalink
Auto-decode stack traces for jag simulate (toitlang#216)
Browse files Browse the repository at this point in the history
* Auto-decode stack traces for jag simulate

* feedback
  • Loading branch information
erikcorry committed Aug 12, 2022
1 parent 78779d5 commit e68c602
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 47 deletions.
56 changes: 56 additions & 0 deletions cmd/jag/commands/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package commands

import (
"bufio"
"encoding/base64"
"errors"
"fmt"
Expand Down Expand Up @@ -171,3 +172,58 @@ func crashDecode(cmd *cobra.Command, backtrace string) error {
fmt.Println(backtrace)
return stacktraceCommand.Run()
}

type Decoder struct {
scanner *bufio.Scanner
cmd *cobra.Command
}

func (d *Decoder) decode() {
POSTPONED_LINES := map[string]bool{
"----": true,
"Received a Toit stack trace. Executing the command below will": true,
"make it human readable:": true,
}

Version := ""

postponed := []string{}

for d.scanner.Scan() {
// Get next line from device (or simulator) console.
line := d.scanner.Text()
versionPrefix := "[toit] INFO: starting <v"
if strings.HasPrefix(line, versionPrefix) && strings.HasSuffix(line, ">") {
Version = line[len(versionPrefix) : len(line)-1]
}
if _, contains := POSTPONED_LINES[line]; contains {
postponed = append(postponed, line)
} else {
separator := strings.Repeat("*", 78)
if strings.HasPrefix(line, "jag decode ") || strings.HasPrefix(line, "Backtrace:") {
fmt.Printf("\n" + separator + "\n")
if Version != "" {
fmt.Printf("Decoded by `jag` <%s>\n", Version)
fmt.Printf(separator + "\n")
}
if err := serialDecode(d.cmd, line); err != nil {
if len(postponed) != 0 {
fmt.Println(strings.Join(postponed, "\n"))
postponed = []string{}
}
fmt.Println(line)
fmt.Println("jag: Failed to decode line.")
} else {
postponed = []string{}
}
fmt.Printf(separator + "\n\n")
} else {
if len(postponed) != 0 {
fmt.Println(strings.Join(postponed, "\n"))
postponed = []string{}
}
fmt.Println(line)
}
}
}
}
49 changes: 3 additions & 46 deletions cmd/jag/commands/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"fmt"
"io"
"os"
"strings"
"time"

"github.com/spf13/cobra"
Expand All @@ -23,12 +22,6 @@ func MonitorCmd() *cobra.Command {
Args: cobra.NoArgs,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
Version := ""
POSTPONED_LINES := map[string]bool{
"----": true,
"Received a Toit stack trace. Executing the command below will": true,
"make it human readable:": true,
}

port, err := cmd.Flags().GetString("port")
if err != nil {
Expand Down Expand Up @@ -63,45 +56,9 @@ func MonitorCmd() *cobra.Command {

scanner := bufio.NewScanner(dev)

postponed := []string{}

for scanner.Scan() {
// Get next line from serial port.
line := scanner.Text()
versionPrefix := "[toit] INFO: starting <v"
if strings.HasPrefix(line, versionPrefix) && strings.HasSuffix(line, ">") {
Version = line[len(versionPrefix) : len(line)-1]
}
if _, contains := POSTPONED_LINES[line]; contains {
postponed = append(postponed, line)
} else {
separator := strings.Repeat("*", 78)
if strings.HasPrefix(line, "jag decode ") || strings.HasPrefix(line, "Backtrace:") {
fmt.Printf("\n" + separator + "\n")
if Version != "" {
fmt.Printf("Decoded by `jag monitor` <%s>\n", Version)
fmt.Printf(separator + "\n")
}
if err := serialDecode(cmd, line); err != nil {
if len(postponed) != 0 {
fmt.Println(strings.Join(postponed, "\n"))
postponed = []string{}
}
fmt.Println(line)
fmt.Println("jag monitor: Failed to decode line.")
} else {
postponed = []string{}
}
fmt.Printf(separator + "\n\n")
} else {
if len(postponed) != 0 {
fmt.Println(strings.Join(postponed, "\n"))
postponed = []string{}
}
fmt.Println(line)
}
}
}
decoder := Decoder{scanner, cmd}

decoder.decode()

return scanner.Err()
},
Expand Down
16 changes: 15 additions & 1 deletion cmd/jag/commands/simulate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package commands

import (
"bufio"
"io"
"os"
"strconv"

Expand Down Expand Up @@ -49,9 +51,21 @@ func SimulateCmd() *cobra.Command {
return err
}

outReader, outWriter := io.Pipe()

// Goroutine that gets data from the pipe and converts it into
// lines.
go func() {
scanner := bufio.NewScanner(outReader)

decoder := Decoder{scanner, cmd}

decoder.decode()
}()

simCmd := sdk.ToitRun(ctx, snapshot, strconv.Itoa(int(port)), id.String(), name)
simCmd.Stderr = os.Stderr
simCmd.Stdout = os.Stdout
simCmd.Stdout = outWriter
return simCmd.Run()
},
}
Expand Down

0 comments on commit e68c602

Please sign in to comment.