您最困难的错误搜寻是什么?如何找到并杀死它?


31

这是一个“共享知识”问题。我有兴趣从您的成功和/或失败中学习。

可能有用的信息...

背景:

  • 上下文:语言,应用程序,环境等
  • 错误是如何识别的?
  • 谁或什么识别出该错误?
  • 复制错误有多复杂?

狩猎。

  • 你有什么计划?
  • 您遇到了什么困难?
  • 最终如何找到违规代码?

杀人。

  • 解决方法有多复杂?
  • 您如何确定修补程序的范围?
  • 该修复程序涉及多少代码?

验尸。

  • 技术上的根本原因是什么?缓冲区溢出等
  • 30,000英尺的根本原因是什么?
  • 该过程最终需要多长时间?
  • 该修复程序是否有不利影响的功能?
  • 您发现哪些方法,工具,动机特别有用?...非常没用?
  • 如果你能再做一遍吗?............

这些示例是通用示例,不适用于所有情况,并且可能无用。请根据需要调味。

Answers:


71

它实际上是在我们应用程序的第三方图像查看器子组件中。

我们发现,我们的应用程序中有2-3个用户会经常使图像查看器组件抛出异常并可怕地死亡。但是,我们有许多其他用户尽管在大多数工作日中都使用该应用程序执行相同任务,但从未看到此问题。特别是,还有一个用户比其他用户更频繁地获得它。

我们尝试了通常的步骤:

(1)让他们与从来没有问题的其他用户交换计算机以排除计算机/配置。-问题跟在他们后面。

(2)让他们登录到应用程序并以从未发现问题的用户身份工作。-问题依旧存在。

(3)让用户报告他们正在查看的图像,并设置测试工具以快速连续地重复查看该图像数千次。线束中未出现问题。

(4)让开发人员与用户坐在一起,整天看着他们。他们看到了错误,但没有注意到他们做任何与众不同的事情来导致它们。

我们为此进行了数周的努力,试图找出“错误用户”与其他用户没有的共同点。我不知道该如何做,但是步骤(4)中的开发人员在努力工作的那一天值得一看,值得值得百科全书布朗(Encyclopedia Brown)参加。

他意识到所有“错误用户”都是左撇子,并证实了这一事实。只有惯用左手的用户会遇到错误,而不会出现Righties。但是,左撇子怎么会导致错误呢?

我们让他坐下,看着左撇子再次特别注意他们可能做的不同事情,这就是我们发现它的方式。

事实证明,仅当您在加载新图像时将鼠标移动到图像查看器中最右边的像素列时才发生该错误(溢出错误,因为供应商对鼠标悬停事件进行了1​​-off计算)。

显然,在等待下一个图像加载时,所有用户都自然地将他们的手(以及鼠标)移向键盘。

碰巧最常发生错误的一个用户是那些ADD类型中的一种,它在等待下一页加载时不耐烦地强迫她的鼠标四处移动,因此她可以更快地将鼠标向右移动并击中时机恰到好处,所以她在加载事件发生时就做到了。直到我们从供应商那里获得了修复程序,我们才告诉她只是在单击(下一个文档)后放开鼠标,直到加载后才触摸它。

此后在开发团队中被称为“左手臭虫”


14
那是我所听说过的最邪恶的事情。
内森·泰勒

9
不过,它使解决这个问题的人成为了英雄。
JohnFx 2010年

2
哇,这真是个漏洞!
米切尔卖家

3
很棒的发现!好故事。
Toon Krijthe

11
好像我们的左撇子还没有像二等公民那样受到足够的对待。现在,我们还必须承担更多的错误,而不仅仅是我们的错误……谢谢,谢谢!:p
Dan Moulding 2010年

11

这是从很久以前(1980年代后期)开始的。

我工作的公司编写了一个CAD软件包(在FORTRAN中),该软件包可以在各种Unix工作站(HP,Sun,Silcon Graphics等)上运行。我们使用自己的文件格式来存储数据,并且在程序包启动时,磁盘空间不足,因此在实体头中有很多移位用于存储多个标志。

存储时,实体的类型(线,弧,文本等)乘以4096(我认为)。另外,该值取反表示已删除项目。因此,要获得该类型,我们需要执行以下代码:

type = record[1] MOD 4096

在除一台机器上的每台机器上,这给出了±1(对于一条线),±2(对于一条弧线)等,然后我们可以检查符号以查看是否被删除。

