当前位置: 首页> 健康> 养生 > 网页设计公司介绍怎么写_设计兼职网站有哪些_国内最新消息_seo排名优化价格

网页设计公司介绍怎么写_设计兼职网站有哪些_国内最新消息_seo排名优化价格

时间:2025/8/28 1:52:49来源:https://blog.csdn.net/h_b__k/article/details/146611655 浏览次数:1次
网页设计公司介绍怎么写_设计兼职网站有哪些_国内最新消息_seo排名优化价格

目录

一、gdb 断点类型

二、通过proc文件系统 设置软断点

三、通过ptrace(PTRACE_POKETEXT) 设置软断点

四、软断点触发后的处理流程

五、代码实现

六、总结


 (代码:linux 6.3.1,架构:arm64)

One look is worth a thousand words.  —— Tess Flanders

相关链接:

linux ptrace 图文详解(一)基础介绍

linux ptrace 图文详解(二) PTRACE_TRACEME 跟踪程序

​​​​​​linux ptrace 图文详解(三) PTRACE_ATTACH 跟踪程序

在阅读本文内容之前,我们先思考下以下几个问题:

1)gdb设置软断点,是否有数量限制?

2)目标程序触发软断点并暂停后,gdb是如何得知被调试程序是因为gdb设置的软断点停下来的?

一、gdb 断点类型

        gdb中,最常用的一个调试手段就是打断点。不过,断点分为两种类型:软断点、硬断点。

  •         软断点

        通过软件的方式,将断点处的指令内容替换成 brk异常指令,当程序执行到断点指令处,会触发一个同步中断,最终将被调试程序暂停下来;

  •         硬断点

        通过配置CPU相关硬断点寄存器,无需改变被调试程序代码段,当程序执行到断点指令地址处时,CPU会主动触发一个断点异常,最终让被调试程序暂停下来;

  •         两者对比
软断点(software breakpoints)硬断点(hardware breakpoints)
实现方式通过在目标代码段中替换断点指令通过设置CPU调试寄存器实现
数量限制无限制调试寄存器数量有限,取决于CPU架构
性能开销较高,每次触发断点时需要额外处理较低,由硬件直接支持
适用范围仅适用于代码断点适用于代码断点、数据断点
设置方式通过gdb在目标代码处插入brk指令通过gdb设置CPU调试寄存器
触发机制执行到brk断点指令时,触发同步断点异常CPU访问到指定地址时,触发断点异常
适用场景需要再多个位置设置断点,无需监控数据访问需要监控特定内存地址的数据访问

        接下来,笔者将介绍下gdb中两种设置软断点的方式,由于篇幅限制,硬断点的实现原理后续文章会再作介绍。

二、通过proc文件系统 设置软断点

        通过proc文件系统中,被调试进程的mem文件,设置软断点的流程如下:

        1)被调试程序被暂停后,唤醒父进程gdb;

        2)用户在gdb中设置软断点;

        3)gdb中打开目标调试程序在proc文件系统中对应的 /proc/PID/mem 文件;

        4) 通过mem文件,修改进程虚拟地址空间中软断点所在指令内容,设置为brk指令(关于brk指令的一些介绍,可以参考笔者之前的这篇文章);

三、通过ptrace(PTRACE_POKETEXT) 设置软断点

        通过ptrace(PTRACE_POKETEXT) 设置软断点:

        1)当目标调试程序暂停后,唤醒gdb父进程开始运行;

        2)用户通过break设置软断点;

        3)gdb中,调用ptrace系统调用,传递软断点在目标程序中的虚拟地址、以及替换的指令内容(brk指令);

        4)陷入内核后,最终会调用copy_to_user_page,替换目标程序代码段内存中指定断点位置处的指令,替换成brk指令;

        5)设置完软断点后,用户执行continue唤醒调试程序继续运行;

        至此,两种设置软断点的实现原理介绍完毕,接下来,笔者将分析软断点触发后的内核处理流程。

四、软断点触发后的处理流程

        被调试程序,执行到断点处后,触发断点异常后的处理流程、以及gdb一些相关流程如下:

        1)程序执行到软断点处,由于断点处的指令被替换为brk指令,于是触发同步异常陷入内核;

        2)CPU跳转到内核的同步异常入口;

        3)在同步异常的处理函数中,通过检查esr_el1.EC(exception class)字段,发现当前同步异常的类型是BRK64类型,于是调用el0_dbg函数处理debug类型的异常;

        4)进一步调用到brk_handler去处理brk指令触发的同步异常;

        5)在brk_handler中,会调用send_user_sigtrap函数,给当前被调试程序发送SIGTRAP信号;

        6)在发送信号的同时,还会将当前程序触发异常的地址,记录到siginfo中,最终该siginfo对象会被保存到被调试程序的task_struct对象中,待后续gdb使用!

        7)上述流程执行完后,就从同步异常处理流程中返回,并在返回用户态的前夕,发现当前被调试程序有待处理的SIGTRAP信号,于是调用do_signal进行处理;

        8)由于当前程序属于PT_PTRACED状态,于是会走ptarce_signal处理流程,发送信号给父进程gdb,并唤醒父进程;

        9)gdb被唤醒后,会调用ptrace(PTRACE_GETSIGINFO),获取目标调试程序内核task_struct对象中保存的siginfo,进一步获取到被调试程序触发同步异常(即:软断点)时的代码段地址,用于与gdb内部维护的断点信息作比较,由此确定调试程序是触发了设置的软断点后暂停下来的!(解释了文章开头的 问题2)

        10)确定目标程序是因为触发了设置好的软断点暂停后,gdb将控制权交给用户;

