I have Valac 0.30 installed. Running the following code,
[indent=4]
init
str : string
str = "Hello World";
data : array of uint8
data = (array of uint8) str;
print "%i\n", data.length;
I get a segfault. GDB tells me this:
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.
I've seen some other people with this problem, but none of them got solutions which have worked for me.
You are telling the compiler to hard cast a string
into an array of uint8
, however those types are not assignment compatible.
Under the hood the simplified generated C code (which you can get with valac -C
) looks like this:
#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;
}
The string
data type has two properties that are meant for what you are trying to do (Vala syntax):
public int length { get; }
public uint8[] data { get; }
So you could write your code like this:
[indent=4]
init
str: string = "Hello World";
print "%i\n", str.length;
Or like this:
[indent=4]
init
str: string = "Hello World";
data: array of uint8 = str.data;
print "%i\n", data.length;
For completeness here is the gdb
backtrace:
(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
So g_memdup
is trying to copy 4294967295 bytes from an 11 byte string here.