Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 这是不是;“不应该发生”;使AMD Fusion CPU错误崩溃?_Assembly_Crash_X86_Windbg_Amd Processor - Fatal编程技术网

Assembly 这是不是;“不应该发生”;使AMD Fusion CPU错误崩溃?

Assembly 这是不是;“不应该发生”;使AMD Fusion CPU错误崩溃?,assembly,crash,x86,windbg,amd-processor,Assembly,Crash,X86,Windbg,Amd Processor,我的公司已经开始有很多客户打电话进来,因为我们的程序因为他们系统上的访问违规而崩溃 崩溃发生在SQLite 3.6.23.1中,我们将其作为应用程序的一部分发布。(为了使用与应用程序其余部分相同的VC++库,我们提供了一个自定义构建,但它是SQLite代码。) 当pcache1Fetch执行call 00000000时发生崩溃,如WinDbg callstack所示: 0b50e5c4 719f9fad 06fe35f0 00000000 000079ad 0x0 0b50e5d8 719f92

我的公司已经开始有很多客户打电话进来,因为我们的程序因为他们系统上的访问违规而崩溃

崩溃发生在SQLite 3.6.23.1中,我们将其作为应用程序的一部分发布。(为了使用与应用程序其余部分相同的VC++库,我们提供了一个自定义构建,但它是SQLite代码。)

pcache1Fetch
执行
call 00000000
时发生崩溃,如WinDbg callstack所示:

0b50e5c4 719f9fad 06fe35f0 00000000 000079ad 0x0
0b50e5d8 719f9216 058d1628 000079ad 00000001 SQLite_Interop!pcache1Fetch+0x2d [sqlite3.c @ 31530]
0b50e5f4 719fd581 000079ad 00000001 0b50e63c SQLite_Interop!sqlite3PcacheFetch+0x76 [sqlite3.c @ 30651]
0b50e61c 719fff0c 000079ad 0b50e63c 00000000 SQLite_Interop!sqlite3PagerAcquire+0x51 [sqlite3.c @ 36026]
0b50e644 71a029ba 0b50e65c 00000001 00000e00 SQLite_Interop!getAndInitPage+0x1c [sqlite3.c @ 40158]
0b50e65c 71a030f8 000079ad 0aecd680 071ce030 SQLite_Interop!moveToChild+0x2a [sqlite3.c @ 42555]
0b50e690 71a0c637 0aecd6f0 00000000 0001edbe SQLite_Interop!sqlite3BtreeMovetoUnpacked+0x378 [sqlite3.c @ 43016]
0b50e6b8 71a109ed 06fd53e0 00000000 071ce030 SQLite_Interop!sqlite3VdbeCursorMoveto+0x27 [sqlite3.c @ 50624]
0b50e824 71a0db76 071ce030 0b50e880 071ce030 SQLite_Interop!sqlite3VdbeExec+0x14fd [sqlite3.c @ 55409]
0b50e850 71a0dcb5 0b50e880 21f9b4c0 00402540 SQLite_Interop!sqlite3Step+0x116 [sqlite3.c @ 51744]
0b50e870 00629a30 071ce030 76897ff4 70f24970 SQLite_Interop!sqlite3_step+0x75 [sqlite3.c @ 51806]
C代码的相关行为:

if( createFlag==1 ) sqlite3BeginBenignMalloc();
编译器内联
sqlite3BeginBenignMalloc
,定义为:

typedef struct BenignMallocHooks BenignMallocHooks;
static SQLITE_WSD struct BenignMallocHooks {
  void (*xBenignBegin)(void);
  void (*xBenignEnd)(void);
} sqlite3Hooks = { 0, 0 };

# define wsdHooksInit
# define wsdHooks sqlite3Hooks

SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void){
  wsdHooksInit;
  if( wsdHooks.xBenignBegin ){
    wsdHooks.xBenignBegin();
  }
}
这方面的大会是:

719f9f99    mov     esi,dword ptr [esp+1Ch]
719f9f9d    cmp     esi,1
719f9fa0    jne     SQLite_Interop!pcache1Fetch+0x2d (719f9fad)
719f9fa2    mov     eax,dword ptr [SQLite_Interop!sqlite3Hooks (71a7813c)]
719f9fa7    test    eax,eax
719f9fa9    je      SQLite_Interop!pcache1Fetch+0x2d (719f9fad)
719f9fab    call    eax ; *** CRASH HERE ***
719f9fad    mov     ebx,dword ptr [esp+14h]
登记册包括:

