I just noticed that I am unable to have a function return a struct.
I am running this on ARM32/debian docker image with threads enabled.
This is the function that gives me the run time error:
struct CEC_call des_CEC_call(char * buffy){
char request = buffy[0]; // fails here
buffy+=4;
char obligation = buffy[1];
buffy+=4;
struct CEC_call ceccall;
pepcall.request = request;
pepcall.obligation = obligation;
return ceccall;
}
But if I change the return type to void
, there is no issue in running:
void des_CEC_call(char * buffy){
char request = buffy[0]; // doesn't fail here
buffy+=4;
char obligation = buffy[1];
buffy+=4;
struct CEC_call ceccall;
pepcall.request = request;
pepcall.obligation = obligation;
}
Return works fine as well with any of the standard return types.
Header where the struct is defined is included in the file with the function although it will still crash even if the struct is defined in the same file. Not sure how to proceed with debugging, any help appreciated.
EDIT:
More details, based on suggestions from comments:
I have rerun the same program on my mac as well as some other non arm architectures with docker, and it runs without any noticeable issues. Some aspects relating to bit shifting are slightly different as expected but no run time error from the segmentation fault. I tried running it with various optimisation levels, but to no avail.
I have used GDB before so I thought that might provide some insight, sadly I have not been able to get it to work on this container.
I ensured GDB is installed and recompiled the binary with -0g
.
I ran docker with --cap-add=SYS_PTRACE
and --security-opt seccomp=unconfined
.
Each time I got:
warning: Could not trace the inferior process.
Error:
warning: ptrace: Function not implemented
During startup program exited with code 127.
I am able to use GDB with other non-arm, non-32bit docker images without any issues. I think this is enough for another question, as I’ve spent ages trying to get GDB working with that environment.
I am not sure really how to verify otherwise, but I have printed out the address buffy
is pointing and the value held by buffy[0]
in the preceding functions as well as the problematic one.
Without struct return:
address of buffy = 0xff58b9ec
buffer[0] = ff
address of buffy = 0xff58b9ec
buffer[0] = ff
address of buffy = 0xff58b9ec
buffer[0] = ff
With struct return:
address of buffy = 0xff58b9ec
buffer[0] = ff
address of buffy = 0xff58b9ec
buffer[0] = ff
address of buffy = (nil)
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Struct CEC_call
does not have any other fields.
It could be a buffer overflow somewhere, but there aren’t any buffers at least none made by me. I have not used QEMU IIRC or valingrad before, but will look into them in more details. I can not test nateively at the moment as I do not have the access to the intended embedded linux.
2
Answers
My problem was that the header for the file that has got the
struct CEC_call des_CEC_call(char * buffy)
function declaration has not been included in the calling file.Function called worked fine if it was returning standard types or void, but with custom struct return the array pointer passed in was nullified. This kind of baffled me initially as I didn’t think it would compile due to missing declaration and this segmentation fault only happened on arm32 architecture, I didn't get that crash on OSX.
It seems you have mismatch in names of your variables:
ceccall
andpepcall
, and you return an uninitialized variablececcall
.