• Advertisement
Sign in to follow this  

Linux i686 and x86-64

This topic is 3301 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to get Angelscript running on Linux, both on 32bit and 64bit, but without much luck at the moment. I'm currently running the latest SVN version as of yesterday, but I've tried before with the stable version with unsuccessful results. There are some issues with compiling on both platforms, firstly the in atomic.cpp. Looks like you've used a kernel header for your asCAtomic class which is a bit of a no-no according to the kernel developers, these functions/headers are only really meant to be used inside the kernel. I've changed it to use gcc built in atomic functions which seems to work o.k. for the few tests that do pass at the moment. See below for the changes.
#include <asm/atomic.h>
BEGIN_AS_NAMESPACE
asDWORD asCAtomic::atomicInc()
{
    return atomic_inc_and_test(value);
}
asDWORD asCAtomic::atomicDec()
{
    return atomic_dec_and_test(value);
}

#include <asm/atomic.h>
asDWORD asCAtomic::atomicInc()
{
    return __sync_fetch_and_add(&value, 1);
}
asDWORD asCAtomic::atomicDec()
{
    return __sync_fetch_and_sub(&value, 1);
}

I'm using test_feature to check Angelscript performs as expected, but I've had to change a few of the tests in order to get it to compile. The vector3 tests require scriptmath3d, but scriptmath3d needs new.h which I'm guessing is part of the MS CRT library? So for the moment I've just #ifndef __LINUX__ these tests out, perhaps once the rest of the code is working I'll look at trying to get this built as well. On 64bit I've also had to #ifdef out a few of the tests in test_registertype due to them using asCALL_CDECL. Anyway my current fail on 64bit is in test_stringscript testing script3, this seems to stem from the fact in asCContext::CallGeneric currentObject is NULL, so further on in scriptstring.cpp CScriptString::operator= is getting passed NULL for other. I'll do some more digging and see if I can work out the exact cause of this, but perhaps you might be able to point me in the right direction?

Share this post


Link to post
Share on other sites
Advertisement
Ah, thanks for the tip. I'm not experienced on Linux programming, so I was not aware of this. I'll change the code accordingly.

As for the scriptmath3d.cpp, I believe you can use #include <new> instead of #include <new.h>.

It's been a while since I tested the library with AS_MAX_PORTABILITY. A lot of the tests in test_feature have not been prepared for this. You can just skip these, and I'll add the proper check for portability mode in the SVN.

The fact that test_scriptstring fails surprises me. But then again, I don't have any 64bit machine to test AngelScript on. I can't say where the bug is, but if you set a break pointer in the constructor for the asCGeneric class in the library and check for moments where the currentObject is set incorrectly you may be able determine where the error is. Probably it has to do with a type cast from int to pointer, or something like that.

Share this post


Link to post
Share on other sites
I've checked in some changes that ought to clear away most of the problems you were having while trying to get AS working on Linux 64bit.

Share this post


Link to post
Share on other sites
hello!
Not sure if it's a bug or not, but the current linux version of as_atomic.cpp seems to be missing a __sync_fetch_and_add call:

asDWORD asCAtomic::atomicInc()
{
return (&value, 1);
}

Also, the builtin gcc __sync_* calls are only available in gcc versions >= 4.1, compiling AS on systems with more dated gcc is currently impossible.

Thanks!

Share this post


Link to post
Share on other sites
Here's a version of the AS_LINUX block of as_atomic.cpp that works for all systems (I've also patched the atomic_*_and_test calls):

#elif defined(AS_LINUX)

#if ( ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 1) || __GNUC__ > 4) )
//
// atomic_inc_and_test() and atomic_dec_and_test() from asm/atomic.h is not meant
// to be used outside the Linux kernel. Instead we should use the GNUC provided
// __sync_fetch_and_add() and __sync_fetch_and_sub() functions.
//
// Reference: http://golubenco.org/blog/atomic-operations/
//

asDWORD asCAtomic::atomicInc()
{
return __sync_fetch_and_add(&value, 1);
}

asDWORD asCAtomic::atomicDec()
{
return __sync_fetch_and_sub(&value, 1);
}

#else

END_AS_NAMESPACE
#include <asm/atomic.h>
BEGIN_AS_NAMESPACE

asDWORD asCAtomic::atomicInc()
{
return atomic_inc_and_test((atomic_t *)&value);
}

asDWORD asCAtomic::atomicDec()
{
return atomic_dec_and_test((atomic_t *)&value);
}
#endif

Share this post


Link to post
Share on other sites
Or, alternatively, in as_config.h

#if defined(AS_LINUX) && !( ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 1) || __GNUC__ > 4) )
#define AS_NO_THREADS
#endif


