diff options
| author | Austin Clements <aclements@csail.mit.edu> | 2009-09-04 11:58:00 -0700 | 
|---|---|---|
| committer | Austin Clements <aclements@csail.mit.edu> | 2009-09-04 11:58:00 -0700 | 
| commit | cd435919e10f9af67192eae5165380e0788571a9 (patch) | |
| tree | 5e36d916dac493aed9518441bbb7d6ee1d6ce446 /usr/austin/ogle/rvalue.go | |
| parent | a861fb9481253312ee92a77e482cca731a56227a (diff) | |
| download | golang-cd435919e10f9af67192eae5165380e0788571a9.tar.gz | |
Update debugger to use Abort interface
R=rsc
APPROVED=rsc
DELTA=314  (132 added, 2 deleted, 180 changed)
OCL=34376
CL=34396
Diffstat (limited to 'usr/austin/ogle/rvalue.go')
| -rw-r--r-- | usr/austin/ogle/rvalue.go | 246 | 
1 files changed, 162 insertions, 84 deletions
| diff --git a/usr/austin/ogle/rvalue.go b/usr/austin/ogle/rvalue.go index 9e5a6ab55..1449ed660 100644 --- a/usr/austin/ogle/rvalue.go +++ b/usr/austin/ogle/rvalue.go @@ -7,6 +7,7 @@ package ogle  import (  	"eval";  	"fmt"; +	"os";  	"ptrace";  ) @@ -34,7 +35,7 @@ type remote struct {  	p *Process;  } -func (v remote) Get(size int) uint64 { +func (v remote) Get(a aborter, size int) uint64 {  	// TODO(austin) This variable might temporarily be in a  	// register.  We could trace the assembly back from the  	// current PC, looking for the beginning of the function or a @@ -55,18 +56,18 @@ func (v remote) Get(size int) uint64 {  	buf := arr[0:size];  	_, err := v.p.Peek(v.base, buf);  	if err != nil { -		eval.Abort(err); +		a.Abort(err);  	}  	return uint64(v.p.ToWord(buf));  } -func (v remote) Set(size int, x uint64) { +func (v remote) Set(a aborter, size int, x uint64) {  	var arr [8]byte;  	buf := arr[0:size];  	v.p.FromWord(ptrace.Word(x), buf);  	_, err := v.p.Poke(v.base, buf);  	if err != nil { -		eval.Abort(err); +		a.Abort(err);  	}  } @@ -74,6 +75,15 @@ func (v remote) plus(x ptrace.Word) remote {  	return remote{v.base + x, v.p};  } +func tryRVString(f func(a aborter) string) string { +	var s string; +	err := try(func(a aborter) { s = f(a) }); +	if err != nil { +		return fmt.Sprintf("<error: %v>", err); +	} +	return s; +} +  /*   * Bool   */ @@ -83,22 +93,30 @@ type remoteBool struct {  }  func (v remoteBool) String() string { -	return fmt.Sprintf("%v", v.Get()); +	return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) }); +} + +func (v remoteBool) Assign(t *eval.Thread, o eval.Value) { +	v.Set(t, o.(eval.BoolValue).Get(t)); +} + +func (v remoteBool) Get(t *eval.Thread) bool { +	return v.aGet(t);  } -func (v remoteBool) Assign(o eval.Value) { -	v.Set(o.(eval.BoolValue).Get()); +func (v remoteBool) aGet(a aborter) bool { +	return v.r.Get(a, 1) != 0;  } -func (v remoteBool) Get() bool { -	return v.r.Get(1) != 0; +func (v remoteBool) Set(t *eval.Thread, x bool) { +	v.aSet(t, x);  } -func (v remoteBool) Set(x bool) { +func (v remoteBool) aSet(a aborter, x bool) {  	if x { -		v.r.Set(1, 1); +		v.r.Set(a, 1, 1);  	} else { -		v.r.Set(1, 0); +		v.r.Set(a, 1, 0);  	}  } @@ -120,19 +138,27 @@ type remoteUint struct {  }  func (v remoteUint) String() string { -	return fmt.Sprintf("%v", v.Get()); +	return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) }); +} + +func (v remoteUint) Assign(t *eval.Thread, o eval.Value) { +	v.Set(t, o.(eval.UintValue).Get(t));  } -func (v remoteUint) Assign(o eval.Value) { -	v.Set(o.(eval.UintValue).Get()); +func (v remoteUint) Get(t *eval.Thread) uint64 { +	return v.aGet(t);  } -func (v remoteUint) Get() uint64 { -	return v.r.Get(v.size); +func (v remoteUint) aGet(a aborter) uint64 { +	return v.r.Get(a, v.size);  } -func (v remoteUint) Set(x uint64) { -	v.r.Set(v.size, x); +func (v remoteUint) Set(t *eval.Thread, x uint64) { +	v.aSet(t, x); +} + +func (v remoteUint) aSet(a aborter, x uint64) { +	v.r.Set(a, v.size, x);  }  func (v remoteUint) addr() remote { @@ -173,19 +199,27 @@ type remoteInt struct {  }  func (v remoteInt) String() string { -	return fmt.Sprintf("%v", v.Get()); +	return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) }); +} + +func (v remoteInt) Assign(t *eval.Thread, o eval.Value) { +	v.Set(t, o.(eval.IntValue).Get(t)); +} + +func (v remoteInt) Get(t *eval.Thread) int64 { +	return v.aGet(t);  } -func (v remoteInt) Assign(o eval.Value) { -	v.Set(o.(eval.IntValue).Get()); +func (v remoteInt) aGet(a aborter) int64 { +	return int64(v.r.Get(a, v.size));  } -func (v remoteInt) Get() int64 { -	return int64(v.r.Get(v.size)); +func (v remoteInt) Set(t *eval.Thread, x int64) { +	v.aSet(t, x);  } -func (v remoteInt) Set(x int64) { -	v.r.Set(v.size, uint64(x)); +func (v remoteInt) aSet(a aborter, x int64) { +	v.r.Set(a, v.size, uint64(x));  }  func (v remoteInt) addr() remote { @@ -222,15 +256,19 @@ type remoteFloat struct {  }  func (v remoteFloat) String() string { -	return fmt.Sprintf("%v", v.Get()); +	return tryRVString(func(a aborter) string { return fmt.Sprintf("%v", v.aGet(a)) }); +} + +func (v remoteFloat) Assign(t *eval.Thread, o eval.Value) { +	v.Set(t, o.(eval.FloatValue).Get(t));  } -func (v remoteFloat) Assign(o eval.Value) { -	v.Set(o.(eval.FloatValue).Get()); +func (v remoteFloat) Get(t *eval.Thread) float64 { +	return v.aGet(t);  } -func (v remoteFloat) Get() float64 { -	bits := v.r.Get(v.size); +func (v remoteFloat) aGet(a aborter) float64 { +	bits := v.r.Get(a, v.size);  	switch v.size {  	case 4:  		return float64(v.r.p.ToFloat32(uint32(bits))); @@ -240,7 +278,11 @@ func (v remoteFloat) Get() float64 {  	panic("Unexpected float size ", v.size);  } -func (v remoteFloat) Set(x float64) { +func (v remoteFloat) Set(t *eval.Thread, x float64) { +	v.aSet(t, x); +} + +func (v remoteFloat) aSet(a aborter, x float64) {  	var bits uint64;  	switch v.size{  	case 4: @@ -250,7 +292,7 @@ func (v remoteFloat) Set(x float64) {  	default:  		panic("Unexpected float size ", v.size);  	} -	v.r.Set(v.size, bits); +	v.r.Set(a, v.size, bits);  }  func (v remoteFloat) addr() remote { @@ -278,30 +320,38 @@ type remoteString struct {  }  func (v remoteString) String() string { -	return v.Get(); +	return tryRVString(func(a aborter) string { return v.aGet(a) });  } -func (v remoteString) Assign(o eval.Value) { -	v.Set(o.(eval.StringValue).Get()); +func (v remoteString) Assign(t *eval.Thread, o eval.Value) { +	v.Set(t, o.(eval.StringValue).Get(t));  } -func (v remoteString) Get() string { +func (v remoteString) Get(t *eval.Thread) string { +	return v.aGet(t); +} + +func (v remoteString) aGet(a aborter) string {  	rs := v.r.p.runtime.String.mk(v.r).(remoteStruct); -	str := ptrace.Word(rs.Field(v.r.p.f.String.Str).(remoteUint).Get()); -	len := rs.Field(v.r.p.f.String.Len).(remoteInt).Get(); +	str := ptrace.Word(rs.field(v.r.p.f.String.Str).(remoteUint).aGet(a)); +	len := rs.field(v.r.p.f.String.Len).(remoteInt).aGet(a);  	bytes := make([]uint8, len);  	_, err := v.r.p.Peek(str, bytes);  	if err != nil { -		eval.Abort(err); +		a.Abort(err);  	}  	return string(bytes);  } -func (v remoteString) Set(x string) { +func (v remoteString) Set(t *eval.Thread, x string) { +	v.aSet(t, x); +} + +func (v remoteString) aSet(a aborter, x string) {  	// TODO(austin) This isn't generally possible without the  	// ability to allocate remote memory. -	eval.Abort(RemoteMismatchError("remote strings cannot be assigned to")); +	a.Abort(RemoteMismatchError("remote strings cannot be assigned to"));  }  func mkString(r remote) eval.Value { @@ -324,30 +374,34 @@ func (v remoteArray) String() string {  		if i > 0 {  			res += ", ";  		} -		res += v.Elem(i).String(); +		res += v.elem(i).String();  	}  	return res + "}";  } -func (v remoteArray) Assign(o eval.Value) { +func (v remoteArray) Assign(t *eval.Thread, o eval.Value) {   	// TODO(austin) Could do a bigger memcpy if o is a  	// remoteArray in the same Process.  	oa := o.(eval.ArrayValue);  	for i := int64(0); i < v.len; i++ { -		v.Elem(i).Assign(oa.Elem(i)); +		v.Elem(t, i).Assign(t, oa.Elem(t, i));  	}  } -func (v remoteArray) Get() eval.ArrayValue { +func (v remoteArray) Get(t *eval.Thread) eval.ArrayValue {  	return v;  } -func (v remoteArray) Elem(i int64) eval.Value { +func (v remoteArray) Elem(t *eval.Thread, i int64) eval.Value { +	return v.elem(i); +} + +func (v remoteArray) elem(i int64) eval.Value {  	return v.elemType.mk(v.r.plus(ptrace.Word(int64(v.elemType.size) * i)));  } -func (v remoteArray) From(i int64) eval.ArrayValue { -	return remoteArray{v.r.plus(ptrace.Word(int64(v.elemType.size) * i)), v.len - i, v.elemType}; +func (v remoteArray) Sub(i int64, len int64) eval.ArrayValue { +	return remoteArray{v.r.plus(ptrace.Word(int64(v.elemType.size) * i)), len, v.elemType};  }  /* @@ -370,25 +424,29 @@ func (v remoteStruct) String() string {  		if i > 0 {  			res += ", ";  		} -		res += v.Field(i).String(); +		res += v.field(i).String();  	}  	return res + "}";  } -func (v remoteStruct) Assign(o eval.Value) { +func (v remoteStruct) Assign(t *eval.Thread, o eval.Value) {  	// TODO(austin) Could do a bigger memcpy.  	oa := o.(eval.StructValue);  	l := len(v.layout);  	for i := 0; i < l; i++ { -		v.Field(i).Assign(oa.Field(i)); +		v.Field(t, i).Assign(t, oa.Field(t, i));  	}  } -func (v remoteStruct) Get() eval.StructValue { +func (v remoteStruct) Get(t *eval.Thread) eval.StructValue {  	return v;  } -func (v remoteStruct) Field(i int) eval.Value { +func (v remoteStruct) Field(t *eval.Thread, i int) eval.Value { +	return v.field(i); +} + +func (v remoteStruct) field(i int) eval.Value {  	f := &v.layout[i];  	return f.fieldType.mk(v.r.plus(ptrace.Word(f.offset)));  } @@ -411,35 +469,45 @@ type remotePtr struct {  }  func (v remotePtr) String() string { -	e := v.Get(); -	if e == nil { -		return "<nil>"; -	} -	return "&" + e.String(); +	return tryRVString(func(a aborter) string { +		e := v.aGet(a); +		if e == nil { +			return "<nil>"; +		} +		return "&" + e.String(); +	});  } -func (v remotePtr) Assign(o eval.Value) { -	v.Set(o.(eval.PtrValue).Get()); +func (v remotePtr) Assign(t *eval.Thread, o eval.Value) { +	v.Set(t, o.(eval.PtrValue).Get(t));  } -func (v remotePtr) Get() eval.Value { -	addr := ptrace.Word(v.r.Get(v.r.p.PtrSize())); +func (v remotePtr) Get(t *eval.Thread) eval.Value { +	return v.aGet(t); +} + +func (v remotePtr) aGet(a aborter) eval.Value { +	addr := ptrace.Word(v.r.Get(a, v.r.p.PtrSize()));  	if addr == 0 {  		return nil;  	}  	return v.elemType.mk(remote{addr, v.r.p});  } -func (v remotePtr) Set(x eval.Value) { +func (v remotePtr) Set(t *eval.Thread, x eval.Value) { +	v.aSet(t, x); +} + +func (v remotePtr) aSet(a aborter, x eval.Value) {  	if x == nil { -		v.r.Set(v.r.p.PtrSize(), 0); +		v.r.Set(a, v.r.p.PtrSize(), 0);  		return;  	}  	xr, ok := x.(remoteValue);  	if !ok || v.r.p != xr.addr().p { -		eval.Abort(RemoteMismatchError("remote pointer must point within the same process")); +		a.Abort(RemoteMismatchError("remote pointer must point within the same process"));  	} -	v.r.Set(v.r.p.PtrSize(), uint64(xr.addr().base)); +	v.r.Set(a, v.r.p.PtrSize(), uint64(xr.addr().base));  }  func (v remotePtr) addr() remote { @@ -456,39 +524,49 @@ type remoteSlice struct {  }  func (v remoteSlice) String() string { -	b := v.Get().Base; -	if b == nil { -		return "<nil>"; -	} -	return b.String(); +	return tryRVString(func(a aborter) string { +		b := v.aGet(a).Base; +		if b == nil { +			return "<nil>"; +		} +		return b.String(); +	}); +} + +func (v remoteSlice) Assign(t *eval.Thread, o eval.Value) { +	v.Set(t, o.(eval.SliceValue).Get(t));  } -func (v remoteSlice) Assign(o eval.Value) { -	v.Set(o.(eval.SliceValue).Get()); +func (v remoteSlice) Get(t *eval.Thread) eval.Slice { +	return v.aGet(t);  } -func (v remoteSlice) Get() eval.Slice { +func (v remoteSlice) aGet(a aborter) eval.Slice {  	rs := v.r.p.runtime.Slice.mk(v.r).(remoteStruct); -	base := ptrace.Word(rs.Field(v.r.p.f.Slice.Array).(remoteUint).Get()); -	nel := rs.Field(v.r.p.f.Slice.Len).(remoteInt).Get(); -	cap := rs.Field(v.r.p.f.Slice.Cap).(remoteInt).Get(); +	base := ptrace.Word(rs.field(v.r.p.f.Slice.Array).(remoteUint).aGet(a)); +	nel := rs.field(v.r.p.f.Slice.Len).(remoteInt).aGet(a); +	cap := rs.field(v.r.p.f.Slice.Cap).(remoteInt).aGet(a);  	if base == 0 {  		return eval.Slice{nil, nel, cap};  	}  	return eval.Slice{remoteArray{remote{base, v.r.p}, nel, v.elemType}, nel, cap};  } -func (v remoteSlice) Set(x eval.Slice) { +func (v remoteSlice) Set(t *eval.Thread, x eval.Slice) { +	v.aSet(t, x); +} + +func (v remoteSlice) aSet(a aborter, x eval.Slice) {  	rs := v.r.p.runtime.Slice.mk(v.r).(remoteStruct);  	if x.Base == nil { -		rs.Field(v.r.p.f.Slice.Array).(remoteUint).Set(0); +		rs.field(v.r.p.f.Slice.Array).(remoteUint).aSet(a, 0);  	} else {  		ar, ok := x.Base.(remoteArray);  		if !ok || v.r.p != ar.r.p { -			eval.Abort(RemoteMismatchError("remote slice must point within the same process")); +			a.Abort(RemoteMismatchError("remote slice must point within the same process"));  		} -		rs.Field(v.r.p.f.Slice.Array).(remoteUint).Set(uint64(ar.r.base)); +		rs.field(v.r.p.f.Slice.Array).(remoteUint).aSet(a, uint64(ar.r.base));  	} -	rs.Field(v.r.p.f.Slice.Len).(remoteInt).Set(x.Len); -	rs.Field(v.r.p.f.Slice.Cap).(remoteInt).Set(x.Cap); +	rs.field(v.r.p.f.Slice.Len).(remoteInt).aSet(a, x.Len); +	rs.field(v.r.p.f.Slice.Cap).(remoteInt).aSet(a, x.Cap);  } | 
