summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2011-03-07 15:55:56 +0000
committerRichard W.M. Jones <rjones@redhat.com>2011-03-07 16:42:45 +0000
commit7c721e4fd674c409b3eee60fe237d480afa1c5e2 (patch)
treeacdcd920eb77e75da7a71018ae3f40838061bbed
parent2a9e345090ceeae5bdab68407bf1133c040c4f45 (diff)
downloadlibguestfs-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.ml47
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"