在一台机器上(我认为是HP),我们遇到了一个怪异的问题,即删除项目的处理被搞砸了。

这是在IDE和可视调试器出现之前的日子,所以我不得不插入跟踪语句和日志记录以尝试找出问题所在。

我最终发现这是因为其他所有制造商都实施了MOD-4096 MOD 4096结果导致-1HP在数学上正确实施了,-4096 MOD 4096结果是-4097

最后,我不得不遍历整个代码库,保存值的正负号,MOD然后在执行之前将其设置为正数,然后将结果乘以正负号。

这花了几天。


3
这些年来,可能有更多困难的错误搜寻,但是这个想法在我心中已经存在了20多年了!
克里斯·

7

哇,在这里好读书!

我最难过的是几年前Turbo Pascal大的时候,尽管它可能是当时的早期C ++ IDE之一。作为唯一的开发人员(和该初创公司的第三人),我写了类似简化的对销售人员友好的CAD程序。当时很棒,但是却出现了令人讨厌的随机崩溃。复制是不可能的,但是经常发生,以至于我开始寻找错误。

我最好的策略是单步调试器。该错误仅在用户输入了足够多的图形并且可能必须处于某种模式或缩放状态时才发生,因此存在许多繁琐的设置和清除断点,正常运行一分钟即可输入图形,然后逐步执行大量代码。断点会跳过一些可调整的次数然后中断,这特别有用。整个练习必须重复几次。

最终,我将其范围缩小到一个被调用子程序的地方,给它一个2,但是从里面看到了一些乱码。我本可以早点抓住这个问题的,但是并没有进入这个子例程,假设它已经得到了它。假设最简单的事情就可以蒙蔽眼睛!

原来是在堆栈上填充了16位int,但是该子例程期望32位。或类似的东西。编译器没有自动将所有值填充到32位,也没有进行足够的类型检查。只需一行的一部分即可解决,几乎不需要任何思考。但是到那儿花了三天的时间去追问明显的问题。

因此,我有一段关于昂贵顾问的轶事的个人经验,一会儿在某处轻按一下,收取2000美元。高管要求进行细目分类,水龙头的价格为1美元,知道水龙头的价格为1999美元。除了我的情况,那是时间而不是金钱。

获得的经验教训:1)使用最佳的编译器,其中“最佳”的定义是包括检查计算机科学知道如何检查的尽可能多的问题,以及2)对简单的显而易见的事物提出质疑,或者至少验证它们的正常功能。

从那以后,所有困难的bug都变得非常困难,因为我知道要比看似需要的更彻底地检查简单的事情。

第2课也适用于我所修复过的最棘手的电子错误,也进行了一些琐碎的修复,但是好几个智能EE被困了几个月。但这不是电子论坛,所以我不再赘述。


请在其他地方发布电子错误,并在此处链接!
tgkprog 2013年

6

来自地狱的网络数据竞争状况

