Skip to content

nodegit crash when trying to use Submodule.foreach #925

Open
@tylerchurch

Description

@tylerchurch

I was trying to use nodegit to do a recursive clone, but was getting crashes left and right and couldn't figure out what was going on. I've found a workaround, but wanted to report the crash here.

As far as I can tell, if I used Submodule.foreach to iterate over the submodules and then call submodule.update, nodegit crashes the node process, and I get an error message popup that looks like this:

Microsoft Visual C++ Runtime Library
Assertion failed!

Program: ...re\node_modules\nodegit\build\Release\nodegit.node
File: ..\..\vendor\libgit2\src\repository.c
Line: 2111

Expression: repo && id

For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.

( Here's a link to an image of the screenshot: https://dl.dropboxusercontent.com/u/108847970/nodegit-crash-screenshot.png )

These's are the versions I'm running:

  • Windows 10 (x64)
  • nodejs 4.2.3 (x64)
  • nodegit 0.11.5

Here's some sample code that reproduces the issue for me:

var path = require("path");

var mkdirp = require("mkdirp");
var rimraf = require("rimraf");
var git = require("nodegit");
var reposPath = path.join(__dirname, "cloned-repos");
var repoPath = path.join(reposPath, "electron");
var cloneUrl = "https://github.com/atom/electron";

rimraf(reposPath, function (err) {
    if (err) {
        throw err;
    }
    mkdirp(reposPath, function (err) {
        if (err) {
            throw err;
        }

        console.log("Cloning '" + cloneUrl + "'...");

        git.Clone.clone(cloneUrl, repoPath, new git.CloneOptions()).then(function () {
            console.log("Cloned successfully!");

            git.Repository.open(repoPath)
                .then(function(repo) {
                    var p = Promise.resolve();

                    git.Submodule.foreach(repo, function(submodule) {
                        var name = submodule.name();
                        console.log("Found submodule: " + name);

                        p = p.then(
                            function() {
                                return new Promise(function(resolve, reject) {
                                    submodule.init(1).then(
                                        function() {
                                            console.log("Init success on " + name);

                                            submodule.update(1, new git.SubmoduleUpdateOptions()).then(
                                                function () {
                                                    console.log("Update success on " + name);
                                                    resolve();
                                                },
                                                reject
                                            );
                                        }, reject
                                    );
                                });
                            }
                        )
                    }).then(
                        function() {
                            console.log("Foreach is done.");

                            p.then(
                                function() {
                                    console.log("Everything is done.");
                                },
                                function(error) {
                                    console.error(error);
                                }
                            )
                        }
                    );
                });
        }, function (error) {
            console.error(error);
        });
    });
});

The workaround I discovered was that if I switch to using Repository.getSubmoduleNames and Submodule.lookup instead of Submodule.foreach, everything seems to work just fine.

Here's the sample code for that:

var path = require("path");

var mkdirp = require("mkdirp");
var rimraf = require("rimraf");
var git = require("nodegit");
var reposPath = path.join(__dirname, "cloned-repos");
var repoPath = path.join(reposPath, "electron");
var cloneUrl = "https://github.com/atom/electron";

rimraf(reposPath, function (err) {
    if (err) {
        throw err;
    }
    mkdirp(reposPath, function (err) {
        if (err) {
            throw err;
        }

        console.log("Cloning '" + cloneUrl + "'...");

        git.Clone.clone(cloneUrl, repoPath, new git.CloneOptions()).then(function () {
            console.log("Cloned successfully!");

            git.Repository.open(repoPath)
                .then(function(repo) {

                    repo.getSubmoduleNames().then(
                        function(names) {
                            console.log("Found the following submodules:");
                            console.log(names);

                            var p = Promise.resolve();

                            names.forEach(function(name) {
                                p = p.then(
                                    function() {
                                        return new Promise(function(resolve, reject) {
                                            git.Submodule.lookup(repo, name).then(
                                                function (submodule) {
                                                    submodule.init(1).then(
                                                        function() {
                                                            console.log("Init success on " + name);

                                                            submodule.update(1, new git.SubmoduleUpdateOptions()).then(
                                                                function () {
                                                                    console.log("Update success on " + name);
                                                                    resolve();
                                                                },
                                                                reject
                                                            );
                                                        }, reject
                                                    );
                                                }, reject
                                            );
                                        });
                                    }
                                )
                            });

                            return p;
                        }
                    ).then(
                        function() {
                            console.log("Done!");
                        },
                        function(error) {
                            console.error(error);
                        }
                    );
                });
        }, function (error) {
            console.error(error);
        });
    });
});

A zip of the files used in the above examples (including my compiled version of nodegit) is available here if that helps at all: https://dl.dropboxusercontent.com/u/108847970/nodegit-foreach-failure.zip

I had screen other crashes in the past when I was using Submodule.foreach as well, but I had never been able to identify the cause as being that specific function. Now I think that it was.

I would try to track down this issue to the source myself, but I have no idea where to even start on debugging this kind of thing 😛

Let me know if I can provide any other additional information.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions