diff contrib/fuzz/manifest.cc @ 40373:c3ab0a89331d

fuzz: move many initialization steps into LLVMFuzzerInitialize Doing this means that things we intentionally leak (eg type objects) no longer confuse AddressSanitizer, so now we can run the fuzzer MUCH longer. Differential Revision: https://phab.mercurial-scm.org/D5154
author Augie Fackler <augie@google.com>
date Thu, 18 Oct 2018 16:36:10 -0400
parents 170cd2a5a1da
children ef103c96ed33
line wrap: on
line diff
--- a/contrib/fuzz/manifest.cc	Thu Nov 17 15:51:33 2016 -0800
+++ b/contrib/fuzz/manifest.cc	Thu Oct 18 16:36:10 2018 -0400
@@ -12,6 +12,10 @@
 
 static char cpypath[8192] = "\0";
 
+static PyCodeObject *code;
+static PyObject *mainmod;
+static PyObject *globals;
+
 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
 {
 	const std::string subdir = "/sanpy/lib/python2.7";
@@ -35,20 +39,8 @@
 	setenv("PYTHONUSERBASE", cpypath, 1);
 	Py_SetPythonHome(cpypath);
 	Py_InitializeEx(0);
-	return 0;
-}
-
-int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
-{
 	initparsers();
-	PyObject *mtext =
-	    PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
-	PyObject *mainmod = PyImport_AddModule("__main__");
-	PyObject *globals = PyModule_GetDict(mainmod);
-	PyObject *locals = PyDict_New();
-	PyDict_SetItemString(locals, "mdata", mtext);
-	PyCodeObject *code =
-	    (PyCodeObject *)Py_CompileString(R"py(
+	code = (PyCodeObject *)Py_CompileString(R"py(
 from parsers import lazymanifest
 try:
   lm = lazymanifest(mdata)
@@ -67,13 +59,23 @@
   # to debug failures.
   # print e
 )py",
-	                                     "fuzzer", Py_file_input);
+	                                        "fuzzer", Py_file_input);
+	mainmod = PyImport_AddModule("__main__");
+	globals = PyModule_GetDict(mainmod);
+	return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
+{
+	PyObject *mtext =
+	    PyBytes_FromStringAndSize((const char *)Data, (Py_ssize_t)Size);
+	PyObject *locals = PyDict_New();
+	PyDict_SetItemString(locals, "mdata", mtext);
 	PyObject *res = PyEval_EvalCode(code, globals, locals);
 	if (!res) {
 		PyErr_Print();
 	}
 	Py_XDECREF(res);
-	Py_DECREF(code);
 	Py_DECREF(locals);
 	Py_DECREF(mtext);
 	return 0; // Non-zero return values are reserved for future use.