我正在编写网络客户端/服务器(Windows XP / C#),以便在另一个开发人员编写的非常老的(Encore 32/77)工作站上使用类似的应用程序。

该应用程序所做的基本上是在主机上共享/处理某些数据,以控制我们的花式基于PC的多显示器触摸屏UI的主机进程。

它使用3层结构来做到这一点。通信过程向主机读取/写入数据,进行所有必要的格式转换(字节序,浮点格式等),并将值写入/读取数据库。该数据库充当了通讯和触摸屏用户界面之间的数据中介。触摸屏UI的应用程序根据连接到PC的监视器数量(它会自动检测到此情况)生成触摸屏界面。

在给定的时间范围内,主机和我们的PC之间一次只能发送最多128个值,每次往返最大延迟为〜110ms(UDP用于在两个主机之间进行直接x-over以太网连接计算机)。因此,严格控制基于连接的触摸屏的可变数量允许的变量数量。此外,主机(尽管具有相当复杂的多处理器体系结构,并且具有用于实时计算的共享内存总线)具有我手机的处理能力的大约1/100,因此它被要求执行尽可能少的处理,并且它是服务器/ client必须以汇编形式编写以确保这一点(主机正在运行不受我们程序影响的完整实时模拟)。

问题是。在触摸屏上更改某些值时,不仅会采用新输入的值,还会在该值和先前的值之间随机循环。这种现象只有在某些特定页面上的某些特定值与页面的某种组合下才会表现出来。在开始通过最初的客户接受流程开始运行之前,我们几乎完全错过了该问题


为了解决这个问题,我选择了一个振荡值:

  • 我检查了触摸屏应用程序,它正在振荡
  • 我检查了数据库,振荡了
  • 我检查了通讯应用程序

然后我爆发了wireshark,开始手动解码数据包捕获。结果:

  • 没有振荡,但数据包看起来不正确,数据太多。

我遍历了comms代码的每个细节一百次,没有发现任何缺陷/错误。

最终,我开始向另一位开发人员发送电子邮件,详细询问他的工作如何查看我是否缺少某些东西。然后我找到了。

显然,当他发送数据时,他没有在传输之前刷新数据数组,因此,从本质上讲,他只是用新值覆盖了使用的最后一个缓冲区,而新值覆盖了旧值,但仍未被传输的旧值仍在传输。

因此,如果某个值位于数据数组的位置80,并且所请求的值列表更改为小于80,但该相同值包含在新列表中,则这两个值将在该数据缓冲区的任何位置存在于该特定缓冲区中。给定时间。

从数据库中读取的值取决于UI请求该值的时间片。


解决方法非常简单。读入数据缓冲区中传入的项目数(实际上已包含在数据包协议中),不要读取超出该项目数的缓冲区。


得到教训:

  • 不要将现代计算能力视为理所当然。曾经有一段时间,计算机不支持以太网,而冲洗阵列可能被认为是昂贵的。如果您真的想看看我们走了多远,请想象一个几乎没有任何形式的动态内存分配的系统。IE,执行过程必须按顺序为所有程序预分配所有内存,并且没有程序可以超出该范围。IE,在不重新编译整个系统的情况下为程序分配更多的内存可能会导致严重的崩溃。我想知道是否有人会以同样的方式谈论垃圾收集的日子。

  • 使用自定义协议进行联网(或通常处理二进制数据表示形式)时,请确保您已阅读规范,直到了解通过管道发送的每个值的每个功能。我的意思是,请阅读直到您的眼睛受伤为止。人们通过操纵单个位或字节来处理数据,它们具有非常聪明和有效的处理方式。缺少最细微的细节可能会破坏系统。

修复的总时间为2-3天,其中大部分时间花在其他事情上,这让我感到沮丧。

注意:默认情况下,所讨论的主机不支持以太网。驱动它的卡是定制和改装的,实际上协议栈根本不存在。与我一起工作的开发人员是程序员的地狱,他不仅在该项目的系统上实现了UDP的精简版和最少的假以太网堆栈(处理器的功能不足以处理完整的以太网堆栈)但是他不到一周就做到了。他还是最初设计和编程操作系统的原始项目团队负责人之一。可以这么说,无论他经历了多久或有多少新知识,他必须分享的有关计算机/编程/体系结构的所有内容,我都会听每个单词。


5

背景

  • 在任务关键的WCF应用程序中,它驱动网站并提供后端事务处理。
  • 大容量应用程序(每秒数百个呼叫)
  • 多服务器多个实例
  • 数百次通过单元测试和无数次质量检查攻击

错误

  • 在投入生产后,服务器将在随机的时间内正常运行,然后开始迅速降级,使盒装CPU达到100%。

我是怎么找到的

起初,我确定这是正常的性能问题,所以我创建了详细的日志记录。在与数据库人员讨论利用率的每个呼叫中​​检查性能,观察服务器是否有问题。1周

然后,我确定我遇到了线程争用问题。我检查了尝试创建情境创建工具的死锁,以尝试在调试中创建情境。随着越来越多的管理人员感到沮丧,我转向同龄人,他们提出了从重新启动项目到将服务器限制为一个线程的建议。1.5周

然后,我看着 Tess Ferrandez博客创建了一个用户转储文件,并在服务器下次转储时使用windebug对其进行了处理。发现我所有的线程都卡在了dictionary.add函数中。

长而短的一本小字典,只是跟踪要向其中写入x线程错误的日志,因此未同步。


3

我们有一个正在与硬件设备通信的应用程序,在某些情况下,如果物理上拔下该设备直到将其重新插入并进行两次软复位,在某些情况下将无法正确运行。

问题原来是,启动时运行的应用程序尝试从尚未挂载的文件系统读取时偶尔会出现段错误(例如,如果用户将其配置为从NFS卷读取)。在启动时,应用程序将向驱动程序发送一些ioctl来初始化设备,然后读取配置设置并发送更多ioctl以将设备置于正确的状态。

进行初始化调用时,驱动程序中的错误导致将无效值写入设备,但是一旦调用使设备处于特定状态,该值就会被有效数据覆盖。

该设备本身有电池,可以检测主板是否断电,并会向易失性存储器中写入一个标志,指示其断电,然后在下次开机时会进入特定状态,并在特定时间需要发送指令以清除标志。

问题在于,如果一旦发送完ioctl来初始化设备(并将无效值写入设备),但又没有发送有效数据,就断电了。重新打开设备电源后,它将看到该标志已设置,并尝试读取由于初始化不完全而从驱动程序发送的无效数据。这将使设备处于无效状态,在该状态下,已清除掉电标志,但在驱动程序将其重新初始化之前,该设备将不会接收进一步的指令。第二次重置将意味着设备没有尝试读取已存储在设备上的无效数据,并且将接收正确的配置指令,从而使其处于正确的状态(假设发送ioctl的应用程序未隔离) )。

