Weird if() behavior

Started by
7 comments, last by bradbobak 9 years, 5 months ago

So I've been working on creating my lua script class interface, and I ran into an interesting crash-inducing problem.


lua_State* SCRIPT::runInit()
{
	log->debugData("Running init function");
	lua_getglobal(L, "init");
	int er = lua_pcall(L, 0, 0, 0);
	if(er != 0)
	{
		log->logData("Pcall error", er);
		log->logData("Failed to run init function", lua_tostring(L, -1));
		return L;
	}
	log->debugData("Ran init function");
	return L;
}

When I run this, it should call the "init" function. If it succeeds, er should equal 0, thus bypassing the if statement and going right to "log->debugData("Ran init function");"

Here's the init function in the lua file:


function init()
	MainScene:SLog("Init DOES in fact exist...")
	MainScene:addMesh("sibenik/sibenik.obj", 0, 0, 0, 0, 0, 0, 1, 1, 1)
end 

However, when I DO run this, here's the output directly from the log file:


DEBUG: Running init function
Init DOES in fact exist...
Loading mesh : sibenik/sibenik.obj
DEBUG: Loaded mesh
Pcall error : 0

Then it errors on the second log->logData() due to the empty lua_tostring(L, -1).

Note that the Pcall error is returning 0... This means that it shouldn't have gone into the if statement at all, however, it does anyway...

Is it a problem with my compiler?

I develop to expand the universe. "Live long and code strong!" - Delta_Echo (dream.in.code)
Advertisement

What does logData do internally? Is there any way something in there could be doing something strange?

Have you tried stepping through the program in the debugger and seeing what the value of the variable is at different points?

The not equal operator in Lua is ~= .

Edit: don't mind me, mistook the first block for Lua code.

The error will most likely occurs in this function call:


MainScene:addMesh("sibenik/sibenik.obj", 0, 0, 0, 0, 0, 0, 1, 1, 1)

You should add a error callback handler to track the error. Lua will output the error and a stacktrace which helps a lot to track down a bug. Take a look at the doc.

Well, pre-coffee the code you've posted looks alright.

How do you perform the binding between C++ and lua? There are some peculiarities with using C++ objects and lua errors during a call chain of C++->lua->C++->lua. By default lua uses setjmp/longjmp to handle errors, which is not compatible to C++'s object lifetime model. Have you tried running it with an empty init function? Does it work?

Is your linked lua library compatible? Have you compiled it on the same machine?

Some kind of linker mismatch could produce such errors, e.g. linking against another version of lua than the one loaded, which could result in stack corruption.

Have you checked debug logging functions? Maybe they produce buffer overruns.

I guess there are plenty of possibilities why code does strange things. A compiler bug is rather unlikely. What compiler version are you using?

Your logData function is messing up somewhere. You should check the actual value of 'er' in debug.


Then it errors on the second log->logData() due to the empty lua_tostring(L, -1).

Your logData function is most likely also what's causing the crash. Your code should allow for "empty" return values from lua_tostring...

Show us da codez.


void LOGGER::logData(std::string data1, std::string data2)
{
	file  << data1 << " : " << data2 << std::endl << std::flush;
	std::cout  << data1 << " : " << data2 << std::endl << std::flush;
	for(int i = 1; i < 10; i++)
	{
		backlog[i] = backlog[i-1];
	}
	std::stringstream tmp;
	tmp << data1 << " : " << data2;
	backlog[0] = tmp.str();
}

void LOGGER::logData(std::string data1, char* data2)
{
	file  << data1 << " : " << data2 << std::endl << std::flush;
	std::cout  << data1 << " : " << data2 << std::endl << std::flush;
	for(int i = 1; i < 10; i++)
	{
		backlog[i] = backlog[i-1];
	}
	std::stringstream tmp;
	tmp << data1 << " : " << data2;
	backlog[0] = tmp.str();
}

Here's the code to the logData function... Both the string version and the char* version.

EDIT: upon further investigation (I.E. stepping to the extreme) I found it's definitely crashing within lua_getstring(L, -1) when it tries to access the stack. My question now becomes: why is it making it that far when er = 0... And yes, er does equal 0. Debugged with a cout<<er.

I develop to expand the universe. "Live long and code strong!" - Delta_Echo (dream.in.code)

Here's the code to the logData function... Both the string version and the char* version.

Where's the int version used for printing er?

Anyway, to speed things up, just remove all of your logData calls, and if it still crashes, then we will know that the problem is or isn't with logData... Leave the lua_toString call in there though - maybe do OutputDebugString(lua_tostring(L, -1)) with it instead, so the compiler doesn't optimize it away as useless.

(Note: I have a hunch that your stack gets corrupted by a std::string allocation on the stack that is not de-allocated after the first call to your logData function - I've seen this happen before - to avoid that "broken" stack allocation, you should always pass std::string parameters as references into your functions)


for(int i = 1; i < 10; i++)
{
backlog = backlog[i-1];
}

fyi, i think this is wrong.. everything will be set to backlog[0]. I think you need to do the loop in reverse.

This topic is closed to new replies.

Advertisement