Skip to content

Commit 79c32e9

Browse files
committed
Initial commit
0 parents  commit 79c32e9

20 files changed

+1198
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
vendor/
2+
jdwpgo

Gopkg.lock

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Gopkg.toml example
2+
#
3+
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
4+
# for detailed Gopkg.toml documentation.
5+
#
6+
# required = ["github.com/user/thing/cmd/thing"]
7+
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
8+
#
9+
# [[constraint]]
10+
# name = "github.com/user/project"
11+
# version = "1.0.0"
12+
#
13+
# [[constraint]]
14+
# name = "github.com/user/project2"
15+
# branch = "dev"
16+
# source = "github.com/myfork/project2"
17+
#
18+
# [[override]]
19+
# name = "github.com/x/y"
20+
# version = "2.4.0"
21+
#
22+
# [prune]
23+
# non-go = false
24+
# go-tests = true
25+
# unused-packages = true
26+
27+
28+
[prune]
29+
go-tests = true
30+
unused-packages = true
31+
32+
[[constraint]]
33+
branch = "master"
34+
name = "github.com/golang-collections/go-datastructures"
35+
36+
[[constraint]]
37+
name = "gopkg.in/restruct.v1"
38+
version = "1.1.0"

api/jdwp/command.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package jdwp
2+
3+
// Command represents a command specification
4+
type Command struct {
5+
Commandset byte
6+
Command byte
7+
HasCommandData bool
8+
HasReplyData bool
9+
}

api/jdwp/error.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package jdwp

debuggercore/debuggercore.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package debuggercore
2+
3+
import (
4+
"encoding/binary"
5+
"errors"
6+
7+
"github.com/jquirke/jdwpgo/api/jdwp"
8+
"github.com/jquirke/jdwpgo/jdwpsession"
9+
"gopkg.in/restruct.v1"
10+
)
11+
12+
// DebuggerCore represents an instance of the debugger core
13+
type DebuggerCore interface {
14+
VMCommands() VMCommands
15+
ThreadCommands() ThreadCommands
16+
}
17+
18+
type debuggercore struct {
19+
jdwpsession jdwpsession.Session
20+
}
21+
22+
// NewFromJWDPSession creates a new instance of a debugger core
23+
// attached to a JWDP session
24+
func NewFromJWDPSession(session jdwpsession.Session) DebuggerCore {
25+
core := &debuggercore{
26+
jdwpsession: session,
27+
}
28+
29+
return core
30+
}
31+
32+
func (d *debuggercore) VMCommands() VMCommands {
33+
return d
34+
}
35+
36+
func (d *debuggercore) ThreadCommands() ThreadCommands {
37+
return d
38+
}
39+
40+
func (d *debuggercore) processCommand(cmd jdwp.Command, requestStruct interface{}, replyStruct interface{}) error {
41+
commandPacket := &jdwpsession.CommandPacket{
42+
Commandset: cmd.Commandset,
43+
Command: cmd.Command,
44+
}
45+
var err error
46+
if cmd.HasCommandData {
47+
commandPacket.Data, err = restruct.Pack(binary.BigEndian, requestStruct)
48+
if err != nil {
49+
return err
50+
}
51+
}
52+
// TODO implement timeout
53+
54+
replyCh := d.jdwpsession.SendCommand(commandPacket)
55+
56+
reply, ok := <-replyCh
57+
if !ok {
58+
return errors.New("Channel closed")
59+
}
60+
// TODO handle protocol returned err
61+
62+
if cmd.HasReplyData {
63+
err = restruct.Unpack(reply.Data, binary.BigEndian, replyStruct)
64+
}
65+
return err
66+
}

debuggercore/thread.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package debuggercore
2+
3+
import (
4+
"github.com/jquirke/jdwpgo/protocol/basetypes"
5+
"github.com/jquirke/jdwpgo/protocol/common"
6+
"github.com/jquirke/jdwpgo/protocol/thread"
7+
)
8+
9+
// ThreadCommands expose the ThreadCommands commands
10+
type ThreadCommands interface {
11+
// Basics
12+
Name(common.ThreadID) (basetypes.JDWPString, error)
13+
}
14+
15+
func (d *debuggercore) Name(threadID common.ThreadID) (basetypes.JDWPString, error) {
16+
nameCommandData := &thread.NameCommandData{
17+
ThreadID: threadID,
18+
}
19+
var nameReply thread.NameReply
20+
err := d.processCommand(thread.NameCommand, nameCommandData, &nameReply)
21+
if err != nil {
22+
return basetypes.EmptyJWDPString(), err
23+
}
24+
return nameReply.ThreadName, nil
25+
}

