gpt4 book ai didi

assembly - 这个 "should not happen"崩溃是 AMD Fusion CPU 的错误吗?

转载 作者:行者123 更新时间:2023-12-02 13:11:57 26 4
gpt4 key购买 nike

我的公司已经开始有许多客户来电,因为我们的程序因他们系统上的访问冲突而崩溃。

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

崩溃发生在 pcache1Fetch 时执行 call 00000000 ,如 WinDbg 调用堆栈所示:

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(它是),零标志应该由 test eax, eax 设置,但它不为零。因为没有设置零标志, je不跳转,然后应用程序在尝试执行时崩溃 call eax (00000000) .

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

到目前为止,共同的因素是所有客户都运行“Windows 7 Home Premium 64-bit (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

  • 根据维基百科的 AMD Fusion article ,这些都是基于 K10 内核的“Llano”型号 AMD Fusion 芯片,并于 2011 年 6 月发布,也就是我们第一次开始收到报告的时候。

    最常见的客户系统是 Toshiba Satellite L775D,但我们也有来自 HP Pavilion dv6 和 dv7 以及网关系统的崩溃报告。

    这种崩溃可能是由 CPU 错误引起的(请参阅 Errata for AMD Family 12h Processors ),还是我忽略了其他一些可能的解释? (根据 Raymond 的说法,它是 could be overclocking ,但奇怪的是,只有这个特定的 CPU 型号受到影响,如果是的话。)

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

    8 月 15 日更新:我购买了带有 AMD A6-3400M 处理器的 Toshiba L745D 笔记本电脑,并且在运行程序时可以始终如一地重现崩溃。崩溃总是在同一条指令上; .time报告崩溃前 1 分 30 秒到 7 米的用户时间。我在原帖中忽略提到的一个事实(可能与问题有关)是应用程序是多线程的,并且 CPU 和 I/O 使用率都很高。该应用程序默认生成四个工作线程并发布 80+% 的 CPU 使用率(有一些 I/O 以及 SQLite 代码中的互斥锁),直到它崩溃。我将应用程序修改为仅使用两个线程,但它仍然崩溃(尽管发生的时间更长)。我现在只用一个线程运行一个测试,它还没有崩溃。

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

    8 月 16 日更新:稍微扰乱说明会使问题“消失”。例如,将内存负载( mov eax,dword ptr [SQLite_Interop!sqlite3Hooks (71a7813c)] )替换为 xor eax, eax防止崩溃。修改原始 C 代码以对 if( createFlag==1 ) 添加额外检查语句改变了编译代码中各种跳转的相对偏移量(以及 test eax, eaxcall eax 语句的位置)并且似乎也防止了这个问题。

    到目前为止我发现的最奇怪的结果是更改 jne719f9fa0对二 nop指令(以便控制总是落在 test eax, eax 指令,无论 createFlag/ esi 的值是什么)允许程序运行而不会崩溃。

    最佳答案

    我在 Microsoft Build session 上与 AMD 工程师讨论了这个错误,并向他展示了我的重现。他今天早上给我发了电子邮件:

    We have investigated and found that this is due to a known errata in the Llano APU family. It can be fixed via a BIOS update depending on the OEM – if possible please recommend it to your customers (even though you have a workaround).

    In case you’re interested, the errata is 665 in the Family 12h Revision Guide (see page 45): http://support.amd.com/TechDocs/44739_12h_Rev_Gd.pdf#page=45



    这是该错误的描述:

    665 整数除法指令可能导致不可预测的行为

    说明

    在一组高度具体和详细的​​内部时序条件下,处理器内核可能会中止推测性 DIV 或 IDIV 整数除法指令(由于推测性执行被重定向,例如由于错误预测的分支),但可能会挂起或过早完成第一个非推测路径的指令。

    对系统的潜在影响

    不可预测的系统行为,通常会导致系统挂起。

    建议的解决方法

    BIOS 应设置 MSRC001_1029[31]。

    此变通方法更改了 AMD 系列 10h 和 12h 处理器软件优化指南中指定的 DIV/IDIV 指令延迟,订单号 40546。应用此变通方法后,AMD 系列 12h 处理器的 DIV/IDIV 延迟类似于 DIV/IDIV 延迟适用于 AMD 系列 10h 处理器。

    修复计划

    关于assembly - 这个 "should not happen"崩溃是 AMD Fusion CPU 的错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7004728/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com