提交 a039e5a9 编写于 作者: D Derek Parker

Add basic support for evaluating struct members

上级 46760aaa
......@@ -49,23 +49,23 @@ func (thread *ThreadContext) AllM() ([]*M, error) {
}
// parse addresses
procidInstructions, err := instructionsForMember("procid", thread.Process, reader)
procidInstructions, err := instructionsFor("procid", thread.Process, reader, true)
if err != nil {
return nil, err
}
spinningInstructions, err := instructionsForMember("spinning", thread.Process, reader)
spinningInstructions, err := instructionsFor("spinning", thread.Process, reader, true)
if err != nil {
return nil, err
}
alllinkInstructions, err := instructionsForMember("alllink", thread.Process, reader)
alllinkInstructions, err := instructionsFor("alllink", thread.Process, reader, true)
if err != nil {
return nil, err
}
blockedInstructions, err := instructionsForMember("blocked", thread.Process, reader)
blockedInstructions, err := instructionsFor("blocked", thread.Process, reader, true)
if err != nil {
return nil, err
}
curgInstructions, err := instructionsForMember("curg", thread.Process, reader)
curgInstructions, err := instructionsFor("curg", thread.Process, reader, true)
if err != nil {
return nil, err
}
......@@ -140,15 +140,19 @@ func (thread *ThreadContext) AllM() ([]*M, error) {
return allm, nil
}
func instructionsForMember(member string, dbp *DebuggedProcess, reader *dwarf.Reader) ([]byte, error) {
func instructionsFor(name string, dbp *DebuggedProcess, reader *dwarf.Reader, member bool) ([]byte, error) {
reader.Seek(0)
entry, err := findDwarfEntry(member, reader, true)
entry, err := findDwarfEntry(name, reader, member)
if err != nil {
return nil, err
}
instructions, ok := entry.Val(dwarf.AttrDataMemberLoc).([]byte)
instructions, ok := entry.Val(dwarf.AttrLocation).([]byte)
if !ok {
return nil, fmt.Errorf("type assertion failed")
instructions, ok = entry.Val(dwarf.AttrDataMemberLoc).([]byte)
if !ok {
return nil, fmt.Errorf("type assertion failed")
}
return instructions, nil
}
return instructions, nil
}
......@@ -314,15 +318,22 @@ func (thread *ThreadContext) EvalSymbol(name string) (*Variable, error) {
if err != nil {
return nil, err
}
fn := thread.Process.GoSymTable.PCToFunc(pc)
if fn == nil {
return nil, fmt.Errorf("could not func function scope")
}
reader := data.Reader()
if err = seekToFunctionEntry(fn.Name, reader); err != nil {
return nil, err
}
if strings.Contains(name, ".") {
idx := strings.Index(name, ".")
return evaluateStructMember(thread, data, reader, name[:idx], name[idx+1:])
}
entry, err := findDwarfEntry(name, reader, false)
if err != nil {
return nil, err
......@@ -403,6 +414,32 @@ func findDwarfEntry(name string, reader *dwarf.Reader, member bool) (*dwarf.Entr
return nil, fmt.Errorf("could not find symbol value for %s", name)
}
func evaluateStructMember(thread *ThreadContext, data *dwarf.Data, reader *dwarf.Reader, parent, member string) (*Variable, error) {
parentInstr, err := instructionsFor(parent, thread.Process, reader, false)
if err != nil {
return nil, err
}
memberInstr, err := instructionsFor(member, thread.Process, reader, true)
if err != nil {
return nil, err
}
reader.Seek(0)
entry, err := findDwarfEntry(member, reader, true)
if err != nil {
return nil, err
}
offset, ok := entry.Val(dwarf.AttrType).(dwarf.Offset)
if !ok {
return nil, fmt.Errorf("type assertion failed")
}
t, err := data.Type(offset)
if err != nil {
return nil, err
}
val, err := thread.extractValue(append(parentInstr, memberInstr...), 0, t)
return &Variable{Name: strings.Join([]string{parent, member}, "."), Type: t.String(), Value: val}, nil
}
// Extracts the value from the instructions given in the DW_AT_location entry.
// We execute the stack program described in the DW_OP_* instruction stream, and
// then grab the value from the other processes memory.
......
......@@ -32,6 +32,7 @@ func TestVariableEvaluation(t *testing.T) {
{"neg", "-1", "int"},
{"i8", "1", "int8"},
{"f32", "1.2", "float32"},
{"a6.Baz", "8", "int"},
}
helper.WithTestProcess(executablePath, t, func(p *proctl.DebuggedProcess) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册