最后,花了大约两周的时间才找出导致问题的确切情况。


2

对于一个大学项目,我们正在编写一个共享文件的分布式P2P节点系统,该系统支持多播以检测彼此,多个节点环和一个名称服务器,以便将节点分配给客户端。

我们使用C ++编写POCO,因为它允许进行漂亮的IO,套接字和线程编程。


有两个错误使我们烦恼并使我们浪费很多时间,这是一个很合逻辑的错误:

随机地,一台计算机正在共享其本地主机IP,而不是远程IP。

这导致客户端连接到同一台PC上的节点或节点相互连接。

我们如何识别呢?当我们改进名称服务器中的输出时,我们在稍后重新启动脚本以确定提供的IP的计算机时发现了错误。随机地,首先列出lo设备,而不是eth0设备...真是愚蠢。所以现在我们硬编码从eth0要求它,因为它在所有大学计算机之间共享...


现在更烦人的是:

随机地,分组流将随机地暂停。
下一个客户端连接时,它将继续...

这种情况实际上是随机发生的,并且涉及到一台以上的计算机,调试该问题变得更加烦人,大学计算机不允许我们在这些计算机上运行Wireshark,因此我们只能猜测问题是在发送端还是在接收端侧。

在代码中有大量输出的情况下,我们只是假设发送命令可以正常进行,
这使我们想知道真正的问题在哪里...似乎POCO轮询的方式是错误的,我们应该检查可用字符在传入的套接字上。