五、代码实现

1、gdb通过proc文件系统设置软断点

set_raw_breakpoint_at {the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp)A.K.Alinux_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr, int size, raw_breakpoint *bp) {if (type == raw_bkpt_type_sw) {insert_memory_breakpoint (struct raw_breakpoint *bp) {unsigned char buf[MAX_BREAKPOINT_LEN]read_inferior_memory (bp->pc, buf, bp_size (bp))memcpy (bp->old_data, buf, bp_size (bp))err = the_target->write_memory (bp->pc, bp_opcode(bp), bp_size(bp))A.K.Alinux_process_target::write_memory (CORE_ADDR memaddr = bp->pc, const unsigned char *myaddr = bp_opcode(bp), int len) {proc_xfer_memory (memaddr, nullptr, myaddr, len) {process_info *proc = current_process()int fd = proc->priv->mem_fdwhile (len > 0) {lseek (fd, memaddr, SEEK_SET)write (fd, writebuf, len)memaddr += byteswritebuf += byteslen -= bytes}}}}}}
}

2、gdb通过ptrace(PTRACE_POKETEXT) 设置软断点

ptrace_request(struct task_struct *child, long request, unsigned long addr, unsigned long data) {switch (request) {case PTRACE_POKETEXT:return generic_ptrace_pokedata(struct task_struct *tsk = child, addr, data) {copied = ptrace_access_vm(tsk, addr, void *buf = &data, len = sizeof(data), gup_flags = FOLL_FORCE | FOLL_WRITE) {struct mm_struct *mmmm = get_task_mm(tsk)if (!tsk->ptrace || (current != tsk->parent) || ((get_dumpable(mm) != SUID_DUMP_USER) && !ptracer_capable(tsk, mm->user_ns))) {mmput(mm)return 0}ret = __access_remote_vm(mm, addr, buf, len, gup_flags) {struct vm_area_struct *vmaint write = gup_flags & FOLL_WRITEwhile (len) {get_user_pages_remote(mm, addr, 1, gup_flags, &page, &vma, NULL)bytes = lenoffset = addr & (PAGE_SIZE-1)maddr = kmap(page)if (write) {copy_to_user_page(vma, page, addr, maddr + offset, buf, bytes)		// <<<<<<< 设置软断点set_page_dirty_lock(page)} else {copy_from_user_page(vma, page, addr, buf, maddr + offset, bytes)}kunmap(page)put_page(page)len -= bytesbuf += bytesaddr += bytes}return buf - old_buf}//__access_remote_vmmmput(mm)return ret}//ptrace_access_vmreturn (copied == sizeof(data)) ? 0 : -EIO}//generic_ptrace_pokedata}
}

3、被调试程序触发软断点后的处理流程

// arch/arm64/kernel/entry-common.c
el0t_64_sync_handler {unsigned long esr = read_sysreg(esr_el1)switch (ESR_ELx_EC(esr))case ESR_ELx_EC_BRK64:el0_dbg {/* (1) 处理BRK64同步异常, 强制给自己发送SIGTRAP信号 */do_debug_exception {const struct fault_info *inf = esr_to_debug_fault_info(esr)return debug_fault_info + DBG_ESR_EVT(esr)inf->fn(addr_if_watchpoint, esr, regs)A.K.Abrk_handler {call_break_hook(regs, esr) // used for kprobesif (user_mode(regs))send_user_sigtrap(si_code = TRAP_BRKPT)arm64_force_sig_fault(SIGTRAP, si_code, instruction_pointer(regs), "User debug trap")force_sig_fault(signo, code, (void __user *)far)force_sig_fault_to_task(sig, code, addr, ___ARCH_SI_IA64(imm, flags, isr), current) {struct kernel_siginfo info;clear_siginfo(&info);info.si_signo = sig;		// A.K.A: SIGTRAPinfo.si_errno = 0;info.si_code  = code;		// A.K.A: TRAP_BRKPTinfo.si_addr  = addr;		// A.K.A: farreturn force_sig_info_to_task(&info, t, HANDLER_CURRENT);}}}/* (2) 返回用户态前夕处理信号, 发送SIGCHLD给parent, 若parent处于block wait就wake它, 并将自己挂起 */exit_to_user_mode {prepare_exit_to_user_modelocal_daif_maskdo_notify_resume {if (thread_flags & _TIF_NEED_RESCHED)schedule()if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))do_signal {get_signalptrace_signalptrace_stop}}}}
}

六、总结

        本文介绍了gdb中两种设置软断点的实现方式,以及程序触发软断点后的内核处理流程。

        软断点的本质:修改断点代码处的指令内容,替换成brk指令。

关键字:网页设计公司介绍怎么写_设计兼职网站有哪些_国内最新消息_seo排名优化价格

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: