From 61b4c20f2ee9462d63306ccd8b36b09f9e39367e Mon Sep 17 00:00:00 2001 From: nekobit Date: Thu, 13 Oct 2022 02:35:35 +0000 Subject: [PATCH] FINALLY fixed the memleak root cause, for good FossilOrigin-Name: c7f650b4f4efaf66ad769919f2277c46345b79337058a13db732c0d8770e625c --- perl/icons.pm | 2 ++ perl/main.pl | 23 ++++++++------ perl/string_helpers.pm | 2 ++ src/about.c | 7 ++-- src/base_page.c | 23 ++++---------- src/global_perl.h | 14 +++++--- src/notifications.c | 2 +- src/query.c | 72 +++++++++++++++++++++--------------------- src/timeline.c | 4 +-- 9 files changed, 76 insertions(+), 73 deletions(-) diff --git a/perl/icons.pm b/perl/icons.pm index c0cfd39..7243d4f 100644 --- a/perl/icons.pm +++ b/perl/icons.pm @@ -1,6 +1,7 @@ package icons; use strict; use warnings; +use Scalar::Util 'looks_like_number'; use Exporter 'import'; @@ -57,6 +58,7 @@ sub visibility_to_icon { # I thought of an array, but I don't want to call get_icon UNLESS # we know the visibility + return unless looks_like_number($_[0]); my $vis = $_[0]; return get_icon('public') if $vis == 1; diff --git a/perl/main.pl b/perl/main.pl index db7e643..274cb8f 100644 --- a/perl/main.pl +++ b/perl/main.pl @@ -16,14 +16,10 @@ use config; use embed; use meta; use login; +# use Devel::Leak; -# my $template = Template->new( -# { -# INTERPOLATE => 1, -# POST_CHOMP => 1, -# EVAL_PERL => 1, -# TRIM => 1 -# }); +# my $handle; +# Devel::Leak::NoteSV($handle); sub base_page { @@ -48,8 +44,15 @@ sub base_page ); my $ret = to_template(\%vars, \$data->{'main.tt'}); - undef($notifs); - undef($main); - undef($ssn); + +# leaky_friend(); + return $ret; } + +# sub leaky_friend +# { +# $count = Devel::Leak::CheckSV($handle); +# my $leakstr = "Memory: $count SVs\n"; +# print STDERR $leakstr; +# } diff --git a/perl/string_helpers.pm b/perl/string_helpers.pm index 09fdf4b..20e7bb1 100644 --- a/perl/string_helpers.pm +++ b/perl/string_helpers.pm @@ -2,6 +2,7 @@ package string_helpers; use strict; use warnings; use Exporter 'import'; +use Scalar::Util 'looks_like_number'; our @EXPORT = qw( reltime_to_str greentextify emojify format_username get_mentions_from_content localize_mentions simple_escape random_error_kaomoji ); @@ -9,6 +10,7 @@ my $re_mentions = '(?=session ? page->session : perlify_session(ssn); - XPUSHs(sv_2mortal(newRV_noinc((SV*)real_ssn))); - - XPUSHs(sv_2mortal(newRV_inc((SV*)template_files))); - SV* content = newSVpv(page->content, 0); - XPUSHs(sv_2mortal(content)); + HV* real_ssn = page->session ? page->session : perlify_session(ssn); + mXPUSHs(newRV_noinc((SV*)real_ssn)); + mXPUSHs(newRV_inc((SV*)template_files)); + mXPUSHs(newSVpv(page->content, 0)); if (notifs && notifs_len) { - XPUSHs(sv_2mortal(pl_notifs_rv)); + mXPUSHs(newRV_noinc(perlify_notifications(notifs, notifs_len))); } else ARG_UNDEFINED(); // Run function PERL_STACK_SCALAR_CALL("base_page"); char* dup = PERL_GET_STACK_EXIT; + send_result(req, NULL, "text/html", dup, 0); - - /* av_clear(pl_notifs); */ - /* av_undef(pl_notifs); */ - /* sv_free(pl_notifs_rv); */ - //hv_undef(real_ssn); - //sv_free(content); mstdnt_cleanup_notifications(notifs, notifs_len); mastodont_storage_cleanup(&storage); - free(dup); + Safefree(dup); } void send_result(FCGX_Request* req, char* status, char* content_type, char* data, size_t data_len) diff --git a/src/global_perl.h b/src/global_perl.h index 7c23ad6..563d4ac 100644 --- a/src/global_perl.h +++ b/src/global_perl.h @@ -22,10 +22,15 @@ #include #include -// hv_stores(ssn_hv, "id", newSVpv(acct->id, 0)); -#define hvstores_str(hv, key, val) if (val) { hv_stores((hv), key, Perl_newSVpv_share(aTHX_ (val), 0)); } +// hv_stores(ssn_hv, "id", newSVpv(acct->id, 0)); +// TODO use sv_usepvn_flags soon +#define hvstores_str(hv, key, val) if ((val)) { hv_stores((hv), key, newSVpvn((val), strlen(val))); } #define hvstores_int(hv, key, val) hv_stores((hv), key, newSViv((val))) -#define hvstores_ref(hv, key, val) if (val) { hv_stores((hv), key, newRV_noinc((SV*)(val))); } +#define hvstores_ref(hv, key, val) if (1) { \ + SV* tmp = (SV*)(val); \ + if (tmp) \ + hv_stores((hv), key, newRV_noinc(tmp)); \ + } /* Seeing all this shit littered in Treebird's code made me decide to write some macros */ #define PERL_STACK_INIT perl_lock(); \ @@ -48,8 +53,9 @@ #define PERLIFY_MULTI(type, types, mstype) AV* perlify_##types(const struct mstype* const types, size_t len) { \ if (!(types && len)) return NULL; \ AV* av = newAV(); \ + av_extend(av, len-1); \ for (size_t i = 0; i < len; ++i) \ - av_push(av, newRV_noinc((SV*)perlify_##type(types + i))); \ + av_store(av, i, newRV_noinc((SV*)perlify_##type(types + i))); \ return av; \ } diff --git a/src/notifications.c b/src/notifications.c index 2cf923f..fc62364 100644 --- a/src/notifications.c +++ b/src/notifications.c @@ -58,7 +58,7 @@ void content_notifications(PATH_ARGS) PERL_STACK_INIT; HV* session_hv = perlify_session(ssn); - XPUSHs(newRV_noinc((SV*)session_hv)); + mXPUSHs(newRV_inc((SV*)session_hv)); mXPUSHs(newRV_inc((SV*)template_files)); if (notifs) mXPUSHs(newRV_noinc((SV*)perlify_notifications(notifs, notifs_len))); diff --git a/src/query.c b/src/query.c index 3763536..8eb46e6 100644 --- a/src/query.c +++ b/src/query.c @@ -276,42 +276,42 @@ HV* perlify_post_values(struct post_values* post) HV* ssn_post_hv = newHV(); // This ugly... - hv_stores(ssn_post_hv, "theme", newSVpv(keystr(post->theme), 0)); - hv_stores(ssn_post_hv, "themeclr", newSViv(keyint(post->themeclr))); - hv_stores(ssn_post_hv, "lang", newSViv(keyint(post->lang))); - hv_stores(ssn_post_hv, "title", newSViv(keyint(post->title))); - hv_stores(ssn_post_hv, "jsactions", newSViv(keyint(post->jsactions))); - hv_stores(ssn_post_hv, "jsreply", newSViv(keyint(post->jsreply))); - hv_stores(ssn_post_hv, "jslive", newSViv(keyint(post->jslive))); - hv_stores(ssn_post_hv, "js", newSViv(keyint(post->js))); - hv_stores(ssn_post_hv, "interact_img", newSViv(keyint(post->interact_img))); - hv_stores(ssn_post_hv, "stat_attachments", newSViv(keyint(post->stat_attachments))); - hv_stores(ssn_post_hv, "stat_greentexts", newSViv(keyint(post->stat_greentexts))); - hv_stores(ssn_post_hv, "stat_dope", newSViv(keyint(post->stat_dope))); - hv_stores(ssn_post_hv, "stat_oneclicksoftware", newSViv(keyint(post->stat_oneclicksoftware))); - hv_stores(ssn_post_hv, "stat_emojo_likes", newSViv(keyint(post->stat_emojo_likes))); - hv_stores(ssn_post_hv, "stat_hide_muted", newSViv(keyint(post->stat_hide_muted))); - hv_stores(ssn_post_hv, "instance_show_shoutbox", newSViv(keyint(post->instance_show_shoutbox))); - hv_stores(ssn_post_hv, "instance_panel", newSViv(keyint(post->instance_panel))); - hv_stores(ssn_post_hv, "notif_embed", newSViv(keyint(post->notif_embed))); - hv_stores(ssn_post_hv, "set", newSViv(keyint(post->set))); - hv_stores(ssn_post_hv, "only_media", newSViv(keyint(post->only_media))); - hv_stores(ssn_post_hv, "replies_only", newSViv(keyint(post->replies_only))); - hv_stores(ssn_post_hv, "replies_policy", newSViv(keyint(post->replies_policy))); - hv_stores(ssn_post_hv, "emojoindex", newSViv(keyint(post->emojoindex))); - hv_stores(ssn_post_hv, "sidebar_opacity", newSViv(keyint(post->sidebar_opacity))); - hv_stores(ssn_post_hv, "file_ids", newSVpv(keystr(post->file_ids), 0)); - hv_stores(ssn_post_hv, "content", newSVpv(keystr(post->content), 0)); - hv_stores(ssn_post_hv, "itype", newSVpv(keystr(post->itype), 0)); - hv_stores(ssn_post_hv, "id", newSVpv(keystr(post->id), 0)); - hv_stores(ssn_post_hv, "username", newSVpv(keystr(post->username), 0)); - hv_stores(ssn_post_hv, "password", newSVpv(keystr(post->password), 0)); - hv_stores(ssn_post_hv, "replyid", newSVpv(keystr(post->replyid), 0)); - hv_stores(ssn_post_hv, "visibility", newSVpv(keystr(post->visibility), 0)); - hv_stores(ssn_post_hv, "instance", newSVpv(keystr(post->instance), 0)); - hv_stores(ssn_post_hv, "min_id", newSVpv(keystr(post->min_id), 0)); - hv_stores(ssn_post_hv, "max_id", newSVpv(keystr(post->max_id), 0)); - hv_stores(ssn_post_hv, "start_id", newSVpv(keystr(post->start_id), 0)); + /* hv_stores(ssn_post_hv, "theme", newSVpv(keystr(post->theme), 0)); */ + /* hv_stores(ssn_post_hv, "themeclr", newSViv(keyint(post->themeclr))); */ + /* hv_stores(ssn_post_hv, "lang", newSViv(keyint(post->lang))); */ + /* hv_stores(ssn_post_hv, "title", newSViv(keyint(post->title))); */ + /* hv_stores(ssn_post_hv, "jsactions", newSViv(keyint(post->jsactions))); */ + /* hv_stores(ssn_post_hv, "jsreply", newSViv(keyint(post->jsreply))); */ + /* hv_stores(ssn_post_hv, "jslive", newSViv(keyint(post->jslive))); */ + /* hv_stores(ssn_post_hv, "js", newSViv(keyint(post->js))); */ + /* hv_stores(ssn_post_hv, "interact_img", newSViv(keyint(post->interact_img))); */ + /* hv_stores(ssn_post_hv, "stat_attachments", newSViv(keyint(post->stat_attachments))); */ + /* hv_stores(ssn_post_hv, "stat_greentexts", newSViv(keyint(post->stat_greentexts))); */ + /* hv_stores(ssn_post_hv, "stat_dope", newSViv(keyint(post->stat_dope))); */ + /* hv_stores(ssn_post_hv, "stat_oneclicksoftware", newSViv(keyint(post->stat_oneclicksoftware))); */ + /* hv_stores(ssn_post_hv, "stat_emojo_likes", newSViv(keyint(post->stat_emojo_likes))); */ + /* hv_stores(ssn_post_hv, "stat_hide_muted", newSViv(keyint(post->stat_hide_muted))); */ + /* hv_stores(ssn_post_hv, "instance_show_shoutbox", newSViv(keyint(post->instance_show_shoutbox))); */ + /* hv_stores(ssn_post_hv, "instance_panel", newSViv(keyint(post->instance_panel))); */ + /* hv_stores(ssn_post_hv, "notif_embed", newSViv(keyint(post->notif_embed))); */ + /* hv_stores(ssn_post_hv, "set", newSViv(keyint(post->set))); */ + /* hv_stores(ssn_post_hv, "only_media", newSViv(keyint(post->only_media))); */ + /* hv_stores(ssn_post_hv, "replies_only", newSViv(keyint(post->replies_only))); */ + /* hv_stores(ssn_post_hv, "replies_policy", newSViv(keyint(post->replies_policy))); */ + /* hv_stores(ssn_post_hv, "emojoindex", newSViv(keyint(post->emojoindex))); */ + /* hv_stores(ssn_post_hv, "sidebar_opacity", newSViv(keyint(post->sidebar_opacity))); */ + /* hv_stores(ssn_post_hv, "file_ids", newSVpv(keystr(post->file_ids), 0)); */ + /* hv_stores(ssn_post_hv, "content", newSVpv(keystr(post->content), 0)); */ + /* hv_stores(ssn_post_hv, "itype", newSVpv(keystr(post->itype), 0)); */ + /* hv_stores(ssn_post_hv, "id", newSVpv(keystr(post->id), 0)); */ + /* hv_stores(ssn_post_hv, "username", newSVpv(keystr(post->username), 0)); */ + /* hv_stores(ssn_post_hv, "password", newSVpv(keystr(post->password), 0)); */ + /* hv_stores(ssn_post_hv, "replyid", newSVpv(keystr(post->replyid), 0)); */ + /* hv_stores(ssn_post_hv, "visibility", newSVpv(keystr(post->visibility), 0)); */ + /* hv_stores(ssn_post_hv, "instance", newSVpv(keystr(post->instance), 0)); */ + /* hv_stores(ssn_post_hv, "min_id", newSVpv(keystr(post->min_id), 0)); */ + /* hv_stores(ssn_post_hv, "max_id", newSVpv(keystr(post->max_id), 0)); */ + /* hv_stores(ssn_post_hv, "start_id", newSVpv(keystr(post->start_id), 0)); */ return ssn_post_hv; } diff --git a/src/timeline.c b/src/timeline.c index ab4293b..b5cf850 100644 --- a/src/timeline.c +++ b/src/timeline.c @@ -43,8 +43,8 @@ void content_timeline(REQUEST_T req, { PERL_STACK_INIT; HV* session_hv = perlify_session(ssn); - XPUSHs(newRV_noinc((SV*)session_hv)); - XPUSHs(newRV_noinc((SV*)template_files)); + mXPUSHs(newRV_inc((SV*)session_hv)); + mXPUSHs(newRV_inc((SV*)template_files)); if (statuses) mXPUSHs(newRV_noinc((SV*)perlify_statuses(statuses, statuses_len)));