我们假设此方法在涉及较少数据包的原型中以更简单的测试方式工作不会导致此问题,因此这使我们仅假设poll语句正在工作,但是...并非如此。:-(


得到教训:

  • 不要做出像网络设备顺序这样的愚蠢假设。

  • 框架并非总是正确地完成其工作(实现或文档)。

  • 在代码中提供足够的输出,如果不允许,请确保将扩展的详细信息记录到文件中。

  • 当代码尚未经过单元测试时(因为它太难了),不要以为事情会做。


1
在没有wireshark(或类似工具)的情况下解决网络问题在iteslf中是很英勇的。
Evan Plaice 2010年

2

我仍在进行最困难的错误查找。它是有时在那里,有时不是错误的其中之一。这就是为什么我第二天早上6:10在这里。

背景:

  • 上下文:语言,应用程序,环境等
    • PHP OS商业
  • 错误是如何识别的?
    • 随机顺序可以部分解决随机失败和重定向问题
  • 谁或什么识别出该错误?
    • 客户端,重定向问题很明显
  • 复制错误有多复杂?
    • 我没有能够复制,但是客户已经能够复制。

狩猎。

  • 你有什么计划?
    • 添加调试代码,填写订单,分析数据,重复
  • 您遇到了什么困难?
    • 缺乏可重复的问题和可怕的代码
  • 最终如何找到违规代码?
    • 发现了许多有问题的代码..并非完全符合我的需要。

杀人。

  • 解决方法有多复杂?
    • 非常
  • 您如何确定修补程序的范围?
    • 没有范围...无处不在
  • 该修复程序涉及多少代码?
    • 所有的?我不认为有一个完整的文件

验尸。

  • 技术上的根本原因是什么?缓冲区溢出等
    • 不良的编码习惯
  • 30,000英尺的根本原因是什么?
    • 我宁愿不说...
  • 该过程最终需要多长时间?
    • 永远的一天
  • 该修复程序是否有不利影响的功能?
    • 特征?还是一个错误?
  • 您发现哪些方法,工具,动机特别有用?...非常没用?
  • 如果你能再做一遍吗?............
    • Ctrl + A组合键

如果原因是“糟糕的编码实践”,那么您可能想与老板讨论是否是修改团队编码实践的好时机,并可能引入同行评审?

2

我不得不在上个测试版中解决一些令人困惑的并发问题,但是对我来说,最突出的错误是我在PDP-11程序集中编写的基于文本的游戏中进行的作业。它基于Conway的《生活游戏》,出于某些奇怪的原因,网格旁边的大部分信息一直被不应该存在的信息覆盖。逻辑也很简单,因此非常混乱。经过一遍遍重新发现所有逻辑都是正确的之后,我突然注意到了问题所在。这东西:.

在PDP-11中,数字旁边的小点使它以10为底数而不是8。它紧接在以数字为界的循环旁边,该循环本应限于网格,网格的大小由相同的数字定义但以底数为单位8。

它对我仍然很突出,因为这种微小的4像素大小的加法造成的损坏量很大。那么结论是什么?不要在PDP-11汇编中编码。


2

大型机程序无故停止工作

我刚刚将其发布到另一个问题。看到这里发布

发生这种情况是因为他们在主机上安装了较新版本的编译器。

13年6月11日更新:(原始答案已由OP删除)

我继承了此大型机应用程序。有一天,它突然失去作用了。就这样... po声就停了下来。

我的工作是使它尽快运行。源代码已经有两年没有被修改,但是突然间它就停止了。我试图编译代码,但它在XX行上中断了。我看着XX行,但我不知道是什么使XX行中断。我询问了此应用程序的详细规格,但没有。XX行不是罪魁祸首。

我打印出了代码,并开始从上至下进行审查。我开始创建正在发生的事情的流程图。代码太复杂了,我什至无法理解。我放弃尝试绘制流程图。我很害怕做出更改,却不知道该更改将如何影响其余的过程,尤其是因为我没有应用程序功能的详细信息。

因此,我决定从源代码的顶部开始,并添加whitespce和行制动器,以使代码更具可读性。我注意到,在某些情况下,是否存在将AND和OR组合在一起的条件,并且对哪些数据进行“与”操作与对哪些数据进行“或”操作并不清楚。因此,我开始在AND和OR条件周围加上括号,以使其更具可读性。

当我慢慢进行清理时,我会定期保存工作。有一次我尝试编译代码,然后发生了一件奇怪的事情。该错误已跳过原始代码行,而现在进一步降低了。所以我继续,用括号分隔了AND和OR条件。当我完成清理工作时。去搞清楚。

然后,我决定访问操作车间,询问他们最近是否在主机上安装了任何新组件。他们说是的,我们最近升级了编译器。嗯

事实证明,旧的编译器无论如何都从左到右评估表达式。新版本的编译器还从左到右评估表达式,但是代码含糊不清,这意味着无法解决AND和OR的不清楚组合。

我从中吸取的教训...当彼此结合使用时,总是,总是,总是使用括号分隔AND条件和OR条件。


您的链接指向的帖子已被删除-您介意更新答案吗?
蚊蚋

1
@gnat-在archive.org上找到了它:)
Michael Riley-AKA Gunny

1

背景:

  • 上下文:Web服务器(C ++),允许客户自行签入
  • 错误:请求页面时,它将完全不响应,即整个服务器场,并且进程将被杀死(并重新启动),因为它们花费了太长时间(仅允许几秒钟)来服务该页面
  • 一些用户确实抱怨了,但是它是非常零星的,因此几乎没有被注意到(当页面不被提供时,人们往往会点击“刷新”)。我们确实注意到了核心转储;)
  • 实际上,我们从未设法在本地环境中进行复制,该错误在测试系统中出现过几次,但在性能测试期间从未出现过?