eax=00000000 ebx=00000001 ecx=000013f0 edx=fffffffe esi=00000001 edi=00000000
eip=00000000 esp=0b50e5c8 ebp=000079ad iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
如果
eax
为0(即0),则应通过
test eax,eax
设置零标志,但它不是零。由于未设置零标志,
je
不会跳转,然后应用程序在尝试执行
调用eax(00000000)
时崩溃

更新:
eax
此处应始终为0,因为在我们的代码构建中未设置
sqlite3Hooks.xBenignBegin
。我可以使用定义的
SQLite\u ommit\u BUILTIN\u TEST
重建SQLite,这将在代码中启用
\define sqlite3BeginBenignMalloc()
,并完全忽略此代码路径。这可能会解决问题,但感觉不像是“真正的”修复;什么能阻止它在其他代码路径中发生

到目前为止,共同的因素是所有客户都在运行“Windows 7 Home Premium 64位(6.1,Build 7601)Service Pack 1”,并具有以下CPU之一(根据DxDiag):

  • AMD A6-3400M APU,带Radeon(tm)高清图形(4个CPU),~1.4GHz
  • AMD A8-3500M APU,带Radeon(tm)高清图形(4个CPU),~1.5GHz
  • AMD A8-3850 APU,带Radeon(tm)高清图形(4个CPU),~2.9GHz
据维基百科称,这些都是基于K10内核的“Llano”型AMD融合芯片,于2011年6月发布,也就是我们第一次收到报告的时候

最常见的客户系统是东芝卫星L775D,但我们也有来自HP Pavilion dv6和dv7以及网关系统的故障报告

这个崩溃是由CPU错误引起的(请参阅),还是我忽略了其他一些可能的解释?(根据雷蒙德的说法,这是可能的,但奇怪的是,只有这种特定的CPU型号受到影响,如果是这样的话。)

老实说,这似乎不可能是真正的CPU或操作系统错误,因为客户不会在其他应用程序中遇到蓝屏或崩溃。肯定还有其他更可能的解释——但是什么呢

8月15日更新:我购买了一台东芝L745D笔记本电脑,带有AMD A6-3400M处理器,在运行该程序时可以始终如一地再现崩溃。碰撞始终在同一指令上
.time
报告崩溃前1米30到7米的用户时间。我在最初的帖子中忽略了一个事实(可能与这个问题有关),那就是这个应用程序是多线程的,CPU和I/O的使用率都很高。默认情况下,应用程序生成四个工作线程,并发布80%以上的CPU使用率(SQLite代码中存在一些I/O和互斥锁阻塞),直到崩溃。我将应用程序修改为只使用两个线程,但它仍然崩溃(尽管需要更长的时间)。我现在正在运行一个只有一个线程的测试,它还没有崩溃

还要注意的是,这似乎不是一个纯粹的CPU负载问题;我可以在系统上无错误地运行Prime95,它会将CPU温度提高到>70℃,而我的应用程序在运行时温度几乎不会超过50℃

8月16日更新:稍微干扰说明会使问题“消失”。对于eax示例,将内存加载(
mov-eax,dword-ptr[SQLite\u Interop!sqlite3Hooks(71a7813c)]
替换为
xor-eax,eax
)可以防止崩溃。修改原始C代码以向
if(createFlag==1)
语句添加额外的检查,从而更改编译代码中各种跳转的相对偏移量(以及
testeax、eax
call eax
语句的位置),并且似乎可以防止出现问题

到目前为止,我发现的最奇怪的结果是将
719f9fa0
处的
jne
更改为两条
nop
指令(这样,无论
createFlag
/
esi
的值是多少,控制总是落在
测试eax,eax
指令上)允许程序在不崩溃的情况下运行。

我有点担心为
if(wsdHooks.xBenignBegin)
生成的代码不是很通用。它假设唯一的真值是
1
,而实际上它应该测试任何非零值。尽管如此,MSVC有时还是让人困惑。可能没什么。没关系:这些说明适用于
C
未显示的代码

假设eflag
Z
位是清晰的,而
EAX
位是零,则代码没有通过执行指令到达这里

719f9fa7    test    eax,eax
必须从其他地方跳转到以下指令(
719f9fa9 je SQLite_Interop!pcache1Fetch+0x2d
),甚至是
调用
指令本身

另一个复杂问题是,对于x86系列,无效的跳转目标(如
JE
指令的第二个字节)通常会对相当多的指令执行不受干扰(无故障)的操作,通常最终会恢复到正确的指令对齐方式。换句话说,您可能不希望跳转到这些指令的开头:跳转可能在它们的字节中间,导致执行不显著的操作,如
add[al+ebp],al
,这些操作往往不会被注意到

我预测异常不会命中
测试
指令处的断点。找到这些原因的唯一方法是