🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Segmentation fault when using cdecl on linux

Started by
1 comment, last by wrt 17 years, 7 months ago
hi there, i'm trying to integrate angelscript into my robot simulation I'm doing as a project for school. When i try to use a function with cdecl my app crashes with a segfault. Generic works however. I'm propably doing something quite stupid ... here's my code:

RobotScript::RobotScript()
{
	engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
        if( engine == 0 )
        {
                cout << "Failed to create script engine." << endl;
        }
	
	// The script compiler will write any compiler messages to the callback.
        engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);
	
	if( !strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
	{
		cout << "a" << endl;
		RegisterScriptString(engine);
		engine->RegisterGlobalFunction("void printText(int &in)", asFUNCTION(printText_Generic), asCALL_GENERIC);
		engine->RegisterGlobalFunction("void printNumber(int &in)", asFUNCTION(printNumber), asCALL_CDECL);
	}
	else
	{
		cout << "b" << endl;
	}
}

RobotScript::~RobotScript()
{
	 // Release the engine
        engine->Release();
}

void RobotScript::addFunction(string code)
{
	engine->AddScriptSection(0, "test", code.c_str(), code.size());
	if (engine->Build(0) < 0)
	{
		cout << "couldnt compile" << endl;
	}
	cout << "Source added" << endl;
}

int RobotScript::runFunction(string id)
{
	ctx = engine->CreateContext();
	
	int funcId = engine->GetFunctionIDByDecl(0, id.c_str());
	if (funcId < 0)
	{
		cout << "Function not found" << endl;
		return -2;
	}
	
	int r = ctx->Prepare(funcId);
	if( r < 0 ) 
	{
		cout << "Failed to prepare the context." << endl;
		ctx->Release();
		return -1;
	}
	cout << "Executing:" << endl;
	r = ctx->Execute();
	if( r != asEXECUTION_FINISHED )
	{
		// The execution didn't finish as we had planned. Determine why.
		if( r == asEXECUTION_ABORTED )
			cout << "The script was aborted before it could finish. Probably it timed out." << endl;
		else if( r == asEXECUTION_EXCEPTION )
		{
			cout << "The script ended with an exception." << endl;

			// Write some information about the script exception
			int funcID = ctx->GetExceptionFunction();
			cout << "func: " << engine->GetFunctionDeclaration(funcID) << endl;
			cout << "modl: " << engine->GetFunctionModule(funcID) << endl;
			cout << "sect: " << engine->GetFunctionSection(funcID) << endl;
			cout << "line: " << ctx->GetExceptionLineNumber() << endl;
			cout << "desc: " << ctx->GetExceptionString() << endl;
		}
		else
			cout << "The script ended for some unforeseen reason (" << r << ")." << endl;
	}
	else
	{
		// Retrieve the return value from the context
		//float returnValue = ctx->GetReturnFloat();
		//cout << "The script function returned: " << returnValue << endl;
	}
	
	ctx->Release();
	
	return 0;
}

void RobotScript::deleteFunction(string id)
{
	/// \todo 1 implement this
}

void MessageCallback(const asSMessageInfo *msg, void *param)
{
	const char *type = "ERR ";
	if( msg->type == asMSGTYPE_WARNING ) 
		type = "WARN";
	else if( msg->type == asMSGTYPE_INFORMATION ) 
		type = "INFO";

	printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);
}

void printText(string &text)
{
	cout << "Script: "<< text << endl;
}

void printText()
{
	cout << "Script works ... " << endl;
}

// Function implementation with generic script interface
void printText_Generic(asIScriptGeneric *gen)
{
	int *str = (int*)gen->GetArgAddress(0);
	cout << "blub" << *str<< endl;
}

void printNumber(int &zahl)
{
	cout << "Script: " << zahl << endl;
}

the segmentation fault occurs at this place acording to gdb:

asm("pushl %ecx           \n"
                "movl  12(%ebp), %ecx \n" // paramSize
                "movl  8(%ebp), %eax  \n" // args
                "addl  %ecx, %eax     \n" // push arguments on the stack
                "cmp   $0, %ecx       \n"
                "je    endcopy        \n"
                "copyloop:            \n"
                "subl  $4, %eax       \n"
                "pushl (%eax)         \n"
                "subl  $4, %ecx       \n"
                "jne   copyloop       \n"
                "endcopy:             \n"
                "call  *16(%ebp)      \n"
                "addl  12(%ebp), %esp \n" // pop arguments
                "popl  %ecx           \n");

in this function: void CallCDeclFunction(const asDWORD *args, int paramSize, size_t func) I'm using CCux-linux, which is a i686 optimised distribution running on athlon XP prozessor. compiler flaggs are: -march=i686 -pipe -fomit-frame-pointer if any other informations could help you please don't hesitate to ask. cu and thanks for your time Simon
Advertisement
Which function is the script calling when it crashes? printNumber?

Sounds like the calling conventions on your configuration is different from what AngelScript has been prepared for. The flag -fomit-frame-pointer is one likely cause, give it a try without this flag and see if it works.

Can you show me the disassembly of a call to the printNumber function made from the C++ code? It might give me some hints on what the difference is.

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

thanks a lot

you were right about the "-fomit-frame-pointer", now it works just fine

cu Simon

This topic is closed to new replies.

Advertisement