github.com/go-delve/delve的源码学习

delve是golang专用的debug工具,原理类似于gdb,关于gdb的原理可以参考这篇文章。关于delve的源码学习,先写一个基础的demo如下:

package main

import (
    "github.com/go-delve/delve/pkg/proc"
    "github.com/go-delve/delve/pkg/proc/native"
)

func main() {
    targetGroup, err := native.Launch([]string{"./hello"}, "", 0, nil, "", [3]string{})
    fn, _ := targetGroup.Selected.BinInfo().FindFunction("main.main")
    _, err = targetGroup.Selected.SetBreakpoint(0, fn[0].Entry, proc.UserBreakpoint, nil)
    err = targetGroup.Continue()
    println(err)
    _ = targetGroup.Detach(true)
}

分析demo的调用栈如下:

targetGroup, err := native.Launch()
|-dbp := newProcess(0)
  |-newPtraceThread()
    |-go pt.handlePtraceFuncs()
|-dbp.execPtraceFunc(fn)
  |-dbp.ptraceThread.ptraceChan <- fn
  |-execute fn
  |-<-dbp.ptraceThread.ptraceDoneChan
|-tgt, err := dbp.initialize()
  |-procgrp.add(dbp, ...)
    |-procgrp.addTarget()
      |-t := grp.newTarget()
      |-grp.Selected = t
targetGroup.Selected.SetBreakpoint()      // 设置断点
|-target.proc.WriteBreakpoint()
  |-nativeProcess.WriteBreakpoint()
    |-nativeProcess.memthread.ReadMemory(bp.OriginalData, bp.Addr)
      |-read and save the original data   // 读取断点位置1字节的代码
    |-dbp.writeSoftwareBreakpoint()
      |-write int3(0XCC) command          // 修改断点位置1字节的代码为int3
|-setLogicalBreakpoint(newBreakpoint)
  |-target.proc.BreakpointMap.Logical[bid] = lbp
  |-target.proc.BreakpointMap.[addr] = bp


go pt.handlePtraceFuncs()
|-native.newPtraceThread.func1
  |-native.(*ptraceThread).handlePtraceFuncs
    |-fn := <-dbp.ptraceThread.ptraceChan
    |-native.Launch.func1
    |-dbp.ptraceThread.ptraceDoneChan <- nil
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!