简单类型转换上的 Genie 段错误

Genie Segfaults on easy typecast

我安装了 Valac 0.30。 运行下面的代码,

[indent=4]
init
    str : string
    str = "Hello World";
    data : array of uint8
    data = (array of uint8) str;
    print "%i\n", data.length;

我遇到段错误。 GDB 告诉我这个:

Program received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned ()
    at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:36
36  ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such file or directory.

我见过其他一些人遇到过这个问题,但是 none 他们找到了对我有用的解决方案。

您告诉编译器将 string 硬转换为 array of uint8,但是这些类型与赋值不兼容。

在引擎盖下,简化生成的 C 代码(您可以使用 valac -C 获得)如下所示:

#include <glib.h>

int main (void) {
        gchar* str = g_strdup ("Hello World");
        // Ouch: A negative number is used as length for g_memdup
        // This will produce a segfault, because the parameter is unsigned and will overflow to a very big number.
        // The string is only 11 bytes long however
        guint8* data = g_memdup (str, -1 * sizeof(guint8));
        int data_length1 = -1;
        g_print ("%i\n\n", data_length1);
        g_free (data);
        g_free (str);
        return 0;
}

string data type 有两个属性用于您要执行的操作(Vala 语法):

public int length { get; }
public uint8[] data { get; }

所以你可以这样写你的代码:

[indent=4]
init
    str: string = "Hello World";
    print "%i\n", str.length;

或者像这样:

[indent=4]
init
    str: string = "Hello World";
    data: array of uint8 = str.data;
    print "%i\n", data.length;

为了完整起见,这里是 gdb 回溯:

(gdb) run
Starting program: /home/user/src/genie/Test
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
__memcpy_avx_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S:245
245             vmovdqu -0x80(%rsi,%rdx), %xmm5
(gdb) bt
#0  __memcpy_avx_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S:245
#1  0x00007ffff78b66c6 in memcpy (__len=4294967295, __src=0x60cdd0, __dest=<optimized out>) at /usr/include/bits/string3.h:53
#2  g_memdup (mem=0x60cdd0, byte_size=4294967295) at /usr/src/debug/dev-libs/glib-2.46.2-r2/glib-2.46.2/glib/gstrfuncs.c:392
#3  0x00000000004007d6 in _vala_array_dup1 (self=0x60cdd0 "Hello World", length=-1) at /home/user/src/genie/Test.gs:6
#4  0x000000000040085e in _vala_main (args=0x7fffffffdf78, args_length1=1) at /home/user/src/genie/Test.gs:6
#5  0x00000000004008f5 in main (argc=1, argv=0x7fffffffdf78) at /home/user/src/genie/Test.gs:2

因此 g_memdup 试图从此处的 11 字节字符串中复制 4294967295 字节。