x86_64 segmentation fault due to forgotten extern directive

G

Geert Fannes

------_=_NextPart_001_01C524B3.040292C4
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

Hello, I have been tracking down a segmentation fault that only appeared
on a x86_64 64 bit linux machine and was finally able to catch the
bastard. I'm not sure it is a bug (it looks more like bad coding
practice from my side), but it might be interesting for other people
experiencing the same problems.

=20

I created a toy example that shows the essence: I have a ruby program
(test.rb) that calls a C function "cf_test" which was added to the class
String. This C function is defined in test.c and calls another C
function (localFunction) that is contained in another .c file (test2.c)
and thus also in another object file (test2.o). Finally, "compile"
contains the compilation instructions I used for compiling all this.

=20

Ruby generates a segmentation fault when I omit the "extern" directive
on line 2 of test.c. I guess it is bad practice to omit this, but I got
no errors when I compiled test.c or linked test.o and test2.o together
to generate the shared object file test.so. For some strange reason,
this does not cause any problems on a 32 bit machine, I only found out
about it when I tried to port everything to a x86_64 machine

=20

I hope this can be useful for someone,

Greetings,

Geert.

=20

***test.rb***

require './test.so'

=20

a=3D'abc'.cf_test

puts a.class

=20

***test.c***

#include "ruby.h"

extern VALUE localFunction(char*);//THIS IS A CRITICAL LINE ON x86_64

VALUE f_test(VALUE self)

{

return localFunction(RSTRING(self)->ptr);

}

=20

VALUE cString;

=20

void Init_test()

{

cString=3Drb_define_class("String",rb_cObject);

rb_define_method(cString,"cf_test",f_test,0);

}

=20

***test2.c***

#include "ruby.h"

=20

VALUE localFunction(char *pch)

{

return rb_str_new2(pch);

}

=20

***compile***

#!/bin/bash

=20

gcc -fpic -c test2.c -I/usr/local/lib/ruby/1.9/x86_64-linux

=20

gcc -fpic -c test.c -I/usr/local/lib/ruby/1.9/x86_64-linux

gcc -shared test.o test2.o -o test.so

=20


------_=_NextPart_001_01C524B3.040292C4--
 
V

Ville Mattila

Hello,

This is easy to explain. On 32 bit system non introduced functions are
treated like they return int. This is 32 bit value on 32 and 64 bit systems.
The VALUE is actually a long type which 32 bit in 32 bit OS and 64 bit
on 64 bit OS. So you will have bad data as a return value if you don't
declare your functions correctly.

- Ville
 
T

ts

G> to generate the shared object file test.so. For some strange reason,
G> this does not cause any problems on a 32 bit machine, I only found out
G> about it when I tried to port everything to a x86_64 machine

Normal, on 32 bit machine sizeof(int) == sizeof(unsigned long). This is
not the case on x86_64




Guy Decoux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top