Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.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
Linux 禁用valgrind&;的glibc(LD_HWCAP_MASK,/etc/LD.so.nohwcap)中的AVX优化功能;gdb记录_Linux_Linker_Gdb_Glibc_Avx - Fatal编程技术网

Linux 禁用valgrind&;的glibc(LD_HWCAP_MASK,/etc/LD.so.nohwcap)中的AVX优化功能;gdb记录

Linux 禁用valgrind&;的glibc(LD_HWCAP_MASK,/etc/LD.so.nohwcap)中的AVX优化功能;gdb记录,linux,linker,gdb,glibc,avx,Linux,Linker,Gdb,Glibc,Avx,带有glibc的现代x86_64 linux将检测到CPU支持AVX扩展,并将许多字符串函数从通用实现切换到版本(在ifunc dispatchers的帮助下:,) 此功能可以提高性能,但它会阻止valgrind(,before)和gdb的“目标记录””()等工具正常工作(Ubuntu“Z”17.04 beta,gdb 7.12.50.20170207-0ubuntu2,gcc 6.3.0-8ubuntu1 20170221,Ubuntu GLIBC 2.24-7ubuntu2): $cat空调

带有glibc的现代x86_64 linux将检测到CPU支持AVX扩展,并将许多字符串函数从通用实现切换到版本(在ifunc dispatchers的帮助下:,)

此功能可以提高性能,但它会阻止valgrind(,before)和gdb的“
目标记录”
”()等工具正常工作(Ubuntu“Z”17.04 beta,gdb 7.12.50.20170207-0ubuntu2,gcc 6.3.0-8ubuntu1 20170221,Ubuntu GLIBC 2.24-7ubuntu2):

$cat空调
#包括
#定义N 1000
int main(){
字符src[N],dst[N];
memcpy(dst、src、N);
返回0;
}
$gcc a.c-o a-fno内置
$gdb-q./a
正在从./a..读取符号(未找到调试符号)…已完成。
(gdb)启动
0x724处的临时断点1
启动程序:/home/user/src/a
主()
(gdb)记录
(gdb)c
持续的。
过程记录不支持地址0x7ffff7b60d31处的指令0xc5。
进程记录:无法记录执行日志。
程序停止。
__memmove_avx_unaligned_erms()位于../sysdeps/x86_64/multiarch/memmove vec unaligned erms.S:416
416 VMOVU(%rsi),%VEC(4)
(gdb)x/i$pc
=>0x7ffff7b60d31:vmovdqu(%rsi),%ymm4
gdb实现“目标记录”时出现错误消息“
过程记录不支持指令0xc5
”,因为记录/重放引擎不支持AVX指令(有时在
\u dl\u runtime\u resolve\u AVX
函数上检测到问题):“进程记录不支持某些AVX指令”

“您可以在运行时重新编译libc(因此ld.so),或hack uu init u cpu u特性和因此uu cpu u特性(参见例如strcmp)”,或设置
ld BIND u NOW=1
,但重新编译的glibc仍然有AVX,而ld BIND NOW没有帮助

我听说glibc中有
/etc/ld.so.nohwcap
ld\u HWCAP\u MASK
配置。它们可以用于禁用ifunc分派到glibc中的AVX优化字符串函数吗

glibc(rtld?)如何使用
cpuid
/proc/cpuinfo
(可能不是)或HWCAP(
LD\u SHOW\u AUXV=1/bin/echo | grep HWCAP
命令给出的
AT\u HWCAP:bfebfbff
)来检测AVX

我听说glibc中有
/etc/ld.so.nohwcap
ld\u HWCAP\u MASK
配置。它们可以用于禁用ifunc分派到glibc中的AVX优化字符串函数吗

是:设置
LD\u HWCAP\u MASK=0将使GLIBC假装没有可用的CPU功能


将掩码设置为0可能会触发错误,您可能需要找出控制AVX的精确位,并仅屏蔽该位。

不是最佳或完整的解决方案,只是一个最小的位编辑kludge以允许valgrind和gdb记录“我的任务”

:

如何在不重新编译glibc的情况下屏蔽AVX/SSE

我完全重建了未修改的glibc,这在debian和ubuntu中相当容易:只需
sudo-apt-get-source-glibc
sudo-apt-get-build-dep-glibc
cd-glibc-*/;dpkg-buildpackage-us-uc
(以获取ld.so,而无需剥离调试信息)

然后,我对输出ld.so文件进行了二进制(位)修补,该文件位于
\uuu get\u cpu\u features
使用的函数中。目标函数是以
get\u common\u index.constprop.1
的名称编译而成的(它位于二进制代码中
\uu get\u cpu\u features
之后)。它有几个CPUID,第一个是;然后检查“jle 0x6”并跳转代码以获取AVX2状态。有一个代码被编译成此逻辑:

get_common_indeces (struct cpu_features *cpu_features,
            unsigned int *family, unsigned int *model,
            unsigned int *extended_model, unsigned int *stepping)
{ ...
  if (cpu_features->max_cpuid >= 7)
    __cpuid_count (7, 0,
           cpu_features->cpuid[COMMON_CPUID_INDEX_7].eax,
           cpu_features->cpuid[COMMON_CPUID_INDEX_7].ebx,
           cpu_features->cpuid[COMMON_CPUID_INDEX_7].ecx,
           cpu_features->cpuid[COMMON_CPUID_INDEX_7].edx);
cpu\u功能->max\u cpuid
是在
cpu\u cpuid(0,cpu\u功能->max\u cpuid,ebx,ecx,edx);
行中填写的。通过将
cmp0x6
之后的
jle
替换为
jg
(字节0x7e到0x7f),禁用
if
语句更容易。(实际上,这个二进制补丁是手动重新应用于real system
ld linux.so.2的
功能的
\uGet\uCPU\功能的。所以.2
-在
mov 7 eax;xor ecx,ecx;cpuid
之前的第一个jle更改为jg。)

系统中未安装重新编译的包和修改的ld.so;我使用了
ld.so./my_程序
(或
mv ld.so/some/short/path.so
patchelf--set解释器./my_程序
)的命令行语法

其他可能的解决办法:

  • 尝试使用更新的valgrind和gdb记录工具
  • 尝试使用旧的glibc
  • 在gdb记录中实现缺失指令模拟(如果未完成)
  • 在glibc中对if(cpu\u功能->max\u cpuid>=7)
进行源代码修补并重新编译
  • 在glibc中对启用avx2的字符串函数进行源代码修补并重新编译

  • 似乎没有一种简单的运行时方法来修补功能检测。这种检测在动态链接器(ld.so)的早期就发生了

    对链接器进行二进制修补似乎是目前最简单的方法。@osgx覆盖跳转的一种方法。另一种方法只是伪造cpuid结果。通常
    cpuid(eax=0)
    返回
    eax
    中支持的最高函数,而制造商ID位于寄存器ebx、ecx和edx中。我们在glibc 2.25
    sysdeps/x86/cpu features.c
    中有此代码段:

    \uuuCPUID(0,cpu功能->最大cpuid,ebx,ecx,edx);
    /*这意味着“真正的英特尔”*/
    如果(ebx==0x756e6547&&ecx==0x6c65746e&&edx==0x49656e69)
    {
    /*各种Intel CPU的功能检测*/
    }
    /*AMD的另一个案例*/
    其他的
    {
    种类=拱门、种类或其他;
    获取公共索引(cpu特性,NULL,NULL,NULL,NULL);
    }
    
    \uuu cpuid
    get_common_indeces (struct cpu_features *cpu_features,
                unsigned int *family, unsigned int *model,
                unsigned int *extended_model, unsigned int *stepping)
    { ...
      if (cpu_features->max_cpuid >= 7)
        __cpuid_count (7, 0,
               cpu_features->cpuid[COMMON_CPUID_INDEX_7].eax,
               cpu_features->cpuid[COMMON_CPUID_INDEX_7].ebx,
               cpu_features->cpuid[COMMON_CPUID_INDEX_7].ecx,
               cpu_features->cpuid[COMMON_CPUID_INDEX_7].edx);
    
    172a8:       31 c0                   xor    eax,eax
    172aa:       c7 44 24 38 00 00 00    mov    DWORD PTR [rsp+0x38],0x0
    172b1:       00 
    172b2:       c7 44 24 3c 00 00 00    mov    DWORD PTR [rsp+0x3c],0x0
    172b9:       00 
    172ba:       0f a2                   cpuid  
    
    $ gdb -q -ex "set exec-wrapper ./ld-linux-x86-64-patched.so.2" -ex start ./a
    Reading symbols from ./a...done.
    Temporary breakpoint 1 at 0x400502: file a.c, line 5.
    Starting program: /tmp/a 
    During startup program exited normally.
    (gdb) quit
    $ gdb -q -ex start --args ./ld-linux-x86-64-patched.so.2 ./a
    Reading symbols from ./ld-linux-x86-64-patched.so.2...(no debugging symbols found)...done.
    Function "main" not defined.
    Temporary breakpoint 1 (main) pending.
    Starting program: /tmp/ld-linux-x86-64-patched.so.2 ./a
    [Inferior 1 (process 27418) exited normally]
    (gdb) quit                                                                                                                                                                         
    
    (gdb) info shared
    From                To                  Syms Read   Shared Object Library
    0x00007ffff7fd3090  0x00007ffff7ff3130  Yes         /lib64/ld-linux-x86-64.so.2
    0x00007ffff76366b0  0x00007ffff766b52e  Yes         /usr/lib/x86_64-linux-gnu/libubsan.so.1
    0x00007ffff746a320  0x00007ffff75d9cab  Yes         /lib/x86_64-linux-gnu/libc.so.6
    ...
    
    (gdb) disassemble 0x7ffff75c65d4
    Dump of assembler code for function __strcmp_avx2:
       0x00007ffff75c65d0 <+0>:     mov    %edi,%eax
       0x00007ffff75c65d2 <+2>:     xor    %edx,%edx
    => 0x00007ffff75c65d4 <+4>:     vpxor  %ymm7,%ymm7,%ymm7
    
      IFUNC_IMPL (i, name, strcmp,
              IFUNC_IMPL_ADD (array, i, strcmp,
                      HAS_ARCH_FEATURE (AVX2_Usable),
                      __strcmp_avx2)
              IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSE4_2),
                      __strcmp_sse42)
              IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSSE3),
                      __strcmp_ssse3)
              IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_sse2_unaligned)
              IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_sse2))