diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2011-03-07 15:55:56 +0000 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2011-03-07 16:42:45 +0000 |
commit | 7c721e4fd674c409b3eee60fe237d480afa1c5e2 (patch) | |
tree | acdcd920eb77e75da7a71018ae3f40838061bbed | |
parent | 2a9e345090ceeae5bdab68407bf1133c040c4f45 (diff) | |
download | libguestfs-7c721e4fd674c409b3eee60fe237d480afa1c5e2.tar.gz libguestfs-7c721e4fd674c409b3eee60fe237d480afa1c5e2.tar.xz libguestfs-7c721e4fd674c409b3eee60fe237d480afa1c5e2.zip |
Fix trace segfault for non-daemon functions (RHBZ#682756).
Previously we expanded the code for 'trace_return' unconditionally for
all non-daemon functions. However this code was not prepared to
handle all error conditions, and in fact would segfault if it tried to
print RStringList or RHashtable where r == NULL.
We need to make the code conditional on the return value, calling
either 'trace_return' or 'trace_return_error' as appropriate.
Note the difficult case for RConstOptString which returns NULL in
non-error cases.
-rw-r--r-- | generator/generator_c.ml | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/generator/generator_c.ml b/generator/generator_c.ml index c4915ea9..99cf327f 100644 --- a/generator/generator_c.ml +++ b/generator/generator_c.ml @@ -887,22 +887,24 @@ check_state (guestfs_h *g, const char *caller) shortname style; pr "{\n"; pr " int trace_flag = g->trace;\n"; - (match ret with - | RErr | RInt _ | RBool _ -> - pr " int r;\n" - | RInt64 _ -> - pr " int64_t r;\n" - | RConstString _ | RConstOptString _ -> - pr " const char *r;\n" - | RString _ | RBufferOut _ -> - pr " char *r;\n" - | RStringList _ | RHashtable _ -> - pr " char **r;\n" - | RStruct (_, typ) -> - pr " struct guestfs_%s *r;\n" typ - | RStructList (_, typ) -> - pr " struct guestfs_%s_list *r;\n" typ - ); + let errcode = + match ret with + | RErr | RInt _ | RBool _ -> + pr " int r;\n"; Some "-1" + | RInt64 _ -> + pr " int64_t r;\n"; Some "-1" + | RConstString _ -> + pr " const char *r;\n"; Some "NULL" + | RConstOptString _ -> + pr " const char *r;\n"; None + | RString _ | RBufferOut _ -> + pr " char *r;\n"; Some "NULL" + | RStringList _ | RHashtable _ -> + pr " char **r;\n"; Some "NULL" + | RStruct (_, typ) -> + pr " struct guestfs_%s *r;\n" typ; Some "NULL" + | RStructList (_, typ) -> + pr " struct guestfs_%s_list *r;\n" typ; Some "NULL" in pr "\n"; check_null_strings shortname style; reject_unknown_optargs shortname style; @@ -910,7 +912,18 @@ check_state (guestfs_h *g, const char *caller) pr " r = guestfs__%s " shortname; generate_c_call_args ~handle:"g" style; pr ";\n"; - trace_return shortname style "r"; + pr "\n"; + (match errcode with + | Some errcode -> + pr " if (r != %s) {\n" errcode; + trace_return ~indent:4 shortname style "r"; + pr " } else {\n"; + trace_return_error ~indent:4 shortname style; + pr " }\n"; + | None -> + trace_return shortname style "r"; + ); + pr "\n"; pr " return r;\n"; pr "}\n"; pr "\n" |