debuggercore/vm.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package debuggercore
2+
3+
import (
4+
"github.com/jquirke/jdwpgo/protocol/vm"
5+
)
6+
7+
// VMCommands expose the VM commands
8+
type VMCommands interface {
9+
// Class
10+
AllClasses() (*vm.AllClassReply, error)
11+
// Thread ops
12+
AllThreads() (*vm.AllThreadsReply, error)
13+
TopLevelThreadGroups() (*vm.TopLevelThreadGroupsReply, error)
14+
// Bootstrap
15+
Version() (*vm.VersionReply, error)
16+
IDSizes() (*vm.IDSizesReply, error)
17+
Capabilities() (*vm.CapabilitiesReply, error)
18+
CapabilitiesNew() (*vm.CapabilitiesNewReply, error)
19+
//Control
20+
Suspend() error
21+
Resume() error
22+
HoldEvents() error
23+
ReleaseEvents() error
24+
Exit(int32) error
25+
}
26+
27+
func (d *debuggercore) Version() (*vm.VersionReply, error) {
28+
var versionReply vm.VersionReply
29+
err := d.processCommand(vm.VersionCommand, nil, &versionReply)
30+
if err != nil {
31+
return nil, err
32+
}
33+
return &versionReply, nil
34+
}
35+
36+
func (d *debuggercore) AllClasses() (*vm.AllClassReply, error) {
37+
var allclassesReply vm.AllClassReply
38+
err := d.processCommand(vm.AllClassesCommand, nil, &allclassesReply)
39+
if err != nil {
40+
return nil, err
41+
}
42+
return &allclassesReply, nil
43+
}
44+
45+
func (d *debuggercore) AllThreads() (*vm.AllThreadsReply, error) {
46+
var allthreadsReply vm.AllThreadsReply
47+
err := d.processCommand(vm.AllThreadsCommand, nil, &allthreadsReply)
48+
if err != nil {
49+
return nil, err
50+
}
51+
return &allthreadsReply, nil
52+
}
53+
54+
func (d *debuggercore) TopLevelThreadGroups() (*vm.TopLevelThreadGroupsReply, error) {
55+
var topLevelThreadGroupsReply vm.TopLevelThreadGroupsReply
56+
err := d.processCommand(vm.TopLevelThreadGroupsCommand, nil, &topLevelThreadGroupsReply)
57+
if err != nil {
58+
return nil, err
59+
}
60+
return &topLevelThreadGroupsReply, nil
61+
}
62+
63+
func (d *debuggercore) IDSizes() (*vm.IDSizesReply, error) {
64+
var idsizesReply vm.IDSizesReply
65+
err := d.processCommand(vm.IDSizesCommand, nil, &idsizesReply)
66+
if err != nil {
67+
return nil, err
68+
}
69+
return &idsizesReply, nil
70+
}
71+
72+
func (d *debuggercore) Capabilities() (*vm.CapabilitiesReply, error) {
73+
var capsReply vm.CapabilitiesReply
74+
err := d.processCommand(vm.CapabilitiesCommand, nil, &capsReply)
75+
if err != nil {
76+
return nil, err
77+
}
78+
return &capsReply, nil
79+
}
80+
81+
func (d *debuggercore) CapabilitiesNew() (*vm.CapabilitiesNewReply, error) {
82+
var capsNewReply vm.CapabilitiesNewReply
83+
err := d.processCommand(vm.CapabilitiesNewCommand, nil, &capsNewReply)
84+
if err != nil {
85+
return nil, err
86+
}
87+
return &capsNewReply, nil
88+
}
89+
90+
func (d *debuggercore) Suspend() error {
91+
err := d.processCommand(vm.SuspendCommand, nil, nil)
92+
if err != nil {
93+
return err
94+
}
95+
return nil
96+
}
97+
98+
func (d *debuggercore) Resume() error {
99+
err := d.processCommand(vm.ResumeCommand, nil, nil)
100+
if err != nil {
101+
return err
102+
}
103+
return nil
104+
}
105+
106+
func (d *debuggercore) HoldEvents() error {
107+
err := d.processCommand(vm.HoldEventsCommand, nil, nil)
108+
if err != nil {
109+
return err
110+
}
111+
return nil
112+
}
113+
114+
func (d *debuggercore) ReleaseEvents() error {
115+
err := d.processCommand(vm.ReleaseEventsCommand, nil, nil)
116+
if err != nil {
117+
return err
118+
}
119+
return nil
120+
}
121+
122+
func (d *debuggercore) Exit(code int32) error {
123+
exitCommandData := &vm.ExitCommandData{
124+
ExitCode: code,
125+
}
126+
err := d.processCommand(vm.ExitCommand, exitCommandData, nil)
127+
if err != nil {
128+
return err
129+
}
130+
return nil
131+
}

0 commit comments

Comments
 (0)