Advertisement

Segfault Linux x86_64

Started by May 16, 2010 03:40 PM
4 comments, last by WitchLord 14 years, 6 months ago
Hey all. I am having a bit of an issue. The application compiles fine on both Windows 64bit and Linux 64bit (using the most recent available version from the The ArchLinux AUR [2.18.2-1 as of this writing]), but it seems that only on the linux version this problem arises. I even gave the source to a friend and he was able to compile and run on windows jut fine. Here is the test code I am using:
/*
    Short test of angelscript functionality.
*/

#include <iostream>
#include <cassert>

#include "TestClass.h"
#include "scriptbuilder.h"
#include "scriptstring.h"
#include <angelscript.h>


int main(void)
{
    int r;

    asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
    RegisterScriptString(engine);
    RegisterScriptStringUtils(engine);

    std::cout<<"r = engine->RegisterObjectType(TestClass,sizeof(TestClass),asOBJ_REF); assert(r>=0);\n";
    r = engine->RegisterObjectType("TestClass",sizeof(TestClass),asOBJ_REF); assert(r>=0);

    std::cout<<"r = engine->RegisterObjectBehaviour(TestClass,asBEHAVE_FACTORY,TestClass@ f(), asFUNCTION(ClassFactory), asCALL_CDECL);\n";
    r = engine->RegisterObjectBehaviour("TestClass",      asBEHAVE_FACTORY,
                                        "TestClass@ f()", asFUNCTION(ClassFactory), asCALL_CDECL);
    assert( r >= 0 );

    std::cout<<"r = engine->RegisterObjectBehaviour(TestClass,asBEHAVE_ADDREF,void f(),asMETHOD(TestClass,AddRef), asCALL_THISCALL);\n";
    r = engine->RegisterObjectBehaviour("TestClass",asBEHAVE_ADDREF,"void f()",asMETHOD(TestClass,AddRef), asCALL_THISCALL);
    assert(r>=0);

    std::cout<<"r = engine->RegisterObjectBehaviour(TestClass,asBEHAVE_RELEASE,void f(),asMETHOD(TestClass,Release), asCALL_THISCALL);\n";
    r = engine->RegisterObjectBehaviour("TestClass",asBEHAVE_RELEASE,
                                        "void f()",asMETHOD(TestClass,Release), asCALL_THISCALL);
    assert(r>=0);

    std::cout<<"r=engine->RegisterObjectMethod(TestClass,void print(string@),asMETHOD(TestClass,TC_Print),asCALL_THISCALL);\n";
    r=engine->RegisterObjectMethod("TestClass", "void print(string@)",asMETHOD(TestClass,TC_Print),asCALL_THISCALL);
    assert(r>=0);

    std::cout<<"r = engine->RegisterObjectMethod(TestClass,void count(int),asMETHOD(TestClass,TC_Count), asCALL_THISCALL);\n";
    r = engine->RegisterObjectMethod("TestClass", "void count(int)",asMETHOD(TestClass,TC_Count), asCALL_THISCALL);
    assert(r>=0);

    std::cout<<"CScriptBuilder builder;\n";
    CScriptBuilder builder;

    std::cout<<"r = builder.StartNewModule(engine,Base);\n";
    r = builder.StartNewModule(engine, "Base");

    if( r < 0 ) { std::cout<<"Out of memory."; return 0; } r = builder.AddSectionFromFile("./main.script");

    if( r < 0 ) { std::cout<<"Please correct the errors in the script and try again.\n"; return 0; }

    std::cout<<"r = builder.BuildModule();";
    r = builder.BuildModule();

    if( r < 0 ) { std::cout<<"Failed to build module.\n"; return 0; }

    std::cout<<"asIScriptModule *mod = engine->GetModule(Base);\n";
    asIScriptModule *mod = engine->GetModule("Base");

    std::cout<<"int funcId = mod->GetFunctionIdByDecl(void run());\n";
    int funcId = mod->GetFunctionIdByDecl("void run()"); // gets right up to here.
    // and I know the segfault occurs here because the following block never gets run
    // with the if contidtion commented out, asIScriptContext *ctx = engine->CreateContext(); never runs either

    std::cout<<"if( funcId < 0 )";
/*    if( funcId < 0 )
    {
        // The function couldn't be found. Instruct the script writer
        // to include the expected function in the script.
        std::cout<<"The script must have the function 'void run()'. Please add it and try again.\n";
        return 0;
    }*/

    std::cout<<"asIScriptContext *ctx = engine->CreateContext();";
    // Create our context, prepare it, and then execute
    asIScriptContext *ctx = engine->CreateContext();

    std::cout<<"ctx->Prepare(funcId);";
    ctx->Prepare(funcId);

    std::cout<<"r = ctx->Execute();";
    r = ctx->Execute();

    std::cout<<"if( r != asEXECUTION_FINISHED )";
    if( r != asEXECUTION_FINISHED )
    {
        // The execution didn't complete as expected. Determine what happened.
        if( r == asEXECUTION_EXCEPTION )
        {
            // An exception occurred, let the script writer know what happened so it can be corrected.
            std::cout<<"An exception \'"
            <<ctx->GetExceptionString()<<
            "\' occurred. Please correct the code and try again.\n";
        }
    }
}
Here is the GDB backtrace
Building to ensure sources are up-to-date
Build succeeded
Selecting target: 
Debug
Adding source dir: /media/sdd1/AngelScriptTest/
Adding source dir: /media/sdd1/AngelScriptTest/
Adding file: bin/Debug/AngelScriptTest
Starting debugger: 
done
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints
Debugger name and version: GNU gdb (GDB) 7.1
Program received signal SIGSEGV, Segmentation fault.
In X64_CallFunction(unsigned int const*, unsigned char const*, void*) () (/usr/lib/libangelscript-2.18.2.so)
Debugger finished with status 0
Anyone have any insight? AngelScript is a great language to work with and it is a shame that this is happening.
There seems to be a bug in the code for the native calling conventions for 64bit Linux, which is in the file as_callfunc_x64_gcc.cpp.

However, are you sure of where the program stops? The call to int funcId = mod->GetFunctionIdByDecl("void run()"); doesn't invoke the X64_CallFunction.

I think it is most likely crashing from inside the call to r = builder.BuildModule();. If I'm right, then this would be when initializing the global variables that you have in your script. Do you have any global variables in the script you're compiling?

Would you mind setting a break point on the X64_CallFunction and try to see what's going wrong in that function? I don't have 64bit Linux myself so I cannot do the debugging on my own.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement
Sure, I can do that. It seems that the segfault occurs on

r = ctx->Execute();


And no, there are no global variables in the script. Everything that is registered to the VM is registered in the main. I am no wizard at calling conventions and low level stuff like that (although I would love to learn), but I will still take a look and see if there are any logic errors that may be causing this. Other than that, I don't know what else I can do. =/

EDIT: Nope. Though I consider myself fairly experienced with C++, I don't have a clue what I am looking at. :downs:

[Edited by - _orm_ on May 23, 2010 6:44:16 PM]
So the code does reach the ctx->Execute()? Probably the cout wasn't flushed to the output when the segfault happened, which led you to think it didn't reach this spot before.

OK. Can you show me the script that you're executing? Try narrow down the script to the bare minimum that still fails. This will help me identify what kind of call that is breaking in X64_CallFunction.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Done and done. It segfaults when it tries to invoke the entry function.

//#include "Over.script"//#define FOO "Hello foo!" // I was testing all kinds of crap. TBH, the #define directive would make exposing things like OpenGL infinitely simpler./*void ObjPrint(TestClass@ tc, string@ message){	tc.print(message);}*/void run(){	//TestClass@ obj = TestClass();	// obj.print("Hello world");		// apparently the new operator has been cast aside in favor of just calling Foo()	// ObjPrint(TestClass(),"ObjPrint(TestClass(),message) works!");	// message("Calling a function fron an #included file.");		//TCProxy@ tcp = TCProxy(); // testing out a proxy class to work around the "can't inherit from VM registered class" limitation. No big deal. also defined in Over.script}
This doesn't make sense. Your script isn't calling any application registered functions and doesn't have any variables declared in it. The X64_CallFunction shouldn't even be invoked in this test. How can it be giving a segfault in the function?

Can you try commenting out the stuff you're registering with the engine, to see if the error goes away? If it does, which was the last function you removed to make the error go away?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement