nodegit crash when trying to use Submodule.foreach
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 5.8k
- Forks
- 704
- PR merge metrics
- No merged PRs in 30d
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the crash with Submodule.foreach followed by submodule.init and submodule.update on the supplied Windows and nodegit versions, then compare that path with Repository.getSubmoduleNames and Submodule.lookup. Inspect the Submodule.foreach binding and vendor/libgit2/src/repository.c at line 2111; done means the reproduced operation no longer crashes the Node process.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, nodejs
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100