程序调试

读《软件调试》第九章

ぐ巨炮叔叔 提交于 2020-03-02 18:14:52
今日读了张银奎老师的《软件调试》,前面的CPU和硬件相关的部分离得比較远,所以从第九章操作系统读起,今天的读书笔记: 9.2採集调试消息 调试事件分为8种 typedef enum _DBGKM_APINUMBER { DbgkmExceptionApi = 0, // 异常 DbgkmCreateThreadApi = 1, // 创建线程 DbgkmCreateProcessApi = 2, // 创建进程 DbgkmExitThreadApi = 3, // 退出线程 DbgkmExitProcessApi = 4, // 进程退出 DbgkmLoadDllApi = 5, // 映射DLL DbgkmUnloadDllApi = 6, // 反映射DLL DbgkmErrorReportApi = 7, // 内部错误 DbgkmMaxApiNumber = 8, // 这组常量的最大值 } DBGKM_APINUMBER; 9.2.2 进程和线程创建消息 操作系统就支持向调试系统发送消息,这个我是没有想到的,详细步骤例如以下: 创建用户态windows线程时,首先为线程建立必要的内核对象和数据结构,并分配栈(stack)空间,这些工作完毕后, 该线程处于挂起状态(CREATE_SUSPEND), 而后进程管理器会通知环境子系统,环境子系统会作必要的设置和登记,最后

Windbg使用简明指南

妖精的绣舞 提交于 2020-03-02 14:28:35
第一章 准备 1.1. 环境配置 _NT_DEBUGGER_EXTENSION_PATH=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 _NT_SYMBOL_PATH=SRV*c:\Symbols*http://msdl.microsoft.com/download/symbols Path add: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 C:\Program Files\Debugging Tools for Windows (x86) 1.2 .Net CLR知识 第二章 常用命令 2.1 基本命令 序号 命令 解释 .chain 显示有哪些调试扩展。 .load DLLName !DLLName.load 加载调试扩展。DLLName要是全路径名,包括”.dll” .loadby DLLName ModuleName 加载调试扩展。DLLName是短文件名,不包括”.dll”。 ModuleName是调试进程中的模块名,表示通过它所在的路径查找DLLName。 .unload DLLName !DLLName.unload 卸载调试扩展。 .setdll DLLName !DLLName.setdll 设置缺省的调试扩展。 ![ext.]address 显示VM的分配状况 !

Xcode 调试技巧 --常用命令和断点

烂漫一生 提交于 2020-03-02 12:42:28
Xcode 中的调试技巧与我们的日常开发息息相关,而这些调试技巧在我们解决Bug时,常常有事半功倍的作用,经常会用到的有各种断点 和 命令。而这些调试技巧也经常会在面试中问到,所以不知道的就来看看吧。 调试命令 在上图中,右侧绿色区域就是Log 输出区,在 Log 输出区可以使用一些命令,来辅助调试。 那有哪些调试命令呢? 想要看所有的调试命令,可以在上图的右侧区域输入 help ,就会列出所有的调试命令。 本文就介绍几个使用频率比较高的,其他就查看后,自行了解吧。 1. p 命令 -- ('expression --') Evaluate an expression on the current thread. Displays any returned value with LLDB's default formatting. p 命令是 print 命令的简写,使用p 命令可以查看基本数据类型的值,但是如果 使用 p 命令 查看的是对象,那么只会返回对象的指针地址。 p 命令后面除了可以接 变量、常量,还可以接 表达式。(❌但是不可以使用宏❌) 2. po 命令 po 命令可以理解为打印对象。功能与 p 命令类似,所以也是可以打印 常量、变量,打印表达式返回的对象等。(❌也不可以打印宏❌) 当然,这些打印功能,除了使用命令外,我们也可以使用左侧区域,点击变量右键—>

Xcode 调试技巧 --常用命令和断点

*爱你&永不变心* 提交于 2020-03-02 12:41:42
Xcode 中的调试技巧与我们的日常开发息息相关,而这些调试技巧在我们解决Bug时,常常有事半功倍的作用,经常会用到的有各种断点 和 命令。而这些调试技巧也经常会在面试中问到,所以不知道的就来看看吧。 调试命令 在上图中,右侧绿色区域就是Log 输出区,在 Log 输出区可以使用一些命令,来辅助调试。 那有哪些调试命令呢? 想要看所有的调试命令,可以在上图的右侧区域输入help,就会列出所有的调试命令。 本文就介绍几个使用频率比较高的,其他就查看后,自行了解吧。 1. p 命令 -- ('expression --') Evaluate an expression on the current thread. Displays any returned value with LLDB's default formatting. 1 2 p 命令是 print 命令的简写,使用p 命令可以查看基本数据类型的值,但是如果 使用 p 命令 查看的是对象,那么只会返回对象的指针地址。 p 命令后面除了可以接 变量、常量,还可以接 表达式。(❌但是不可以使用宏❌) 2. po 命令 po 命令可以理解为打印对象。功能与 p 命令类似,所以也是可以打印 常量、变量,打印表达式返回的对象等。(❌也不可以打印宏❌) 当然,这些打印功能,除了使用命令外,我们也可以使用左侧区域,点击变量右键—>

Xcode 调试技巧

我怕爱的太早我们不能终老 提交于 2020-03-02 12:39:33
   【前言】:本篇为同事崔桂祥分享资料。   随着Xcode 5的发布,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器。它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能。LLDB为Xcode提供了底层调试环境,其中包括内嵌在Xcode IDE中的位于调试区域的控制面板,在这里我们可以直接调用LLDB命令,示例如下: 1.必备篇 1.1 打印变量: print/po print :打印变量的值可以使用 print命令,该命令如果打印的是简单类型,则会列出简单类型的类型和值。如果是对象,还会打印出对象指针地址; print object :如果我们只想查看对象的值的信息,则可以使用 po (print object的缩写 )命令。 1.2 查看线程状态: thread list   在进程停止后,LLDB会选择一个当前线程和线程中当前帧(frame)。很多检测状态的命令可以用于这个线程或帧。   为了检测进程的当前状态,使用该命令,其中星号(*)表示thread #1为当前线程。 1.3 获取线程的跟踪栈: thread backtrace (简写bt)   使用命令 thread backtrace (简写bt)可以查看线程的跟踪栈,若要查看所有线程的调用栈则可以使用命令: thread backtrace all (简写bt all) 。

Xcode 调试技巧

强颜欢笑 提交于 2020-03-02 12:38:17
随着Xcode 5的发布,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器。它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能。LLDB为Xcode提供了底层调试环境,其中包括内嵌在Xcode IDE中的位于调试区域的控制面板,在这里我们可以直接调用LLDB命令 目录 一、 必备篇 • 打印变量 • 查看线程状态 • 获取线程的跟踪栈 • 列出帧参数和本地变量 • 寻址 • 帮助系统 二、 技巧篇 • 运行时修改变量的值 • 异常排查 • 符号断点 • Watchpoints 一、必备篇 1.1 打印变量 print :打印变量的值可以使用 print命令,该命令如果打印的是简单类型,则会列出简单类型的类型和值。如果是对象,还会打印出对象指针地址 print object :如果我们只想查看对象的值的信息,则可以使用 po(print object的缩写 )命令 1.2 查看线程状态 thread list 在进程停止后, LLDB会选择一个当前线程和线程中当前帧 (frame)。很多检测状态的命令可以用于这个线程或帧。 为了检测进程的当前状态,使用该命令,星号 (*)表示 thread #1为当前线程 1.3 获取线程的跟踪栈 使用命令 thread backtrace (简写bt),若要查看所有线程的调用栈则可以使用命令: thread

XCode调试器LLDB

老子叫甜甜 提交于 2020-03-02 12:30:19
与调试器共舞 - LLDB 的华尔兹 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThisThing); 或者跳过一个函数调用来简化程序的行为? NSNumber *n = @7; // 实际应该调用这个函数:Foo(); 或者短路一个逻辑检查? if (1 || theBooleanAtStake) { ... } 或者伪造一个函数实现? int calculateTheTrickyValue { return 9; /* 先这么着 ... */ } 并且每次必须重新编译,从头开始? 构建软件是复杂的,并且 Bug 总会出现。一个常见的修复周期就是修改代码,编译,重新运行,并且祈祷出现最好的结果。 但是不一定要这么做。你可以使用调试器。而且即使你已经知道如何使用调试器检查变量,它可以做的还有很多。 这篇文章将试图挑战你对调试的认知,并详细地解释一些你可能还不了解的基本原理,然后展示一系列有趣的例子。现在就让我们开始与调试器共舞一曲华尔兹,看看最后能达到怎样的高度。 LLDB LLDB 是一个有着 REPL 的特性和 C++ ,Python 插件的 开源 调试器。LLDB 绑定在 Xcode 内部,存在于主窗口底部的控制台中。调试器允许你在程序运行的特定时暂停它,你可以查看变量的值,执行自定的指令