which is probably a safer solution

Share this post


Link to post
Share on other sites
The problem is that with gcc 3.3.4 the program crashed very soon after AS initialization, disabling multithreading fixed that, hence the second patch.

Share this post


Link to post
Share on other sites
Sorry for sidetracking the thread a bit, I'm testing our implementation of AS scripts on a x64 linux machine and I can't get it to work so far. The program crashes (SIGSEGV) in a refcount function, here's the backtrace


0x00007ff73c125f88 in objectString_Addref (obj=0x128f6600128f660) at game/g_ascript.c:859
859 static void objectString_Addref( asstring_t *obj ) { obj->asRefCount++; }
(gdb) backtrace
#0 0x00007ff73c125f88 in objectString_Addref (obj=0x128f6600128f660) at game/g_ascript.c:859
#1 0x00007ff73c125fb4 in objectString_asGeneric_Addref (gen=0x7fff478d93b0) at game/g_ascript.c:863
#2 0x00007ff73e236629 in asCScriptEngine::CallObjectMethod (this=0x12356b0, obj=0x128f6600128f660, i=0x1241880, s=0x12418e0)
at ../../source/as_scriptengine.cpp:2668
#3 0x00007ff73e236766 in asCScriptEngine::CallObjectMethod (this=0x12356b0, obj=0x128f6600128f660, func=41) at ../../source/as_scriptengine.cpp:2658
#4 0x00007ff73e28f5e4 in asCContext::ExecuteNext (this=0x1297d00) at ../../source/as_context.cpp:2307
#5 0x00007ff73e293076 in asCContext::Execute (this=0x1297d00) at ../../source/as_context.cpp:1096
#6 0x00007ff73e29ee78 in asCModule::CallInit (this=0x1268450) at ../../source/as_module.cpp:217
#7 0x00007ff73e29f14b in asCModule::Build (this=0x1268450) at ../../source/as_module.cpp:168
#8 0x00007ff73e22e6b8 in qasBuildModule (engineHandle=0, module=0x7ff73c1ab10f "gametypes") at angelwrap/qas_angelwrap.cpp:629
#9 0x000000000043a11b in ?? ()
(gdb)





Note the the obj pointer address seems to be valid.

Share this post


Link to post
Share on other sites
It looks to be valid but it is not. Look closely at the value:

0x128f6600128f660

That is in fact the correct address - '0x128f660' - with itself added to the end - '0128f660'. I've encountered and reported this problem here. I'm still hacking away at the native calling conventions for x86_64/gcc (still haven't quite gotten virtuals to work properly) but once I'm done with that I'll have a look. WitchLord has also promised to look into it.

Share this post


Link to post
Share on other sites
oh, right, how could I miss that.. Note that the address gets mangled with AS_MAX_PORTABILITY defined, so my guess is that it's a bug in the VM itself

Share this post


Link to post
Share on other sites
BTW, the very same thing happens in win64:

Quote:

> game_x64.dll!objectString_Addref(asstring_t * obj=0x01e467a001e467a0) Line 859 + 0xb bytes C
game_x64.dll!objectString_asGeneric_Addref(void * gen=0x000000000012eeb8) Line 864 C
angelwrap_x64.dll!asCScriptEngine::CallObjectMethod(void * obj=0x01e467a001e467a0, asSSystemFunctionInterface * i=0x000000000215ebe0, asCScriptFunction * s=0x000000000217bbd0) Line 2713 C++
angelwrap_x64.dll!asCScriptEngine::CallObjectMethod(void * obj=0x01e467a001e467a0, int func=41) Line 2659 C++
angelwrap_x64.dll!asCContext::ExecuteNext() Line 2308 C++
angelwrap_x64.dll!asCContext::Execute() Line 1096 + 0xa bytes C++
angelwrap_x64.dll!asCModule::CallInit() Line 218 C++
angelwrap_x64.dll!asCModule::Build() Line 170 C++
angelwrap_x64.dll!qasBuildModule(int engineHandle=0, const char * module=0x0000000002cad868) Line 630 C++

Quote:

+ obj 0x01e467a001e467a0 {buffer=??? len=??? asRefCount=??? ...} asstring_t *


EDIT: It's normal that it ends in the non-generic function, because our code uses the generic function just to call the normal function.

[Edited by - jal_ on February 8, 2009 6:17:51 AM]

Share this post


Link to post
Share on other sites
Quote:

The problem is that with gcc 3.3.4 the program crashed very soon after AS initialization, disabling multithreading fixed that, hence the second patch.


Did it crash due to asCAtomic, or something else? If it was due to asCAtomic, then perhaps it works if the critical sections are used instead?

I'd prefer not to disable the multithreading support by default. If it is possible to get multithreading working then it should be turned on by default (even if it hurts performance).

I'll add a section in the manual on how to get the most performance out of the library, e.g. by compiling the library with asNO_THREADS.



I'll look into the problem with the 64bit platforms. It's most likely a bad type cast somewhere. The problem is that I don't have a 64bit platform to test this on, but I've asked droz for access to his VPS, so hopefully I should be able to fix this soon enough.

Share this post


Link to post
Share on other sites
Quote:
Original post by WitchLord
Quote:

The problem is that with gcc 3.3.4 the program crashed very soon after AS initialization, disabling multithreading fixed that, hence the second patch.


Did it crash due to asCAtomic, or something else? If it was due to asCAtomic, then perhaps it works if the critical sections are used instead?


Here's the backtrace:

#0  0x00000041 in ?? ()
#1 0xb7bb9662 in ScriptStructFactory (objType=0x8401ad0, engine=0x83a8fb0) at ../../source/as_scriptstruct.cpp:69
#2 0xb7bbf674 in asCArrayObject::Construct (this=0x83ee468, buf=0x8446568, start=0, end=3) at ../../source/as_arrayobject.cpp:452
#3 0xb7bbf544 in asCArrayObject::CreateBuffer (this=0x83ee468, buf=0x83ee478, numElements=3) at ../../source/as_arrayobject.cpp:420
#4 0xb7bbee23 in asCArrayObject (this=0x83ee468, length=3, ot=0x840c7b0) at ../../source/as_arrayobject.cpp:302
#5 0xb7bbe2ef in ArrayObjectFactory2 (ot=0x840c7b0, length=3) at ../../source/as_arrayobject.cpp:56
#6 0xb7bd2996 in endcopy () at ../../source/as_callfunc_x86.cpp:565
#7 0xb7bd22a3 in CallSystemFunction (id=2, context=0x8410dd8, objectPointer=0x0) at ../../source/as_callfunc_x86.cpp:324
#8 0xb7bf9bc0 in asCContext::ExecuteNext (this=0x8410dd8) at ../../source/as_context.cpp:2044
#9 0xb7bf834d in asCContext::Execute (this=0x8410dd8) at ../../source/as_context.cpp:1096
#10 0xb7c05632 in asCModule::CallInit (this=0x83eee88) at ../../source/as_module.cpp:217
#11 0xb7c05415 in asCModule::Build (this=0x83eee88) at ../../source/as_module.cpp:168



jal: figured :)

Share this post


Link to post
Share on other sites
I just checked in some changes (rev 354) that I hope fixes both of your problems.

First of all I changed as_atomic.cpp to use critical sections on GCC for versions older than 4.1. This will avoid using the kernel functions altogether, at the price of slower performance. (Remember to turn off multithreading if you don't need it)

I also found a couple of places where the compiler was generating incorrect bytecode for 64bit platforms. Hopefully with these fixes you won't get the SEGV crashes anymore.

Share this post


Link to post
Share on other sites
Thanks! I'll check out the x64 changes asap. As for the atomic stuff, you forgot to add the
		#if !( ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 1) || __GNUC__ > 4) )
// Only with GCC 4.1 was the atomic instructions available
#define AS_NO_ATOMIC
#endif




section into the
#elif defined(__linux__)


block ;) Not sure if it really belongs to the __APPLE__ one.. After fixing this section, things seem to be working fine again

Share this post


Link to post
Share on other sites
Due to the change to the Makefile, linking a library with libangelscript.a produces an error:

/usr/bin/ld: ../libsrcs/angelscript/angelSVN/sdk/angelscript/lib/libangelscript.a(as_scriptengine.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
../libsrcs/angelscript/angelSVN/sdk/angelscript/lib/libangelscript.a: could not read symbols: Bad value
collect2: ld returned 1 exit status

Share this post


Link to post
Share on other sites
I'm not sure what it may be. gargltk has just finished implementing the native support for 64bit Linux and he didn't report this problem.

Share this post


Link to post
Share on other sites
adding back the -fPIc flag fixed the problem for me, not sure why it got removed in the first place..

Share this post


Link to post
Share on other sites
The only modification I made to the makefile is that I've added 'as_callfunc_x64_gcc.cpp' to the list of sources - the flag didn't exist in the first place. Anyway, adding '-fPIC' would have been my suggestion as well - I've seen this before with other libraries as well, and it's always been the way I fixed it.

Share this post


Link to post
Share on other sites
Yes, I think you should, will probably keep more duplicate bug reports from pouring in in the future :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement