Skip to content

Commit f115eb8

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 85f78b7 commit f115eb8

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

@@ -1668,7 +1668,7 @@ namespace Sass {
16681668
return str_quoted;
16691669
}
16701670

1671-
String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate);
1671+
String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
16721672
schema->is_interpolant(true);
16731673
while (i < chunk.end) {
16741674
p = constant ? find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end) :
@@ -1704,7 +1704,7 @@ namespace Sass {
17041704
++ i;
17051705
}
17061706

1707-
return schema;
1707+
return schema.detach();
17081708
}
17091709

17101710
String_Constant_Obj Parser::parse_static_value()

0 commit comments

Comments
 (0)