Skip to content

Crash when saving and loading snapshots #111

Closed
@harryr0se

Description

@harryr0se

Hey, thanks for the library it's great!

Unfortunately I'm getting a reproducible error when trying to use the snapshot feature. I've managed to create a minimal reproduction
I'm unsure if this is a bug in inkcpp or my code, any guidance would be great

#include <filesystem>
#include <inkcpp/include/story.h>
#include <inkcpp/include/globals.h>
#include <inkcpp/include/runner.h>
#include <inkcpp/include/snapshot.h>

int main()
{
    try
    {
        auto story = ink::runtime::story::from_file("path/to/game.ink.bin");
        printf("Loaded Story\n");

        ink::runtime::runner runner;
        auto savePath = "suitable/path/for/save.bin";
        if (std::filesystem::exists(savePath))
        {
            auto snap = ink::runtime::snapshot::from_file(savePath);
            runner = story->new_runner_from_snapshot(*snap);
        }
        else
            runner = story->new_runner();

       if (runner->can_continue())
        {
            auto basic_string = runner->getline();
            printf("Stepping story once: %s\n", basic_string.c_str());
        }
        else if (runner->has_choices())
        {
            for (const auto& choice : *runner)
                printf("* %s\n", choice.text());
        }

        auto snap = runner->create_snapshot();
        snap->write_to_file(savePath);
    }
    catch (std::runtime_error exception)
    {
        printf("Ink exception: %s\n", exception.what());
    }

    printf("Exiting\n");
    return 0;
}

With the following ink file

VAR test = false

-> start

=== start ===
First line of text
Second line of test

* Choice
~ test = true
* Choice

- end

-> END

Steps to reproduce:

  1. Point the story path to the compiled version of the ink above
  2. Update the path to the save.bin
  3. Compile and run the program once, it will create a snapshot of the story one step in and save it to disk
  4. Run the program again
  5. Observe it either crashing or throwing an exception

The crash seems to occur in story_impl::container_flag

It appears that offset is invalid memory

CommandFlag story_impl::container_flag(ip_t offset) const
{
	inkAssert(
	    (static_cast<Command>(offset[0]) == Command::START_CONTAINER_MARKER
	     || static_cast<Command>(offset[0]) == Command::END_CONTAINER_MARKER),
	    "Tried to fetch container flag from non container command!"
	);
	return static_cast<CommandFlag>(offset[1]);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions