Skip to content

Commit 4bf831e

Browse files
committed
Fix memory leak and internal leak detector
Media_Blocks are prone to have circular references. Copy could leak memory if it does not get picked up. Looks like we are able to reset block reference for copy Good as it will ensure a low memory overhead for this fix So this is a cheap solution with a minimal price
1 parent 2d679a1 commit 4bf831e

File tree

6 files changed

+19
-9
lines changed

6 files changed

+19
-9
lines changed

src/context.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ namespace Sass {
6767
plugins(),
6868
emitter(c_options),
6969

70+
ast_gc(),
7071
strings(),
7172
resources(),
7273
sheets(),

src/context.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ namespace Sass {
4343
Plugins plugins;
4444
Output emitter;
4545

46+
// generic ast node garbage container
47+
// used to avoid possible circular refs
48+
std::vector<AST_Node_Obj> ast_gc;
4649
// resources add under our control
4750
// these are guaranteed to be freed
4851
std::vector<char*> strings;

src/expand.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,13 @@ namespace Sass {
176176

177177
Statement_Ptr Expand::operator()(Media_Block_Ptr m)
178178
{
179-
Media_Block_Ptr cpy = m->copy();
179+
Media_Block_Obj cpy = SASS_MEMORY_COPY(m);
180+
// Media_Blocks are prone to have circular references
181+
// Copy could leak memory if it does not get picked up
182+
// Looks like we are able to reset block reference for copy
183+
// Good as it will ensure a low memory overhead for this fix
184+
// So this is a cheap solution with a minimal price
185+
ctx.ast_gc.push_back(cpy); cpy->block(0);
180186
Expression_Obj mq = eval(m->media_queries());
181187
std::string str_mq(mq->to_string(ctx.c_options));
182188
char* str = sass_copy_c_string(str_mq.c_str());

src/memory/SharedPtr.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ namespace Sass {
1717
std::cerr << "###################################\n";
1818
std::cerr << "# REPORTING MISSING DEALLOCATIONS #\n";
1919
std::cerr << "###################################\n";
20-
for (auto var : all) {
21-
if (AST_Node_Ptr ast = Cast<AST_Node>(var)) {
20+
for (SharedObj* var : all) {
21+
if (AST_Node_Ptr ast = dynamic_cast<AST_Node*>(var)) {
2222
debug_ast(ast);
2323
} else {
2424
std::cerr << "LEAKED " << var << "\n";
@@ -60,7 +60,7 @@ namespace Sass {
6060
#endif
6161
if (node->refcounter == 0) {
6262
#ifdef DEBUG_SHARED_PTR
63-
AST_Node_Ptr ptr = Cast<AST_Node>(node);
63+
// AST_Node_Ptr ast = dynamic_cast<AST_Node*>(node);
6464
if (node->dbg) std::cerr << "DELETE NODE " << node << "\n";
6565
#endif
6666
if (!node->detached) {

src/memory/SharedPtr.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace Sass {
1717
#ifdef DEBUG_SHARED_PTR
1818

1919
#define SASS_MEMORY_NEW(Class, ...) \
20-
((new Class(__VA_ARGS__))->trace(__FILE__, __LINE__)) \
20+
((Class*)(new Class(__VA_ARGS__))->trace(__FILE__, __LINE__)) \
2121

2222
#define SASS_MEMORY_COPY(obj) \
2323
((obj)->copy(__FILE__, __LINE__)) \

src/parser.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ namespace Sass {
541541
// selector schema re-uses string schema implementation
542542
String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate);
543543
// the selector schema is pretty much just a wrapper for the string schema
544-
Selector_Schema_Ptr selector_schema = SASS_MEMORY_NEW(Selector_Schema, pstate, schema);
544+
Selector_Schema_Obj selector_schema = SASS_MEMORY_NEW(Selector_Schema, pstate, schema);
545545
selector_schema->connect_parent(chroot == false);
546546
selector_schema->media_block(last_media_block);
547547

@@ -605,7 +605,7 @@ namespace Sass {
605605
after_token = before_token = pstate;
606606

607607
// return parsed result
608-
return selector_schema;
608+
return selector_schema.detach();
609609
}
610610
// EO parse_selector_schema
611611

@@ -1647,7 +1647,7 @@ namespace Sass {
16471647
return str_quoted;
16481648
}
16491649

1650-
String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate);
1650+
String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
16511651
schema->is_interpolant(true);
16521652
while (i < chunk.end) {
16531653
p = constant ? find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end) :
@@ -1683,7 +1683,7 @@ namespace Sass {
16831683
++ i;
16841684
}
16851685

1686-
return schema;
1686+
return schema.detach();
16871687
}
16881688

16891689
String_Constant_Obj Parser::parse_static_value()

0 commit comments

Comments
 (0)