iOS调试 LLDB

瘦欲@ 提交于 2020-03-02 12:29:23
LLDB是个开源的内置于XCode的具有REPL(read-eval-print-loop)特征的Debugger,其可以安装C++或者Python插件。 常用调试命令: 1、print命令 print命令的简化方式有prin pri p,唯独pr不能用来作为检查,因为会和process混淆,幸运的是p被lldb实现为特指print。 实际上你会发现,lldb对于命令的简称,是头部匹配方式,只要不混淆,你可以随意简称某个命令。 例如: (lldb) p i (int) $3 = 0 返回的$3是命令结果的引用名,使用$3可以进行print $3 + 7这样打印出7,当然,$3可以被用于任何其他表达式或者接收参数的命令。 2、expression命令 expression命令可以用来修改变量的值,当然大部分情况下,使用xcode提供的可视化编辑器更方便。 (lldb) e i = 100 (int) $4 = 100 实际上print相当于expression --,而--的意思是命令的参数终止,跟在--后面的都是命令的输入数据 要打印一个对象,则需要使用e -O -- anObj,而e -O -- 的缩写正是我们常用的po命令: 3、流程控制命令 继续:process continue, continue, c 下一步:thread step-over, next, n 进入

别再用print来调试啦:logging模块超简明指南

隐身守侯 提交于 2020-03-02 11:42:21
替换print?print怎么了? print 可能是所有学习Python语言的人第一个接触的东西。它最主要的功能就是往控制台 打印一段信息,像这样: print 'Hello, logging!' print也是绝大多数人用来调试自己的程序用的最多的东西,就像写js使用 console.log 一样那么自然。很多刚刚开始学习Python的新手甚至有一定经验的老手,都在使用print 来调试他们的代码。 比如这是一个我写的输出 斐波那契数列 的小程序,让我们来看看它的代码: # -*- coding: utf-8 -*-""" A simple fibonacci program """import argparse parser = argparse.ArgumentParser(description='I print fibonacci sequence') parser.add_argument('-s', '--start', type=int, dest='start', help='Start of the sequence', required=True) parser.add_argument('-e', '--end', type=int, dest='end', help='End of the sequence', required=True)def

