nodegit / nodegit/nodegit

nodegit crash when trying to use Submodule.foreach

Ouverte
#925 14 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Bug
Langage dominant
JavaScript
Étoiles
5.8k
Forks
704
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

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.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Reproduisez le crash avec Submodule.foreach suivi de submodule.init et submodule.update sur les versions de Windows et nodegit fournies, puis comparez ce chemin avec Repository.getSubmoduleNames et Submodule.lookup. Inspectez le binding de Submodule.foreach et vendor/libgit2/src/repository.c à la ligne 2111 ; le travail est terminé lorsque l’opération reproduite ne fait plus crasher le processus Node.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
javascript, nodejs
Domaine
api, backend
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.