* [PATCH v2] tests/9pfs: Use g_autofree and g_autoptr where possible
@ 2022-01-31 16:39 Greg Kurz
2022-01-31 17:43 ` Christian Schoenebeck
0 siblings, 1 reply; 4+ messages in thread
From: Greg Kurz @ 2022-01-31 16:39 UTC (permalink / raw)
To: qemu-devel
Cc: Laurent Vivier, Paolo Bonzini, Thomas Huth,
Christian Schoenebeck, Greg Kurz
It is recommended to use g_autofree or g_autoptr as it reduces
the odds of introducing memory leaks in future changes. Let's do
that everywhere a glib allocation is performed.
The virtio_9p_create_local_test_dir() function needs some extra
care though : the template pointer is eventually cached into the
local_test_path global variable for the duration of the tests and
should not be freed. Add the g_autofree annotation but negate it
with g_steal_pointer() to make it clear that the pointer ownership
is dropped on purpose.
Based-on: <f6602123c6f7d0d593466231b04fba087817abbd.1642879848.git.qemu_oss@crudebyte.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
---
v2: - fix crash with local_test_path
---
tests/qtest/libqos/virtio-9p.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c
index ef96ef006adc..f0ffbc583492 100644
--- a/tests/qtest/libqos/virtio-9p.c
+++ b/tests/qtest/libqos/virtio-9p.c
@@ -37,18 +37,22 @@ static char *concat_path(const char* a, const char* b)
return g_build_filename(a, b, NULL);
}
-void virtio_9p_create_local_test_dir(void)
+static char *make_temp_dir(char *template)
{
- struct stat st;
- char *pwd = g_get_current_dir();
- char *template = concat_path(pwd, "qtest-9p-local-XXXXXX");
-
- local_test_path = mkdtemp(template);
- if (!local_test_path) {
+ char *path = mkdtemp(template);
+ if (!path) {
g_test_message("mkdtemp('%s') failed: %s", template, strerror(errno));
}
- g_free(pwd);
+ return path;
+}
+
+void virtio_9p_create_local_test_dir(void)
+{
+ g_autofree char *pwd = g_get_current_dir();
+ g_autofree char *template = concat_path(pwd, "qtest-9p-local-XXXXXX");
+ struct stat st;
+ local_test_path = make_temp_dir(g_steal_pointer(&template));
g_assert(local_test_path != NULL);
/* ensure test directory exists now ... */
@@ -60,12 +64,11 @@ void virtio_9p_create_local_test_dir(void)
void virtio_9p_remove_local_test_dir(void)
{
g_assert(local_test_path != NULL);
- char *cmd = g_strdup_printf("rm -fr '%s'\n", local_test_path);
+ g_autofree char *cmd = g_strdup_printf("rm -fr '%s'\n", local_test_path);
int res = system(cmd);
if (res < 0) {
/* ignore error, dummy check to prevent compiler error */
}
- g_free(cmd);
}
char *virtio_9p_test_path(const char *path)
@@ -209,8 +212,8 @@ static void *virtio_9p_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
static void regex_replace(GString *haystack, const char *pattern,
const char *replace_fmt, ...)
{
- GRegex *regex;
- char *replace, *s;
+ g_autoptr(GRegex) regex = NULL;
+ g_autofree char *replace = NULL, *s = NULL;
va_list argp;
va_start(argp, replace_fmt);
@@ -220,9 +223,6 @@ static void regex_replace(GString *haystack, const char *pattern,
regex = g_regex_new(pattern, 0, 0, NULL);
s = g_regex_replace(regex, haystack->str, -1, 0, replace, 0, NULL);
g_string_assign(haystack, s);
- g_free(s);
- g_regex_unref(regex);
- g_free(replace);
}
void virtio_9p_assign_local_driver(GString *cmd_line, const char *args)
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2] tests/9pfs: Use g_autofree and g_autoptr where possible
2022-01-31 16:39 [PATCH v2] tests/9pfs: Use g_autofree and g_autoptr where possible Greg Kurz
@ 2022-01-31 17:43 ` Christian Schoenebeck
2022-02-01 10:11 ` Greg Kurz
0 siblings, 1 reply; 4+ messages in thread
From: Christian Schoenebeck @ 2022-01-31 17:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Greg Kurz, Laurent Vivier, Paolo Bonzini, Thomas Huth
On Montag, 31. Januar 2022 17:39:30 CET Greg Kurz wrote:
> It is recommended to use g_autofree or g_autoptr as it reduces
> the odds of introducing memory leaks in future changes. Let's do
> that everywhere a glib allocation is performed.
>
> The virtio_9p_create_local_test_dir() function needs some extra
> care though : the template pointer is eventually cached into the
> local_test_path global variable for the duration of the tests and
> should not be freed. Add the g_autofree annotation but negate it
> with g_steal_pointer() to make it clear that the pointer ownership
> is dropped on purpose.
>
> Based-on:
> <f6602123c6f7d0d593466231b04fba087817abbd.1642879848.git.qemu_oss@crudebyte
> .com> Signed-off-by: Greg Kurz <groug@kaod.org>
> ---
> v2: - fix crash with local_test_path
> ---
> tests/qtest/libqos/virtio-9p.c | 30 +++++++++++++++---------------
> 1 file changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c
> index ef96ef006adc..f0ffbc583492 100644
> --- a/tests/qtest/libqos/virtio-9p.c
> +++ b/tests/qtest/libqos/virtio-9p.c
> @@ -37,18 +37,22 @@ static char *concat_path(const char* a, const char* b)
> return g_build_filename(a, b, NULL);
> }
>
> -void virtio_9p_create_local_test_dir(void)
> +static char *make_temp_dir(char *template)
> {
> - struct stat st;
> - char *pwd = g_get_current_dir();
> - char *template = concat_path(pwd, "qtest-9p-local-XXXXXX");
> -
> - local_test_path = mkdtemp(template);
> - if (!local_test_path) {
> + char *path = mkdtemp(template);
> + if (!path) {
> g_test_message("mkdtemp('%s') failed: %s", template,
> strerror(errno)); }
> - g_free(pwd);
> + return path;
> +}
> +
> +void virtio_9p_create_local_test_dir(void)
> +{
> + g_autofree char *pwd = g_get_current_dir();
> + g_autofree char *template = concat_path(pwd, "qtest-9p-local-XXXXXX");
> + struct stat st;
>
> + local_test_path = make_temp_dir(g_steal_pointer(&template));
Quite noisy diff and under the bottom line, it does not fix what it originally
supposed to: addressing the leak of the global variable 'local_test_path'.
g_steal_pointer() simply makes the previous g_autofree prefix pointless.
Why not just moving g_autofree from 'template' to the global variable
'local_test_path' and avoid all that noise?
> g_assert(local_test_path != NULL);
>
> /* ensure test directory exists now ... */
> @@ -60,12 +64,11 @@ void virtio_9p_create_local_test_dir(void)
> void virtio_9p_remove_local_test_dir(void)
> {
> g_assert(local_test_path != NULL);
> - char *cmd = g_strdup_printf("rm -fr '%s'\n", local_test_path);
> + g_autofree char *cmd = g_strdup_printf("rm -fr '%s'\n",
> local_test_path); int res = system(cmd);
> if (res < 0) {
> /* ignore error, dummy check to prevent compiler error */
> }
> - g_free(cmd);
> }
>
> char *virtio_9p_test_path(const char *path)
> @@ -209,8 +212,8 @@ static void *virtio_9p_pci_create(void *pci_bus,
> QGuestAllocator *t_alloc, static void regex_replace(GString *haystack,
> const char *pattern, const char *replace_fmt, ...)
> {
> - GRegex *regex;
> - char *replace, *s;
> + g_autoptr(GRegex) regex = NULL;
> + g_autofree char *replace = NULL, *s = NULL;
> va_list argp;
>
> va_start(argp, replace_fmt);
> @@ -220,9 +223,6 @@ static void regex_replace(GString *haystack, const char
> *pattern, regex = g_regex_new(pattern, 0, 0, NULL);
> s = g_regex_replace(regex, haystack->str, -1, 0, replace, 0, NULL);
> g_string_assign(haystack, s);
> - g_free(s);
> - g_regex_unref(regex);
> - g_free(replace);
> }
>
> void virtio_9p_assign_local_driver(GString *cmd_line, const char *args)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] tests/9pfs: Use g_autofree and g_autoptr where possible
2022-01-31 17:43 ` Christian Schoenebeck
@ 2022-02-01 10:11 ` Greg Kurz
2022-02-01 13:00 ` Christian Schoenebeck
0 siblings, 1 reply; 4+ messages in thread
From: Greg Kurz @ 2022-02-01 10:11 UTC (permalink / raw)
To: Christian Schoenebeck
Cc: Laurent Vivier, Paolo Bonzini, Thomas Huth, qemu-devel
On Mon, 31 Jan 2022 18:43:22 +0100
Christian Schoenebeck <qemu_oss@crudebyte.com> wrote:
> On Montag, 31. Januar 2022 17:39:30 CET Greg Kurz wrote:
> > It is recommended to use g_autofree or g_autoptr as it reduces
> > the odds of introducing memory leaks in future changes. Let's do
> > that everywhere a glib allocation is performed.
> >
> > The virtio_9p_create_local_test_dir() function needs some extra
> > care though : the template pointer is eventually cached into the
> > local_test_path global variable for the duration of the tests and
> > should not be freed. Add the g_autofree annotation but negate it
> > with g_steal_pointer() to make it clear that the pointer ownership
> > is dropped on purpose.
> >
> > Based-on:
> > <f6602123c6f7d0d593466231b04fba087817abbd.1642879848.git.qemu_oss@crudebyte
> > .com> Signed-off-by: Greg Kurz <groug@kaod.org>
> > ---
> > v2: - fix crash with local_test_path
> > ---
> > tests/qtest/libqos/virtio-9p.c | 30 +++++++++++++++---------------
> > 1 file changed, 15 insertions(+), 15 deletions(-)
> >
> > diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c
> > index ef96ef006adc..f0ffbc583492 100644
> > --- a/tests/qtest/libqos/virtio-9p.c
> > +++ b/tests/qtest/libqos/virtio-9p.c
> > @@ -37,18 +37,22 @@ static char *concat_path(const char* a, const char* b)
> > return g_build_filename(a, b, NULL);
> > }
> >
> > -void virtio_9p_create_local_test_dir(void)
> > +static char *make_temp_dir(char *template)
> > {
> > - struct stat st;
> > - char *pwd = g_get_current_dir();
> > - char *template = concat_path(pwd, "qtest-9p-local-XXXXXX");
> > -
> > - local_test_path = mkdtemp(template);
> > - if (!local_test_path) {
> > + char *path = mkdtemp(template);
> > + if (!path) {
> > g_test_message("mkdtemp('%s') failed: %s", template,
> > strerror(errno)); }
> > - g_free(pwd);
> > + return path;
> > +}
> > +
> > +void virtio_9p_create_local_test_dir(void)
> > +{
> > + g_autofree char *pwd = g_get_current_dir();
> > + g_autofree char *template = concat_path(pwd, "qtest-9p-local-XXXXXX");
> > + struct stat st;
> >
> > + local_test_path = make_temp_dir(g_steal_pointer(&template));
>
> Quite noisy diff and under the bottom line, it does not fix what it originally
> supposed to: addressing the leak of the global variable 'local_test_path'.
> g_steal_pointer() simply makes the previous g_autofree prefix pointless.
>
The g_autofree and g_steal_pointer() dance is just an idiom that
says "I'm not freeing this pointer on purpose, it will be handled
somewhere else". No big deal. I'll split this in two patches : one
for the leak of 'local_test_path' with a clear comment instead of
g_autofree and one for the remaining g_auto* conversions.
> Why not just moving g_autofree from 'template' to the global variable
> 'local_test_path' and avoid all that noise?
>
Because the 'cleanup' attribute cannot be set on a static variable as
documented in GCC:
cleanup (cleanup_function)
The cleanup attribute runs a function when the variable goes out of
scope. This attribute can only be applied to auto function scope
variables; it may not be applied to parameters or variables with
static storage duration. The function must take one parameter, a
pointer to a type compatible with the variable. The return value
of the function (if any) is ignored.
and trying to do so produces:
../../tests/qtest/libqos/virtio-9p.c:32:1: error: ‘cleanup’ attribute ignored [-Werror=attributes]
32 | static g_autofree char *local_test_path;
| ^~~~~~
cc1: all warnings being treated as errors
The leak of 'local_test_path' can only be addressed with a g_free()
in its last user, i.e. virtio_9p_remove_local_test_dir().
> > g_assert(local_test_path != NULL);
> >
> > /* ensure test directory exists now ... */
> > @@ -60,12 +64,11 @@ void virtio_9p_create_local_test_dir(void)
> > void virtio_9p_remove_local_test_dir(void)
> > {
> > g_assert(local_test_path != NULL);
> > - char *cmd = g_strdup_printf("rm -fr '%s'\n", local_test_path);
> > + g_autofree char *cmd = g_strdup_printf("rm -fr '%s'\n",
> > local_test_path); int res = system(cmd);
> > if (res < 0) {
> > /* ignore error, dummy check to prevent compiler error */
> > }
> > - g_free(cmd);
> > }
> >
> > char *virtio_9p_test_path(const char *path)
> > @@ -209,8 +212,8 @@ static void *virtio_9p_pci_create(void *pci_bus,
> > QGuestAllocator *t_alloc, static void regex_replace(GString *haystack,
> > const char *pattern, const char *replace_fmt, ...)
> > {
> > - GRegex *regex;
> > - char *replace, *s;
> > + g_autoptr(GRegex) regex = NULL;
> > + g_autofree char *replace = NULL, *s = NULL;
> > va_list argp;
> >
> > va_start(argp, replace_fmt);
> > @@ -220,9 +223,6 @@ static void regex_replace(GString *haystack, const char
> > *pattern, regex = g_regex_new(pattern, 0, 0, NULL);
> > s = g_regex_replace(regex, haystack->str, -1, 0, replace, 0, NULL);
> > g_string_assign(haystack, s);
> > - g_free(s);
> > - g_regex_unref(regex);
> > - g_free(replace);
> > }
> >
> > void virtio_9p_assign_local_driver(GString *cmd_line, const char *args)
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2] tests/9pfs: Use g_autofree and g_autoptr where possible
2022-02-01 10:11 ` Greg Kurz
@ 2022-02-01 13:00 ` Christian Schoenebeck
0 siblings, 0 replies; 4+ messages in thread
From: Christian Schoenebeck @ 2022-02-01 13:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Greg Kurz, Laurent Vivier, Paolo Bonzini, Thomas Huth
On Dienstag, 1. Februar 2022 11:11:37 CET Greg Kurz wrote:
> On Mon, 31 Jan 2022 18:43:22 +0100
>
> Christian Schoenebeck <qemu_oss@crudebyte.com> wrote:
> > On Montag, 31. Januar 2022 17:39:30 CET Greg Kurz wrote:
> > > It is recommended to use g_autofree or g_autoptr as it reduces
> > > the odds of introducing memory leaks in future changes. Let's do
> > > that everywhere a glib allocation is performed.
> > >
> > > The virtio_9p_create_local_test_dir() function needs some extra
> > > care though : the template pointer is eventually cached into the
> > > local_test_path global variable for the duration of the tests and
> > > should not be freed. Add the g_autofree annotation but negate it
> > > with g_steal_pointer() to make it clear that the pointer ownership
> > > is dropped on purpose.
> > >
> > > Based-on:
> > > <f6602123c6f7d0d593466231b04fba087817abbd.1642879848.git.qemu_oss@crudeb
> > > yte
> > > .com> Signed-off-by: Greg Kurz <groug@kaod.org>
> > > ---
> > > v2: - fix crash with local_test_path
> > > ---
> > >
> > > tests/qtest/libqos/virtio-9p.c | 30 +++++++++++++++---------------
> > > 1 file changed, 15 insertions(+), 15 deletions(-)
> > >
> > > diff --git a/tests/qtest/libqos/virtio-9p.c
> > > b/tests/qtest/libqos/virtio-9p.c index ef96ef006adc..f0ffbc583492
> > > 100644
> > > --- a/tests/qtest/libqos/virtio-9p.c
> > > +++ b/tests/qtest/libqos/virtio-9p.c
> > > @@ -37,18 +37,22 @@ static char *concat_path(const char* a, const char*
> > > b)
> > >
> > > return g_build_filename(a, b, NULL);
> > >
> > > }
> > >
> > > -void virtio_9p_create_local_test_dir(void)
> > > +static char *make_temp_dir(char *template)
> > >
> > > {
> > >
> > > - struct stat st;
> > > - char *pwd = g_get_current_dir();
> > > - char *template = concat_path(pwd, "qtest-9p-local-XXXXXX");
> > > -
> > > - local_test_path = mkdtemp(template);
> > > - if (!local_test_path) {
> > > + char *path = mkdtemp(template);
> > > + if (!path) {
> > >
> > > g_test_message("mkdtemp('%s') failed: %s", template,
> > >
> > > strerror(errno)); }
> > > - g_free(pwd);
> > > + return path;
> > > +}
> > > +
> > > +void virtio_9p_create_local_test_dir(void)
> > > +{
> > > + g_autofree char *pwd = g_get_current_dir();
> > > + g_autofree char *template = concat_path(pwd,
> > > "qtest-9p-local-XXXXXX");
> > > + struct stat st;
> > >
> > > + local_test_path = make_temp_dir(g_steal_pointer(&template));
> >
> > Quite noisy diff and under the bottom line, it does not fix what it
> > originally supposed to: addressing the leak of the global variable
> > 'local_test_path'. g_steal_pointer() simply makes the previous g_autofree
> > prefix pointless.
> The g_autofree and g_steal_pointer() dance is just an idiom that
> says "I'm not freeing this pointer on purpose, it will be handled
> somewhere else". No big deal. I'll split this in two patches : one
> for the leak of 'local_test_path' with a clear comment instead of
> g_autofree and one for the remaining g_auto* conversions.
Yeah, I got that, but it still adds redundant code, as if adding a constant
literal expression like "... * 1/2 * 2".
The other changes have an actual purpose: they reduce code. This one though
just adds noise without a real purpose, plus it reverts of what I just have
done with the previous patch: getting rid of the previously already existing
separate function init_local_test_path():
https://github.com/cschoenebeck/qemu/commit/072636e2a9f3a153078e6046e52ae5a330728b68
I don't care enough though to continue defending my position on this.
> > Why not just moving g_autofree from 'template' to the global variable
> > 'local_test_path' and avoid all that noise?
>
> Because the 'cleanup' attribute cannot be set on a static variable as
> documented in GCC:
>
> cleanup (cleanup_function)
>
> The cleanup attribute runs a function when the variable goes out of
> scope. This attribute can only be applied to auto function scope
> variables; it may not be applied to parameters or variables with
> static storage duration. The function must take one parameter, a
> pointer to a type compatible with the variable. The return value
> of the function (if any) is ignored.
>
> and trying to do so produces:
>
> ../../tests/qtest/libqos/virtio-9p.c:32:1: error: ‘cleanup’ attribute
> ignored [-Werror=attributes] 32 | static g_autofree char *local_test_path;
>
> | ^~~~~~
>
> cc1: all warnings being treated as errors
>
> The leak of 'local_test_path' can only be addressed with a g_free()
> in its last user, i.e. virtio_9p_remove_local_test_dir().
Agreed, that would probably be the best solution for now.
Thanks!
Best regards,
Christian Schoenebeck
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-02-01 15:29 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-31 16:39 [PATCH v2] tests/9pfs: Use g_autofree and g_autoptr where possible Greg Kurz
2022-01-31 17:43 ` Christian Schoenebeck
2022-02-01 10:11 ` Greg Kurz
2022-02-01 13:00 ` Christian Schoenebeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).