狩猎。

  • 计划:好吧,因为我们有内存转储和日志,所以我们想对其进行分析。由于它影响到整个服务器场,并且过去我们遇到了一些数据库问题,因此我们怀疑该数据库(用于多个服务器的单个数据库)
  • 难点:完整的服务器转储是巨大的,因此它们很经常被清除(不会耗尽空间),因此我们必须在发生故障时迅速抓住它。转储显示了各种堆栈(从没有任何DB东西,如此之多),它在准备页面本身时失败(在先前的计算中没有),并确认日志显示的内容,准备页面有时甚至需要很长时间,甚至尽管它只是具有预计算数据的基本模板引擎(传统MVC)
  • 深入了解:经过更多示例和思考,我们意识到花了时间从HDD(页面模板)读取数据。由于涉及到整个农场,因此我们首先查找了预定的工作(crontab,批处理),但是时间从一次出现到另一个都没有匹配……最后,我发现这总是在激活新版本之前几天发生该软件,我有一个AhAh!瞬间...这是由软件的发行引起的!交付数百兆字节(压缩)可能会降低磁盘性能:/当然,分发是自动化的,并且存档一次推送到所有服务器(多播)。

杀人。

  • 修复复杂性:切换到编译的模板
  • 受影响的代码:无,构建过程中的一个简单更改

验尸。

  • 根本原因:运营问题或缺乏前瞻性计划:)
  • 时间尺度:花了几个月的时间进行跟踪,花了几天的时间进行修复和测试,花了几周的时间进行质量检查和性能测试和部署-不用着急,因为我们知道部署此修复程序会触发该错误...而且什么也没有否则...真的有点变态!
  • 不利影响:由于模板已在交付的代码中生成,因此无法在运行时切换模板,但是我们并没有使用太多功能,因为通常切换模板意味着您需要输入更多数据。对于“小的”布局更改而言,大多数情况就足够了。
  • 方法,工具: gdb +监控!只是花了一些时间来怀疑磁盘,然后在监视图上确定活动高峰的原因...
  • 下次:将所有IO视为不利!

1

最艰苦的人从来没有被杀过,因为除了工厂运营的完整生产环境外,再也无法复制它。

我杀了最疯狂的人:

图纸印刷乱码!

我看着代码,什么也看不到。我将作业从打印机队列中拉出并进行了检查,看起来不错。(这是在dos时代,具有嵌入式HPGl / 2的PCL5,实际上非常适合于绘制图形,并且不会在有限的内存中构建光栅图像。)我将其定向到另一台应该了解它的打印机,它可以正常打印。

回滚代码,问题仍然存在。

最后,我手动制作了一个简单的文件,然后将其发送到打印机,看上去很乱。事实证明,这根本不是我的错误,而是打印机本身。维修公司在修复其他内容时已将其更新为最新版本,并且该最新版本存在错误。让他们了解他们已经删除了关键功能,并且不得不将其刷新回早期版本比发现错误本身要难得多。

一个更让人讨厌的东西,但是由于它只放在我的盒子里,所以我不会放在第一位:

Borland Pascal,DPMI代码,用于处理一些不受支持的API。运行它,偶尔它起作用,通常它在尝试处理无效指针时变得很繁荣。但是,它永远不会产生错误的结果,就像您踩到指针所期望的那样。

调试-如果我单步执行代码,它将始终可以正常工作,否则它会像以前一样不稳定。检查始终显示正确的值。

罪魁祸首:有两个。

1)Borland的库代码有一个主要错误:实模式指针以保护模式存储在指针变量中。问题在于大多数实模式指针在保护模式下具有无效的段地址,并且当您尝试复制指针时,它将指针加载到寄存器对中然后保存。

2)在单步模式下,调试器永远不会说任何有关这种无效负载的信息。我不知道它在内部做了什么,但是呈现给用户的看起来完全正确。我怀疑它实际上不是在执行指令,而是在模拟它。


1

这只是一个非常简单的错误,我不知何故变成了噩梦。

背景:我正在制作自己的操作系统。调试非常困难(trace语句是您所能拥有的,有时甚至没有)

错误:与其在用户模式下进行两个线程切换,不如说是一般性保护错误。

错误查找:我可能花了一两个星期来尝试解决此问题。在各处插入跟踪语句。检查生成的汇编代码(来自GCC)。打印出我能得到的每一个值。

问题:在Bug搜寻的早期,我hlt在crt0中放置了一条指令。crt0基本上是引导用户程序以在操作系统中使用的程序。这个hlt从用户模式执行时,指令会导致GPF。我把它放在那儿,基本上忘了它。(最初的问题是缓冲区溢出或内存分配错误)

解决方法:删除hlt指令:) 删除指令后,一切工作顺利。

我学到的东西:尝试调试问题时,请不要忘记尝试的修补程序。与最新的稳定源代码控制版本进行定期对比,看看在其他方法无效的情况下您最近所做的更改

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.