LLI Segfaulting

Hi,

I've been stuck with this problem for a while now, and my supervisor's
starting to think it's a bug in lli, but I thought I'd ask here before going
down that route. I have this code, which stores an array in my 'MainClass',
and prints out an element of it.

Note that the print statement is irrelevant here, it segfaults regardless,
and this code has been run with -O2 optimization level, but segfaults either
way (the code is just a lot shorter and easier to post this way)

%MainClass = type { { i32, [0 x i32] } }

@.gvar_array = private unnamed_addr constant [5 x i32] [i32 1, i32 2, i32 3,
i32 4, i32 5]

define void @"MainClass::<init>()"(%MainClass* nocapture %this_ptr) nounwind
{
allocas:
  %0 = getelementptr inbounds %MainClass* %this_ptr, i64 0, i32 0, i32 0
  store i32 5, i32* %0, align 4
  %1 = getelementptr inbounds %MainClass* %this_ptr, i64 0, i32 0, i32 1
  %2 = bitcast [0 x i32]* %1 to i8*
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* bitcast ([5 x i32]*
@.gvar_array to i8*), i64 20, i32 4, i1 false)
  ret void
}

define void @main() nounwind {
allocas:
  %0 = alloca { i32, [0 x i32] }, align 8
  %1 = getelementptr inbounds { i32, [0 x i32] }* %0, i64 0, i32 0
  store i32 5, i32* %1, align 8
  %2 = getelementptr inbounds { i32, [0 x i32] }* %0, i64 0, i32 1
  %3 = bitcast [0 x i32]* %2 to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* bitcast ([5 x i32]*
@.gvar_array to i8*), i64 20, i32 4, i1 false)
  %4 = getelementptr inbounds [0 x i32]* %2, i64 0, i64 0
  %5 = load i32* %4, align 4
  %6 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]*
@.int_and_newline, i64 0, i64 0), i32 %5) nounwind
  ret void
}

declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64,
i32, i1) nounwind

lli array_ex.bc

1
Segmentation fault

If anyone would care to let me know what information is required to help
here, then I'll supply it.

Thanks,
Fraser

Hi Fraser, it looks to me like you are smashing the stack.

define void @main() nounwind {
allocas:
   %0 = alloca { i32, [0 x i32] }, align 8

^ this allocates 4 bytes on the stack.

   %2 = getelementptr inbounds { i32, [0 x i32] }* %0, i64 0, i32 1

^ this gets a pointer to the byte after the 4 allocated bytes.

   %3 = bitcast [0 x i32]* %2 to i8*
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* bitcast ([5 x i32]*
@.gvar_array to i8*), i64 20, i32 4, i1 false)

This copies 20 bytes there, kaboom!

Ciao, Duncan.

Hi Duncan,

Duncan Sands wrote:

Hi Fraser, it looks to me like you are smashing the stack.

define void @main() nounwind {
allocas:
   %0 = alloca { i32, [0 x i32] }, align 8

^ this allocates 4 bytes on the stack.

   %2 = getelementptr inbounds { i32, [0 x i32] }* %0, i64 0, i32 1

^ this gets a pointer to the byte after the 4 allocated bytes.

   %3 = bitcast [0 x i32]* %2 to i8*
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %3, i8* bitcast ([5 x i32]*
@.gvar_array to i8*), i64 20, i32 4, i1 false)

This copies 20 bytes there, kaboom!

Such a painfully obvious answer, thank you! I'm assuming this is what
happens when I use the unoptimized version of the code and call

   %0 = alloca %MainClass

then transfer the array into that. If I'm taking a MainClass pointer into my
<init> function, can I then just re-allocate it as a { i32, [5 x i32] } when
I learn about the length? That doesn't sound like the nicest option. I'm not
aware of a way of only allocating a part of a literal struct, is that
possible?

Cheers,
Fraser

Hi Fraser,

Is there anything preventing you from using a pointer for the second part of the structure and allocating memory for it later?

Thanks,
Gavin

Hi Gavin,

Do you mean something along the lines of having my array struct as { i32,
i32* } and then indexing it with a gep and allocating the appropriate memory
when I learn of it?

Thanks,
Fraser

Gavin Harrison-2 wrote:

Yes, that is what I mean. :slight_smile:

Sorry for my ignorance, but I'm unaware as to how I'd achieve this.

I know I'd have this,

%MainClass = type { { i32, i32* } }

And something along these lines:

%1 = getelementptr inbounds %MainClass* %0, i32 0, i32 0 ; get to the
'array'
%2 = getelementptr inbounds { i32, i32* }* %1, i32 0, i32 1 ; index the
data pointer

And then I'd want to:

alloca i32, i64 5

But I don't understand how I'd associate this allocation with the existing
integer 'array' pointer. Also, what would happen when the function returns,
wouldn't the new array allocation portion go out of scope, as it's allocated
on the function's stack frame?

Thanks,
Fraser

Gavin Harrison-2 wrote:

One way to find out how to do these sorts of things is to write them in C or C++ and see what clang does :slight_smile:

In C you would do something like this:

a = malloc(sizeof(int) * n);

The associated LLVM IR would look similar to this:

%a = alloca i32* ; %a's type is i32**
%n = alloca i32
...
%1 = load i32 %n
%2 = sext i32 %1 to i64
%3 = mul i64 4, %2
%4 = call i8 * @malloc(i64 %2)
%5 = bitcast i8* %4 to i32*
store i32* %5, i32** %a

Thanks,
Gavin