OD调试学习笔记7—去除未注册版软件的使用次数限制

风格不统一 提交于 2020-03-02 00:37:25
OD调试学习笔记7—去除未注册版软件的使用次数限制 本节使用的软件链接 (想自己试验下的可以下载) 一:破解的思路   仔细观察一个程序,我们会发现,无论在怎么加密,无论加密哪里,这个程序加密的目的就是需要你掏腰包来获得更多的功能或者解除限制。那么我们就可以逆向的来思考,如果该程序成功的注册后,那么程序的行为必将发生变化,如NAG去除了,如功能限制没有了等等。也就是说,程序的代码的走法也会跟未注册的时候截然不同。因为程序的行为改变了,那么决定它所有行为的代码走法也会发生变化。 二:认识OD的两种断点 OllyDBG从原理上来区分,有两种不同的断点:软件断点和硬件断点。 也许会有朋友说那不是还有内存断点吗? 内存断点严格来说是属于一种特殊的软件断点。 内存断点: – 内存断点每次只能设置一个,假如你设置了另一个内存断点,则上一个会被自动删除。 – 设置一个内存断点,会改变整块(4KB)内存的属性,哪怕你只设置一个字节的内存断点。 – 另外还需要提一下的是,内存断点会明显降低OD的性能,因为OD经常会校对内存。 软件断点: – 当我们按下F2设置的断点就是软件断点。 – 设置该断点的原理是在断点处重写代码,插入一个int3中断指令,当CPU执行到int3指令的时候,OD就可以获得控制权。 硬件断点: – 这个原理跟软件断点不同,硬件断点的可行性依赖于CPU的物理支持。 – 传说中