Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kernel: fix mem leaks #951

Merged
merged 1 commit into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions etc/tst-local-vars.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
"""
TODO
This simple script adds the local variables used in a GAP tst file to the top
of the file.
"""
import os
import re
Expand All @@ -24,10 +25,7 @@ def main():
lvars.extend([x.group(1) for x in re.finditer(pattern1, lines)])
lvars.extend([x.group(1) for x in re.finditer(pattern2, lines)])
lvars = ", ".join(sorted([*{*lvars}]))
lvars = [
x if x[-1] != "," else x[:-1]
for x in textwrap.wrap(lvars, width=72)
]
lvars = [x if x[-1] != "," else x[:-1] for x in textwrap.wrap(lvars, width=72)]
lvars = [""] + ["#@local " + x for x in lvars]
lines = lines.split("\n")
pos = next(i for i in range(len(lines)) if "START_TEST" in lines[i])
Expand Down
49 changes: 49 additions & 0 deletions etc/tst-unbind-local-vars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env python3
"""
This simple script adds the "Unbind" statements to the end of a GAP tst file.
"""
import os
import re
import sys
import textwrap

import yaml
from bs4 import BeautifulSoup


def main():
if sys.version_info[0] < 3:
raise Exception("Python 3 is required")
args = sys.argv[1:]
pattern1 = re.compile(r"(\w+)\s*:=")
pattern2 = re.compile(r"for (\w+) in")
for fname in args:
lvars = []
with open(fname, "r") as f:
lines = f.read()
lvars.extend([x.group(1) for x in re.finditer(pattern1, lines)])
lvars.extend([x.group(1) for x in re.finditer(pattern2, lines)])
lvars = sorted([*{*lvars}])
lvars = [
"# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py"
] + [f"gap> Unbind({lvar});" for lvar in lvars]
lvars.append("")
lines = lines.split("\n")
pos1 = next(i for i in range(len(lines)) if "STOP_TEST" in lines[i]) - 1
try:
pos0 = next(
i
for i in range(len(lines))
if "etc/tst-unbind-local-vars.py" in lines[i]
)
except StopIteration:
pos0 = pos1
lines = lines[:pos0] + lvars + lines[pos1:]
lines = "\n".join(lines)
with open(fname, "w") as f:
print(f"Writing local variables to {fname}...")
f.write(lines)


if __name__ == "__main__":
main()
11 changes: 7 additions & 4 deletions gapbind14/include/gapbind14/gapbind14.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@ namespace gapbind14 {
: SubtypeBase(nm, sbtyp) {}

void free(Obj o) override {
static_assert(IsGapBind14Type<T>::value,
"template parameter T must satisfy IsGapbind14Type<T>");
GAPBIND14_ASSERT(obj_subtype(o) == module().subtype<T>());
delete detail::obj_cpp_ptr<T>(o);
}
};
Expand Down Expand Up @@ -214,12 +217,12 @@ namespace gapbind14 {
_subtypes(),
_type_to_subtype() {}

Module(Module const&) = delete;
Module(Module&&) = delete;
Module(Module const&) = delete;
Module(Module&&) = delete;
Module& operator=(Module const&) = delete;
Module& operator=(Module&&) = delete;
Module& operator=(Module&&) = delete;

~Module() = default;
~Module();

void clear();

Expand Down
12 changes: 8 additions & 4 deletions gapbind14/include/gapbind14/to_cpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ namespace gapbind14 {

std::string operator()(Obj o) const {
if (TNUM_OBJ(o) != T_STRING) {
ErrorQuit("expected string, found %s", (Int) TNAM_OBJ(o), 0L);
throw std::runtime_error(std::string("expected string, found ")
+ TNAM_OBJ(o));
}
return std::string(CSTR_STRING(o), GET_LEN_STRING(o));
}
Expand All @@ -106,7 +107,8 @@ namespace gapbind14 {

Int operator()(Obj o) const {
if (TNUM_OBJ(o) != T_INT) {
ErrorQuit("expected int, found %s", (Int) TNAM_OBJ(o), 0L);
throw std::runtime_error(std::string("expected int, found ")
+ TNAM_OBJ(o));
}
return INT_INTOBJ(o);
}
Expand All @@ -123,7 +125,8 @@ namespace gapbind14 {

bool operator()(Obj o) const {
if (TNUM_OBJ(o) != T_BOOL) {
ErrorQuit("expected bool, found %s", (Int) TNAM_OBJ(o), 0L);
throw std::runtime_error(std::string("expected bool, found ")
+ TNAM_OBJ(o));
}
return o == True ? true : false;
}
Expand All @@ -140,7 +143,8 @@ namespace gapbind14 {

std::vector<T> operator()(Obj o) const {
if (!IS_LIST(o)) {
ErrorQuit("expected list, found %s", (Int) TNAM_OBJ(o), 0L);
throw std::runtime_error(std::string("expected list, found ")
+ TNAM_OBJ(o));
}

size_t const N = LEN_LIST(o);
Expand Down
34 changes: 28 additions & 6 deletions gapbind14/src/gapbind14.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

#include "gapbind14/gapbind14.hpp"

#include <stdio.h> // for fprintf, stderr
#include <string.h> // for memcpy, strchr, strrchr
//
#include <stdio.h> // for fprintf, stderr
#include <string.h> // for memcpy, strchr, strrchr

#include <unordered_set> // for unordered_set, unordered_set<>::iterator

#include "gapbind14/gap_include.hpp" // for Obj etc
Expand Down Expand Up @@ -93,10 +93,32 @@ namespace gapbind14 {

// Module implementations

Module::~Module() {
clear();
for (auto *subtype : _subtypes) {
delete subtype;
}
}

void Module::clear() {
for (auto &func : _funcs) {
delete func.name;
if (func.nargs != 0) {
delete func.args;
}
delete func.cookie;
}
_funcs.clear();
for (auto &funcs : _mem_funcs) {
funcs.clear();

for (auto &vec : _mem_funcs) {
for (auto &func : vec) {
delete func.name;
if (func.nargs != 0) {
delete func.args;
}
delete func.cookie;
}
vec.clear();
}
}

Expand Down Expand Up @@ -266,7 +288,7 @@ namespace gapbind14 {
first_call = false;
InitGVarFuncsFromTable(GVarFuncs);
}
auto & m = module();
auto &m = module();
StructGVarFunc const *tab = m.funcs();

// init functions from m in the record named name
Expand Down
50 changes: 50 additions & 0 deletions tst/standard/attributes/homomorph.tst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
##
#############################################################################
##

## We don't use local variables in this test file because it doesn't play nice
## with something in this test file.

#
gap> START_TEST("Semigroups package: standard/attributes/homomorph.tst");
gap> LoadPackage("semigroups", false);;

Expand Down Expand Up @@ -1079,6 +1084,51 @@ gap> hom2 := SemigroupHomomorphismByImages(S, S, GeneratorsOfSemigroup(S),
gap> hom1 = hom2;
false

# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py
gap> Unbind(BruteForceHomoCheck);
gap> Unbind(BruteForceInverseCheck);
gap> Unbind(BruteForceIsoCheck);
gap> Unbind(F);
gap> Unbind(J);
gap> Unbind(K);
gap> Unbind(S);
gap> Unbind(T);
gap> Unbind(U);
gap> Unbind(V);
gap> Unbind(acting);
gap> Unbind(cong);
gap> Unbind(congs);
gap> Unbind(g);
gap> Unbind(gens);
gap> Unbind(gens1);
gap> Unbind(gens2);
gap> Unbind(gens3);
gap> Unbind(gensS);
gap> Unbind(gensT);
gap> Unbind(gensU);
gap> Unbind(gensV);
gap> Unbind(h);
gap> Unbind(hom);
gap> Unbind(hom1);
gap> Unbind(hom1bf);
gap> Unbind(hom1bfbi);
gap> Unbind(hom2);
gap> Unbind(hom3);
gap> Unbind(images);
gap> Unbind(images1);
gap> Unbind(images2);
gap> Unbind(images3);
gap> Unbind(imgs);
gap> Unbind(imgs2);
gap> Unbind(inv);
gap> Unbind(iso);
gap> Unbind(j);
gap> Unbind(map);
gap> Unbind(relations);
gap> Unbind(x);
gap> Unbind(y);
gap> Unbind(z);

#
gap> SEMIGROUPS.StopTest();
gap> STOP_TEST("Semigroups package: standard/attributes/homomorph.tst");
24 changes: 19 additions & 5 deletions tst/standard/semigroups/semifp.tst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
##
#############################################################################
##

## We don't use local variables in this test file because it doesn't play nice
## with AssignGeneratorVariables, which is used repeatedly here.

gap> START_TEST("Semigroups package: standard/semigroups/semifp.tst");
gap> LoadPackage("semigroups", false);;

Expand Down Expand Up @@ -2666,23 +2670,33 @@ true
gap> IsSubsemigroupOfFpMonoid(Range(map));
true

# SEMIGROUPS_UnbindVariables
gap> Unbind(a);
gap> Unbind(b);
# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py
gap> Unbind(BruteForceInverseCheck);
gap> Unbind(BruteForceIsoCheck);
gap> Unbind(f);
gap> Unbind(F);
gap> Unbind(G);
gap> Unbind(LoopIterator);
gap> Unbind(Noop);
gap> Unbind(R);
gap> Unbind(S);
gap> Unbind(T);
gap> Unbind(TestEnumerator);
gap> Unbind(TestIterator);
gap> Unbind(a);
gap> Unbind(b);
gap> Unbind(f);
gap> Unbind(factorizable);
gap> Unbind(inv);
gap> Unbind(iso);
gap> Unbind(len);
gap> Unbind(map);
gap> Unbind(rels);
gap> Unbind(s);
gap> Unbind(tst);
gap> Unbind(valid);
gap> Unbind(w);
gap> Unbind(x);
gap> Unbind(y);

#
gap> SEMIGROUPS.StopTest();
gap> STOP_TEST("Semigroups package: standard/semigroups/semifp.tst");
8 changes: 7 additions & 1 deletion tst/standard/tools/display.tst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
##
#############################################################################
##

## We don't use local variables in this test file because it doesn't play nice
## with something in this test file.

#
gap> START_TEST("Semigroups package: standard/tools/display.tst");
gap> LoadPackage("semigroups", false);;

Expand Down Expand Up @@ -1025,7 +1030,8 @@ gap> TikzRightCayleyDigraph(S);
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 2nd choice method found for `TikzString' on 1 arguments

# SEMIGROUPS_UnbindVariables
# Unbind local variables, auto-generated by etc/tst-unbind-local-vars.py
gap> Unbind(S);
gap> Unbind(x);
gap> Unbind(y);

Expand Down