跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 想到一个有趣的问题,为什么 debug 模式可以进断点而 run 模式不行?
未分類
14 11 月 2020

想到一个有趣的问题,为什么 debug 模式可以进断点而 run 模式不行?

想到一个有趣的问题,为什么 debug 模式可以进断点而 run 模式不行?

資深大佬 : wqgogogo 2

因为当在 debug 模式下一个断点时,IDE 将断点处程序的二进制替换为了 0xCC,即 INT 3 指令,当程序执行到 INT 3 时,再替换回原指令执行,而 run 模式并未做这个事。
大佬有話說 (38)

  • 資深大佬 : magiclx

    debug 模式,编译器什么的会给生成的可执行文件加入很多调试相关的信息

  • 資深大佬 : ZSeptember

    不同的语言采用的方式略有区别. 建议明确一下语言

  • 資深大佬 : Guaidaodl

    调试模式运行的时候,会有类似 DWARF 的调试文件生成,包含运行的指令与源文件行号、函数等信息,然后运行的时候会执行 ptrace 类似的函数,如 #1 所说,替换断点处的机器指令,可以查询当时各寄存器的值等信息。

    如果有源文件的话,IDE 支持在程序运行之后再把调试器挂载到指定进程。

    而普通模式运行的时候是很少与源文件相关的信息,不方便你对着源码去调试。

  • 資深大佬 : LuckyKoala

    @Guaidaodl Java 语言,idea 调试 Java 程序的时候

  • 主 資深大佬 : wqgogogo

    为什么你们连这个都懂…

  • 資深大佬 : luckyrayyy

    @magiclx
    @LuckyKoala
    这个都完全没接触过,又增加了新的知识点

  • 主 資深大佬 : wqgogogo

    一拍脑门,为什么我就没想到呢

  • 資深大佬 : atonku

    @atonku 哈哈,有时候有很多奇怪的想法,过一会就忘了,赶紧发出来分享下 ^_^

  • 主 資深大佬 : wqgogogo

    因为 run 模式不需要进断点

  • 資深大佬 : msaionyc

    主你这是想得太多学得太少,建议多看看基础知识的书籍。

  • 資深大佬 : scar263

    硬件支持,操作系统提供 api,编译器提供符号,调试器提供功能,想要理解调试的原理需要很多知识
    《软件调试》张银奎,这本书很不错,主有兴趣的话可以读一下

  • 資深大佬 : ju5t4fun

    。

  • 資深大佬 : yangJunKing

    正经科班都学过编译原理这门课吧。。

  • 資深大佬 : GrayXu

    Java 其实就是开了个特殊端口给调试器调用,其他没区别了

  • 資深大佬 : cheng6563

    @GrayXu 你看看人怎么回复的

  • 資深大佬 : warush

    @GrayXu 言语中暗贬主 不正经、非科班 呗

  • 資深大佬 : warush

    C 语言的话 GCC 编译参数不一样.
    生成的.o 文件也不一样.
    譬如 需要将机器码和代码做映射.

    另外执行方式也不同. 参考 ptrace.

  • 資深大佬 : chaleaoch

    @warush #17
    同意,装的自己很牛,啥信息也没提供.

  • 資深大佬 : Team

    除了加入调试相关信息外,debug 模式通常还会禁用代码优化,保证你写的什么就生成什么。
    release 下代码会经过大量优化,有可能你洋洋洒洒写了一大段的计算,最后被优化成一个常量什么的。
    像是 C 系的还会做 unroll 或者 vectorize,不关优化的话根本没法调试的。

  • 資深大佬 : msg7086

    好强。。

  • 資深大佬 : raaaaaar

    matlab 随时可停

  • 資深大佬 : fl2d

    以前 NOIP 用 Free Pascal 的时候看到文章说简单花指令 asm push pop 一下
    然后看到 FP 有 asm,顺便玩了下,然后发现编译输出 debug 的话仅仅 asm push xxx; pop xxx; end; fc 一看,差了非常非常多的部分。而如果编译输出为 release,就只多了几个字节。

  • 資深大佬 : no1xsyzy

    https://eli.thegreenplace.net/2011/01/27/how-debuggers-work-part-2-breakpoints

  • 資深大佬 : YenvY

    Java 的 debug 不是加 int 3 的,是 JVM 处理的。

  • 資深大佬 : atempcode

    @wqgogogo JPDA 了解一下.

  • 資深大佬 : Guaidaodl

    @warush @Team 这么敏感吗,这个问题的最简单的解答,就是 1L 说的 INT 3,学了编译原理或者汇编什么的就能理解了。这种东西都能装逼那门槛也太低了…建议大家以及在读的本科学生好好学习 CS 基础核心课程。

  • 資深大佬 : GrayXu

    release 模式的话,可以用 ollydb 之类的来设置断点,唔。。。。

  • 資深大佬 : akira

    @GrayXu #27 忽然想起一个梗,程序员分为 10 类,一类是折腾过硬件的,一类是没折腾过硬件的。

  • 資深大佬 : xuboying

    @magiclx #1 我胡乱猜测的:目测你说的这个应该是执行的时候发生的替换(几乎不可能是修改的编译后的文件),那么非 debug 模式,按道理也能进行替换,甚至插入指令。意思就是不管是不是 debug 模式都能 debug 。

    唯一想到的可能就是:非 debug 模式下不好去定位到源文件,也不好去处理变量名(也许都丢失了),然后调试器的开发者懒得去支持非 debug 模式调试

  • 資深大佬 : xiangyuecn

    @xuboying 应该说 0 类是没折腾过硬件的 高电平是折腾过硬件的 233

  • 資深大佬 : vantis

    软件工程专业…没学过编译原理…我确定学校没有安排这门课程…

  • 資深大佬 : luhe

    @GrayXu 编译原理真的讲这个吗

  • 資深大佬 : afx

    @magiclx 是的 再补充一个小细节,就是替换回原来的指令之后还需要把用户态 eip 往前挪一个字节,因为 trap 到内核后,内核栈存的 eip 是被替换指令字节的下一条指令,不然再次执行被替换指令就被 skipped 了

  • 資深大佬 : irytu

    前面有主说到位了,建议看一下 LLVM 编译原理这本书。简单说,run 的编译过程,做了指令集的优化处理,而 debug 模式可以不做指令集的优化,另外会在编译的代码中加入调试代码,只有这样才能实时的 IDE 中看到内存和执行位置。
    release 模式直接是汇编或者说是到了机器码,无调试,所以为了找到那一段代码 crash,会生成其他的文件来定位。

    debug 过程生产的代码未必到了汇编或者机器码,而只是编译器自己解析的逻辑代码,当然可以 debug 。

  • 資深大佬 : lujie2012

    java 的话 debug 是 jvm 层面实现的,ide 只是在调用接口,具体没深入了解过

  • 資深大佬 : MineDog

    如果是 native 程序的话,这个问题的主要跟“调试器”相关,debug 模式下运行的程序受调试器控制。native 调试器实现主要依赖硬件和操作系统提供的调试机制,跟编译器,编译原理无关。

  • 資深大佬 : amimo

    @MineDog #36 道理是差不多的,都是在二进制指令 生成了中断指令,或者使用 mprotect 这种系统调用 触发一个软中断调用

  • 資深大佬 : lewis89

    归根结底不是什么 INT3 的问题(说这个的你用过 od/IDA 么),是 release 模式有优化,编译器会打乱代码行序并且清除大量的编译相关信息以提升运行性能。这样你最多能看到调用了啥函数(某些 stripped 了的程序你连调用栈信息都看不到,里面只剩各种指针了),内部有什么指令偏移多少的信息没了,调试器看到你的源文件的时候不知道去哪里找对应的指令下断点。
    为啥 vs 的 release 模式就支持下断点呢,人家有 pdb 文件啊!
    debug 模式下编译器会在程序中插入调试用的符号表,以及使用未优化的代码(确保每行源代码都能对应上特定的二进制指令),所以下断点容易得多。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具