[SOLVED] Wrapper Segfault

Started by mdblabs, October 11, 2017, 12:13:47 AM

Previous topic - Next topic
October 11, 2017, 12:13:47 AM Last Edit: October 12, 2017, 11:09:26 AM by mdblabs
Hi,
first of all, I would like to thank you for this great open source project, and community!

I'm trying to create an stand-alone version of solarus, wrapping the execution of the quest, just as the editor code does. I have satisfactory compiled solarus library, and I have created a simple scaffolding C++ code to wrap the execution.

Basically, it mimics solarus-editor's "play" functionality, or solarus -run. The idea is to have a stand-alone binary file, which runs the MainLoop. This is just a test, to understand correctly how solarus works.

Here is my basic main:


int main()
{
std::vector<std::string> arguments = {"","./quest"};
std::vector<char*> argv;

for (const auto& arg : arguments)
    argv.push_back((char*)arg.data());
argv.push_back(nullptr);

const Arguments args(argv.size() - 1, argv.data());   
MainLoop(args).run();

return 0;
}


My quest folder is on same level as binary file. I am using solarus trunk library version (1.6.0), which I compiled without any issue.

Also, if I open my quest with solarus editor, editor runs it without any problem (it's just a basic, clean, quest).

When I run my binary looks like it detects the quest, but I obtain a segfault when it tries to open it.

Here is my output:

./solarus
[Solarus] [0] Info: Solarus 1.6.0
[Solarus] [0] Info: Opening quest './quest'
Segmentation fault: 11


I'm running everything on MacOS and compiled with g++.

Thank you very much for your help.

Best,
mdb

When you do argv.push_back(nullptr), there is a good chance that your arguments vector gets reallocated so the arg.data() pointers are no longer valid.

Thanks Christopho,

yes, you are right: when I add a nullptr to the end, pointers realocated to the end of the array, which seems is ok.

If I don't add the nullptr, args. parsing fails (doesn't locate quest path). Some traces:


std::vector<std::string> arguments = {"","./quest"};
std::vector<char*> argv;

for (const auto& arg : arguments)
    argv.push_back((char*)arg.data());

cout << argv.data() << endl;
argv.push_back(nullptr);
cout << argv.data() << endl;

cout << argv[0] << endl;
cout << argv[1] << endl;

const Arguments args(argv.size() - 1, argv.data());   
MainLoop(args).run();


And the output is:


0x7fd09340e2a0
0x7fd093412b90

./quest
[Solarus] [0] Info: Solarus 1.6.0
[Solarus] [0] Info: Opening quest './quest'
Segmentation fault: 11


If I comment "argv.push_back(nullptr);" line, I get:


0x7fe0b650b560
0x7fe0b650b560

./quest
[Solarus] [0] Info: Solarus 1.6.0
[Solarus] [0] Info: Opening quest '.'                        <---- ??
[Solarus] [0] Error: No quest was found in the directory '.' <---- ??


We need the nullptr to determine end of argv. Without it, it cannot find path to quest. Is this assumption right?

If so, where is the segfault?


Just create an empty Argument object and then use add_argument to add them. You don't have to mess with char* pointers.

I think issue is somewhere else... Route is detected fine, just as with char pointers, but still getting segfault.


Arguments args;
string quest_path("./quest");
cout << quest_path << endl;
args.add_argument(quest_path); 
MainLoop(args).run();

return 0;


Output:

./quest
[Solarus] [0] Info: Solarus 1.6.0
[Solarus] [0] Info: Opening quest './quest'
Segmentation fault: 11


I will review how quests are loaded.

Can you run a debugger to get a backtrace and know more about the crash?

Oooook. Found the issue! Thank you very much for the support.

When running lldb, I get:

Process 20088 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x24)
    frame #0: 0x00007fff04c4d103 libluajit-5.1.2.dylib`___lldb_unnamed_symbol112$$libluajit-5.1.2.dylib + 20
libluajit-5.1.2.dylib`___lldb_unnamed_symbol112$$libluajit-5.1.2.dylib:
->  0x7fff04c4d103 <+20>: movl   0x24(%rbp), %r15d
    0x7fff04c4d107 <+24>: subl   0x18(%rbp), %r15d
    0x7fff04c4d10b <+28>: movl   $0x0, 0x14(%rsp)
    0x7fff04c4d113 <+36>: movl   %r15d, 0x10(%rsp)


So, I found this thread:
https://github.com/pllua/pllua/issues/18

Adding "-pagezero_size 10000 -image_base 100000000" to my LDFLAGS solve the issue.

Thank you very much for your support!

Best,
mdb

October 13, 2017, 10:15:48 AM #7 Last Edit: October 13, 2017, 10:56:39 AM by vlag
Sorry I'm late :)

Yes this ldflag is needed when you build a 64bit application against LuaJIT on OSX, it is described on the official installation page.
However I handle this flag in the OSX-related cmake file, could you just tell me how you've built the engine to check if this is a bug or not ?


Best regards.

Thank you very much vlag.

I have attached screenshots of my cmake configuration. Lua Jit + OSX_64.



But, I think is not and issue of Solarus code, but mine. I just create an example, compiled agains Solarus lib, with my own Makefile.

If I run solarus-run from original branch, it runs the quest without any issue.

So, I think, is not a solarus engine bug, but my code.