浮点异常
IEEE浮点数标准定义了六种异常,每种错误都对应于特定类型的错误。当异常发生时(在标准语言中,当异常被引发时),可能发生以下两种情况之一。默认情况下,只需在浮点状态字中记录异常,程序将继续运行,就好像什么都没有发生一样。该操作生成一个默认值,该值取决于异常。您的程序可以检查状态字以找出发生了哪些异常。或者,您可以为异常启用陷阱。在这种情况下,当引发异常时,您的程序将收到SIGFPE信号。此信号的默认操作是终止程序。当检测到某些异常时,发出异常信号。通常会引发(设置)这些异常的标志,并传递默认结果,然后继续执行。这种默认行为通常是可取的,尤其是在应用上线运行时,但在开发过程中,当发出异常信号时,暂停会很有用。停止异常就像在程序中的每个浮点操作中添加一个断言,因此,这是提高代码可靠性的一个很好的方法,可以从根本上找到神秘的行为。
让我们重新认识IEEE浮点标准规定的六个例外是:
- 无效操作(EM_INVALID):如果给定的操作数对于要执行的操作无效(有或没有可用的可定义结果),则引发此异常。示例包括(参见IEEE 754第7节):例如零除以零、无穷减无穷、0乘无穷、无穷除无穷、余数:x REM y,其中y为零或x为无穷大、sqrt(-1),当浮点数无法以目标格式表示时(由于溢出、无穷大或NaN)、将浮点数转换为整数或十进制字符串、无法识别的输入字符串的转换则发出此信号。默认结果为NaN(不是数字)
- 被零除(EM_ZERODIVIDE):非零数字被零除时发出信号。结果是无穷大。
- 溢出(EM_OVERFLOW):如果结果不能以目标的精度格式表示为有限值或当四舍五入结果不合适时,会发出此信号。默认结果是无穷大。每当引发溢出异常时,也会引发不精确异常。
- 下溢(EM_UNDERFLOW):如果中间结果太小而无法准确计算,或者如果四舍五入到目标精度的操作结果太小而无法标准化,则会引发下溢异常。又或当结果为非零且介于-FLT_MIN和FLT_MIN之间时发出信号。默认结果为四舍五入结果。
- 不精确(EM_INEXACT):任何时候操作结果不精确时都会发出此信号。默认结果是四舍五入的结果。
- 非规格化(EM_DENORMAL):非规范异常(仅适用于控制87)
开发者通常对下溢异常不感兴趣,因为它很少发生,而且通常不会检测到任何感兴趣的东西。不精确的结果通常也不会引起开发人员的兴趣-它经常发生(虽然不总是,并且理解什么操作是精确的可能很有用),但通常不会检测到任何感兴趣的东西。无效操作、除零和溢出在开发的环境中通常是非常特殊的。它们很少是故意做的,所以它们通常表示一个bug。在许多情况下,这些错误是良性的,但偶尔这些错误表明真正的问题。从现在起,我将把前三个异常称为“坏”异常,并假设开发人员希望避免它们。被零除什么时候有用?虽然“坏”异常通常表示程序上下文中的无效操作,但并非在所有上下文中都是如此。被零除的默认结果(无穷大)可允许继续计算并生成有效结果,无效操作的默认结果(NaN)有时可允许使用快速算法,如果生成NaN结果,则使用较慢且更稳健的算法。零除行为的经典示例是并联电阻的计算。对于电阻为R1和R2的两个电阻器,其计算公式为:
因为被零除得到无穷大的结果,因为无穷大加上另一个数得到无穷大,因为被无穷大除的有限数得到零,所以当R1或R2为零时,此计算出正确的零并联电阻。如果没有这种行为,代码将需要检查R1和R2是否为零,并专门处理这种情况。此外,如果R1或R2非常小–小于FLT_MAX或DBL_MAX的倒数,则此计算结果将为零。此零结果在技术上不正确。如果程序员需要区分这些场景,则需要监控溢出和零除标志。假设我们没有试图利用除零行为,那么抵抗是徒劳的。我们需要一种方便的方法来打开“坏”浮点异常。而且,由于我们必须与其他代码共存(调用物理库、D3D和其他可能不“异常清除”的代码),因此我们还需要一种临时关闭所有浮点异常的方法。实现这一点的适当方法是使用一对类,它们的构造函数和析构函数发挥了必要的魔力。下面是一些用于VC++的类:
// Declare an object of this type in a scope in order to suppress // all floating-point exceptions temporarily. The old exception // state will be reset at the end. class FPExceptionDisabler { public: FPExceptionDisabler() { // Retrieve the current state of the exception flags. This // must be done before changing them. _MCW_EM is a bit // mask representing all available exception masks. _controlfp_s(&mOldValues, _MCW_EM, _MCW_EM); // Set all of the exception flags, which suppresses FP // exceptions on the x87 and SSE units. _controlfp_s(0, _MCW_EM, _MCW_EM); } ~FPExceptionDisabler() { // Clear any pending FP exceptions. This must be done // prior to enabling FP exceptions since otherwise there // may be a 'deferred crash' as soon the exceptions are // enabled. _clearfp(); // Reset (possibly enabling) the exception status. _controlfp_s(0, mOldValues, _MCW_EM); } private: unsigned int mOldValues; // Make the copy constructor and assignment operator private // and unimplemented to prohibit copying. FPExceptionDisabler(const FPExceptionDisabler&); FPExceptionDisabler& operator=(const FPExceptionDisabler&); }; // Declare an object of this type in a scope in order to enable a // specified set of floating-point exceptions temporarily. The old // exception state will be reset at the end. // This class can be nested. class FPExceptionEnabler { public: // Overflow, divide-by-zero, and invalid-operation are the FP // exceptions most frequently associated with bugs. FPExceptionEnabler(unsigned int enableBits = _EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID) { // Retrieve the current state of the exception flags. This // must be done before changing them. _MCW_EM is a bit // mask representing all available exception masks. _controlfp_s(&mOldValues, _MCW_EM, _MCW_EM); // Make sure no non-exception flags have been specified, // to avoid accidental changing of rounding modes, etc. enableBits &= _MCW_EM; // Clear any pending FP exceptions. This must be done // prior to enabling FP exceptions since otherwise there // may be a 'deferred crash' as soon the exceptions are // enabled. _clearfp(); // Zero out the specified bits, leaving other bits alone. _controlfp_s(0, ~enableBits, enableBits); } ~FPExceptionEnabler() { // Reset the exception state. _controlfp_s(0, mOldValues, _MCW_EM); } private: unsigned int mOldValues; // Make the copy constructor and assignment operator private // and unimplemented to prohibit copying. FPExceptionEnabler(const FPExceptionEnabler&); FPExceptionEnabler& operator=(const FPExceptionEnabler&); };
关于0xC06D007E未知软件异常
简介
此错误可能是由软件冲突或系统文件损坏引起的。也有可能应用缺少模块。
说明
为了排除这个异常,可以先确认:最近是否安装了一个新程序吗?Windows的内部版本号和版本是什么?建议您执行干净的引导。通过使用最少的一组驱动程序和启动程序来执行干净引导以启动Windows。这有助于消除在Windows中安装程序或更新或运行程序时发生的软件冲突。
如果是系统文件损坏,建议运行sfc/scannow命令来修复损坏或丢失的系统文件。
关于0xC06D007F未知软件异常
简介
0xC06D007F这个异常通常是在PE的延迟加载dll的时候发生的,加载器找不到对应的dll就会抛出这个异常。
说明
这个异常其实跟0xC06D007E异常差多,排查方法可以跟它一样。但0xC06D007F更偏向模块错误。
异常结构
ExceptionAddress: 7c812aeb (kernel32!RaiseException+0x00000053)
ExceptionCode: c06d007f
ExceptionFlags: 00000000
NumberParameters: 1
Parameter[0]: 0012f918
ExceptionCode: c06d007f
ExceptionFlags: 00000000
NumberParameters: 1
Parameter[0]: 0012f7b0
Python爬虫常用正则re.findall的使用
re.findall正则符说明
1、单字符表达
. : 除换行以外所有字符
[] :[aoe] [a-w] 匹配集合中任意一个字符
\d :数字 [0-9]
\D : 非数字
\w :数字、字母、下划线、中文
\W : 非\w
\s :所有的空白字符包,括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]
\S : 非空白
2、数量修饰
* : 任意多次 >=0
+ : 至少1次 >=1
? : 可有可无 0次或者1次
{m} :固定m次 hello{3,}
{m,} :至少m次
{m,n} :m-n次
3、边界
$ : 以某某结尾
^ : 以某某开头
4、分组
(ab)
5、贪婪模式
.*
6、非贪婪惰性模式
.*?
7、re.findall 可以对多行进行匹配,并依据参数作出不同结果。
re.findall(取值,值,re.M)
- re.M :多行匹配
- re.S :单行匹配 如果分行则显示/n
- re.I : 忽略大小写
- re.sub(正则表达式, 替换内容, 字符串)
二、举例说明
1、提取出python
'''
key = 'javapythonc++php'
re.findall('python',key)
re.findall('python',key)[0] ###[0]代表打印的时候去掉中括号和引号
2、提取出 hello word
'''
key = '<html><h1>hello word</h1></html>'
print(re.findall('<h1>.*</h1>', key))
print(re.findall('<h1>(.*)</h1>', key))
print(re.findall('<h1>(.*)</h1>', key)[0])
'''
3、提取170
'''
key = '这个女孩身高170厘米'
print(re.findall('\d+', key)[0])
'''
4、提取出http://和https://
'''
key = 'http://www.baidu.com and https://www.cnblogs.com'
print(re.findall('https?://', key))
'''
5、提取出 hello
'''
key = 'lalala<hTml>hello</HtMl>hahaha' # 输出的结果<hTml>hello</HtMl>
print(re.findall('<[hH][tT][mM][lL]>(.*)</[hH][tT][mM][lL]>',key))
'''
6、提取hit. 贪婪模式;尽可能多的匹配数据
'''
key = 'qiang@hit.edu.com' # 加?是贪婪匹配,不加?是非贪婪匹配
print(re.findall('h.*?\.', key))
'''
7、匹配出所有的saas和sas
'''
key = 'saas and sas and saaas'
print(re.findall('sa{1,2}s',key))
'''
8、匹配出 i 开头的行
'''
key = """fall in love with you
i love you very much
i love she
i love her
"""
print(re.findall('^i.*', key, re.M))
'''
9、匹配全部行
'''
key = """
<div>细思极恐
你的队友在看书,
你的闺蜜在减肥,
你的敌人在磨刀,
隔壁老王在练腰.
</div>
"""
print(re.findall('.*', key, re.S))
'''
————————————————
版权声明:本文为CSDN博主「三颗草丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/icanflyingg/article/details/124128611
Windbg命令系列---#(汇编搜索)
#命令在反汇编代码里根据指定模式进行搜索。
语法
#[Pattern] [Address [ L Size ]]
参数
Pattern
指定要在反汇编代码中搜索的模式。模式可以包含各种通配符和说明符。如果要在模式中包含空格,则必须用引号将模式括起来。该模式不区分大小写。如果您以前使用过#命令并且省略了模式,则该命令将重用最近使用的模式。
Address
指定搜索开始的地址。
Size
指定要搜索的指令数。如果忽略大小,搜索将继续,直到出现第一个匹配。
环境
Modes |
User mode, kernel mode |
Targets |
Live, crash dump |
Platforms |
All |
备注
如果您以前使用过#命令并且省略了地址,则搜索将从上一次搜索结束的位置开始。此命令通过搜索反汇编文本中的指定模式来工作。可以使用此命令查找寄存器名称、常量或反汇编输出中显示的任何其他字符串。可以在不使用Address参数的情况下重复该命令。
您可以使用u(Unassemble)命令或WinDbg中的“反汇编”窗口查看反汇编说明。反汇编显示最多包含四个部分:地址偏移、二进制代码、汇编语言助记符和汇编语言详细信息。以下示例显示了可能的显示。