Skip to content

Commit

Permalink
plugins: fix memory leak while parsing options
Browse files Browse the repository at this point in the history
It was hard to track down this leak as it was an internal allocation
by glib and the backtraces did not give much away. The autofree was
freeing the allocation with g_free() but not taking care of the
individual strings. They should have been freed with g_strfreev()
instead.

Searching the glib source code for the correct string free function
led to:

  G_DEFINE_AUTO_CLEANUP_FREE_FUNC(GStrv, g_strfreev, NULL)

and indeed if you read to the bottom of the documentation page you
will find:

  typedef gchar** GStrv;

  A typedef alias for gchar**. This is mostly useful when used together with g_auto().

So fix up all the g_autofree g_strsplit case that smugly thought they
had de-allocation covered.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20230630180423.558337-21-alex.bennee@linaro.org>
  • Loading branch information
stsquad committed Jul 3, 2023
1 parent 6d03226 commit 4025874
Show file tree
Hide file tree
Showing 12 changed files with 12 additions and 12 deletions.
2 changes: 1 addition & 1 deletion contrib/plugins/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,

for (i = 0; i < argc; i++) {
char *opt = argv[i];
g_autofree char **tokens = g_strsplit(opt, "=", 2);
g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);

if (g_strcmp0(tokens[0], "iblksize") == 0) {
l1_iblksize = STRTOLL(tokens[1]);
Expand Down
2 changes: 1 addition & 1 deletion contrib/plugins/drcov.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,
int argc, char **argv)
{
for (int i = 0; i < argc; i++) {
g_autofree char **tokens = g_strsplit(argv[i], "=", 2);
g_auto(GStrv) tokens = g_strsplit(argv[i], "=", 2);
if (g_strcmp0(tokens[0], "filename") == 0) {
file_name = g_strdup(tokens[1]);
}
Expand Down
2 changes: 1 addition & 1 deletion contrib/plugins/execlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,

for (int i = 0; i < argc; i++) {
char *opt = argv[i];
g_autofree char **tokens = g_strsplit(opt, "=", 2);
g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);
if (g_strcmp0(tokens[0], "ifilter") == 0) {
parse_insn_match(tokens[1]);
} else if (g_strcmp0(tokens[0], "afilter") == 0) {
Expand Down
2 changes: 1 addition & 1 deletion contrib/plugins/hotblocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,
{
for (int i = 0; i < argc; i++) {
char *opt = argv[i];
g_autofree char **tokens = g_strsplit(opt, "=", 2);
g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);
if (g_strcmp0(tokens[0], "inline") == 0) {
if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &do_inline)) {
fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
Expand Down
2 changes: 1 addition & 1 deletion contrib/plugins/hotpages.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,

for (i = 0; i < argc; i++) {
char *opt = argv[i];
g_autofree char **tokens = g_strsplit(opt, "=", -1);
g_auto(GStrv) tokens = g_strsplit(opt, "=", -1);

if (g_strcmp0(tokens[0], "sortby") == 0) {
if (g_strcmp0(tokens[1], "reads") == 0) {
Expand Down
2 changes: 1 addition & 1 deletion contrib/plugins/howvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,

for (i = 0; i < argc; i++) {
char *p = argv[i];
g_autofree char **tokens = g_strsplit(p, "=", -1);
g_auto(GStrv) tokens = g_strsplit(p, "=", -1);
if (g_strcmp0(tokens[0], "inline") == 0) {
if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &do_inline)) {
fprintf(stderr, "boolean argument parsing failed: %s\n", p);
Expand Down
2 changes: 1 addition & 1 deletion contrib/plugins/hwprofile.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,

for (i = 0; i < argc; i++) {
char *opt = argv[i];
g_autofree char **tokens = g_strsplit(opt, "=", 2);
g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);

if (g_strcmp0(tokens[0], "track") == 0) {
if (g_strcmp0(tokens[1], "read") == 0) {
Expand Down
2 changes: 1 addition & 1 deletion contrib/plugins/lockstep.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,

for (i = 0; i < argc; i++) {
char *p = argv[i];
g_autofree char **tokens = g_strsplit(p, "=", 2);
g_auto(GStrv) tokens = g_strsplit(p, "=", 2);

if (g_strcmp0(tokens[0], "verbose") == 0) {
if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &verbose)) {
Expand Down
2 changes: 1 addition & 1 deletion tests/plugin/bb.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,

for (i = 0; i < argc; i++) {
char *opt = argv[i];
g_autofree char **tokens = g_strsplit(opt, "=", 2);
g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);
if (g_strcmp0(tokens[0], "inline") == 0) {
if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &do_inline)) {
fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
Expand Down
2 changes: 1 addition & 1 deletion tests/plugin/insn.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
{
for (int i = 0; i < argc; i++) {
char *opt = argv[i];
g_autofree char **tokens = g_strsplit(opt, "=", 2);
g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);
if (g_strcmp0(tokens[0], "inline") == 0) {
if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &do_inline)) {
fprintf(stderr, "boolean argument parsing failed: %s\n", opt);
Expand Down
2 changes: 1 addition & 1 deletion tests/plugin/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,

for (int i = 0; i < argc; i++) {
char *opt = argv[i];
g_autofree char **tokens = g_strsplit(opt, "=", 2);
g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);

if (g_strcmp0(tokens[0], "haddr") == 0) {
if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &do_haddr)) {
Expand Down
2 changes: 1 addition & 1 deletion tests/plugin/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,

for (int i = 0; i < argc; i++) {
char *opt = argv[i];
g_autofree char **tokens = g_strsplit(opt, "=", 2);
g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);

if (g_strcmp0(tokens[0], "print") == 0) {
if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &do_print)) {
Expand Down

0 comments on commit 4025874

Please sign in to comment.